AndEngine sprites are locked when setting velocity after collision in onManagedUpdate method - android

I have to create a game in which there is one player sprite and several(approx 30) other sprites who moves randomly on the screen without colliding within themselves. I have problem in avoiding collision, since when detecting collision all the moving sprites are locked.
Below is my code..In my code I have created two classes one is MainActivity( This is the main class which extends BaseGameActivity and creates approx 30 AnimatedSprites using the NewSprite class and contains a static array list 'playerSprite' of NewSprite objects(approx 30 objects created randomly) and the second is NewSprite( which extends AnimatedSprite and overloads the method onManagedUpdate() to prevent these moving AnimatedSprites from going offscreen and collision between them.)
I have only shown NewSprite class..
public class NewSprite extends AnimatedSprite{
public PhysicsHandler physicsHandler;
Random randPos;
public NewSprite(final float pX, final float pY, final ITiledTextureRegio pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
randPos = new Random();
float x1;
float y1;
while((x1 = randPos.nextFloat()) < 0.8f);
while((y1 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x1 *= -1;
if(randPos.nextInt() % 2 == 0)
y1 *= -1;
physicsHandler = new PhysicsHandler(this);
this.registerUpdateHandler(physicsHandler);
physicsHandler.setVelocity(x1 * 100, y1 * 100);
}
#Override
protected void onManagedUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
if(this.mX < 0){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mY < 0){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mX > (MainActivity.CAMERA_WIDTH - MainActivity.MONSTER_WIDTH)){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
x2 *= -1;
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mY > (MainActivity.CAMERA_HEIGHT - MainActivity.MONSTER_HEIGHT)){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
for(int i=0 ; i < MainActivity.playerSprite.size(); i++){
if(( MainActivity.playerSprite.get(i)).collidesWith(this) || this.collidesWith(MainActivity.playerSprite.get(i))){
float x2, y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
this.physicsHandler.setVelocity( x2*100, y2*100);
break;
}
}
super.onManagedUpdate(pSecondsElapsed);
}

Did you tried to put your code after the super.onManagedUpdate(pSecondsElapsed); ?

Related

Bitmap Bounding RectF Collision

I have been trying to create a simple breakout type game. I have a ball and a bat and want to invert the ball's direction when it collides with the bat. The bat is controlled by the user's touch and can freely move around the screen.
#Override
public boolean onTouch(View v, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
return true;
}
In my game loop:
int cx = -1;
int cy = -1;
private int xVelocity = -11;
private int yVelocity = -14;
Bitmap player, ball;
RectF boundsPlayer, boundsBall;
float boundCX, boundCY;
boundCX = (float) cx;
boundCY = (float) cy;
player = BitmapFactory.decodeResource(getResources(), R.drawable.nightplayer);
canvas.drawBitmap(player, x - (player.getWidth() / 2), y - (player.getHeight() + 100), null);
ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
boundsPlayer = new RectF((x - (player.getWidth()/2)), (y - (player.getHeight() + 150)), ((x - (player.getWidth()/2)) + player.getWidth()), ((y - (player.getHeight() + 150)) + player.getHeight()));
boundsBall = new RectF(boundCX, boundCY, boundCX + ball.getWidth(), boundCY + ball.getHeight());
if (RectF.intersects(boundsBall, boundsPlayer)) {
collision();
}
private void collision() {
yVelocity = yVelocity * -1;
score = score + 1;
//Log.d(TAG, String.valueOf(score));
yVelocity = yVelocity - 2;
if(xVelocity < 0) {
xVelocity = xVelocity - 2;
} else if (xVelocity > 0) {
xVelocity = xVelocity + 2;
}
collision = false;
}
The issue I am having is that when the ball collides with the bat it seems to collide multiple times and repeatedly inverts the direction instead of "bouncing off" of the bat.

Provided data element number (0) should be multiple of the Mat channels count (1) Android OpenCV

I'm trying to find 4 corners from a rect object(paper sheet).
Mat source = new Mat();
Org.Opencv.Core.Point center;
public GetCorners(Bitmap _sourceImg)
{
Utils.BitmapToMat(_sourceImg, source);
}
//find corners
public void FindCorners()
{
center = new Org.Opencv.Core.Point(0, 0);
//Mat source = new Mat();
if (source == null)
{
Console.WriteLine("No IMG");
return;
}
Mat BlackWhite = new Mat();
Imgproc.CvtColor(source, BlackWhite, Imgproc. ColorBgr2gray); //ColorBgra2gray, 4);
Imgproc.Blur(BlackWhite, BlackWhite, new Size(3, 3));
Imgproc.Canny(BlackWhite, BlackWhite, 100, 100, 3, true);
Mat Lines = new Mat();
int treshold = 70;
int minLinsize = 30;
int lineGap = 10;
Imgproc.HoughLinesP(BlackWhite, Lines, 1, Math.PI / 180, treshold, minLinsize, lineGap);
for (int i = 0; i < Lines.Cols(); i++)
{
double[] Vector = Lines.Get(0, i);
double[] Value = new double[4];
Value[0] = 0;
Value[1] = ((float) Vector[1] - Vector[3]) / (Vector[0] - Vector[2]) * -Vector[0] + Vector[1];
Value[2] = source.Cols();
Value[3] = ((float)Vector[1] - Vector[3]) / (Vector[0] - Vector[2]) * (source.Cols() - Vector[2]) + Vector[3];
Lines.Put(0, i, Value);
}
Console.WriteLine("##Quantity {0} Founded##",Lines.Cols());
List<Org.Opencv.Core.Point> Corners = new List<Org.Opencv.Core.Point>();
for (int i = 0; i < Lines.Cols(); i++)
{
for (int j = 0 ; i < Lines.Cols(); j++)
{
Mat m1 = new Mat(),
m2 = new Mat();
double[] d1 = Lines.Get(0, i);
double[] d2 = Lines.Get(0, j);
m1.Put(0, j, d1);
m2.Put(0, j, d2);
try
{
//i'm getting exception here
Org.Opencv.Core.Point pt = ComputeInteresect(Lines.Get(0, i), Lines.Get(0, j)); //(m1, m2);
if (pt.X >= 0 && pt.Y >= 0)
{
Corners.Add(pt);
Console.WriteLine ("dobavleno {0} koordinat",Corners.Count);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
and also i got a method that calculate intersects :
static Org.Opencv.Core.Point ComputeInteresect(double[] a, double[] b) //(Mat es,Mat es2)//
{
double x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
double denom = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
Org.Opencv.Core.Point pt = new Org.Opencv.Core.Point();
if (denom != 0)
{
pt.X = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2)
* (x3 * y4 - y3 * x4))
/ denom;
pt.Y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2)
* (x3 * y4 - y3 * x4))
/ denom;
return pt;
}
else
return new Org.Opencv.Core.Point(-1, -1);
}
And I don't understand why, but I'm getting this exception:
java.lang.UnsupportedOperationException:
Provided data element number (0)
should be multiple of the Mat channels
count (1)
I found,that this problem occurs, when an image is in RGB Format (and has 4 channels), but at first, I'm converting to gray (1 channel), via this method:
Imgproc.CvtColor(source, BlackWhite, Imgproc. ColorBgr2gray); //ColorBgra2gray, 4);
Any help will be appreciated, thanks!
Finally, i changed some part of code and its works:
Console.WriteLine("##Quantity {0} Founded##",Lines.Cols());
List<Org.Opencv.Core.Point> Corners = new List<Org.Opencv.Core.Point>();
for (int i = 0; i < Lines.Cols(); i++)
{
for (int j = i+1 ; i < Lines.Cols(); j++)
{
try
{
Org.Opencv.Core.Point pt = ComputeInteresect(Lines.Get(0, i), Lines.Get(0, j));
if (pt.X >= 0 && pt.Y >= 0)
{
Corners.Add(pt);
Console.WriteLine ("dobavleno {0} koordinat",Corners.Count);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

rotate image on every touch event

In my application, I have some images and when I tap on that image, it should be rotated by 90 degree. I am able to rotate image once but can't rotate on second tap. Can anyone help me to solve this problem? How can I rotate image on every touch event?
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.quartercircle1);
Matrix m = new Matrix();
imgvwQrtr1.setScaleType(ScaleType.MATRIX);
m.setRotate(90f, imgvwQrtr1.getDrawable().getBounds().width()/2, imgvwQrtr1.getDrawable().getBounds().height()/2);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
imgvwQrtr1.setImageBitmap(bm);
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new DragShadowBuilder(v);
v.startDrag(data, shadowBuilder, v, 0);
return true;
}
you need to create global variable like:
int degree = 0;
and in the code
.....
//shortest way
degree = degree + 90;
if(degree % 360 == 0) {
degree = 0;
}
//if(degree >= 270) {
//degree = 0;
//} else {
//degree+=90;
//}
m.setRotate(degree, imgvwQrtr1.getDrawable().getBounds().width()/2,
imgvwQrtr1.getDrawable().getBounds().height()/2);
....
try this
public static float getRotationAngle(final float x1, final float y1, final float x2, final float y2) {
final float CLOCK_WISE = 1.0f;
final float ANTI_CLOCK_WISE = -1.0f;
final float deltaX = Math.abs(x2 - x1);
final float deltaY = Math.abs(y2 - y1);
if (deltaX == 0) {
return 0.0f;
}
final float angle = (float) Math.toDegrees(Math.atan(deltaY / deltaX));
if (x1 <= x2 && y2 <= y1) {
return CLOCK_WISE * (90.0f - angle);
} else if (x2 <= x1 && y2 <= y1) {
return ANTI_CLOCK_WISE * (90.0f - angle);
} else if (x2 <= x1 && y1 <= y2) {
return ANTI_CLOCK_WISE * (90.0f + angle);
} else if (x1 <= x2 && y1 <= y2) {
return CLOCK_WISE * (90.0f + angle);
} else {
return 0.0f;
}
}

How do I draw a graph on Android without using any external API? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I understand how to draw lines using a canvas, but how can I use the same lines using a canvas to draw a graph?
The problem is with the coordinates. (0,0) starts right at the top left corner of the device. How can I set (0,0) as the margin and draw the particular line with respect to the margin?
1)Create an activity.
public class GraphView1 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
float[] values = new float[] { "your values"};
String[] verlabels = new String[] { "your values" };
String[] horlabels = new String[] { "your values"
GraphView graphView = new GraphView(this, values,"GraphView",horlabels, verlabels, GraphView.BAR);
setContentView(graphView);
}
}
2)Then create another class extends View:
public class GraphView2 extends View{
public static boolean LINE = true;
private Paint paint;
private float[] values;
private String[] str;
private String[] verlabels;
private String title;
private boolean type;
Context context;
public GraphView(Context context, float[] values, String title, String[] str,String[] verlabels, boolean type) {
super(context);
if (values == null)
values = new float[0];
else
this.values = values;
if (title == null)
title = "";
else
this.title = title;
if (str == null)
this.str = new String[0];
else
this.str = str;
if (verlabels == null)
this.verlabels = new String[0];
else
this.verlabels = verlabels;
this.type = type;
paint = new Paint();
}
#Override
protected void onDraw(final Canvas canvas) {
context=getContext();
float border = 15;
float horstart = border * 2;
float height = getHeight();
float width = getWidth();
float max = getMax();
Log.w("max", ""+max);
float min = getMin();
Log.w("min", ""+min);
float diff = max - min;
float graphheight = height - (2 * border);
float graphwidth = width - (2 * border);
paint.setTextAlign(Align.LEFT);
int vers = verlabels.length;
for (int i = 0; i < verlabels.length; i++) {
paint.setColor(Color.DKGRAY);
float y = ((graphheight / vers) * i) + border;
canvas.drawLine(horstart, y, width, y, paint);
paint.setColor(Color.WHITE);
paint.setTextSize(10);
canvas.drawText(verlabels[i], 0, y, paint);
}
int hors = values.length;
for (int i = 0; i < str.length; i++) {
paint.setColor(Color.DKGRAY);
float x = ((graphwidth / hors) * i) + horstart;
canvas.drawLine(x, height - border, x, border, paint);
paint.setTextAlign(Align.LEFT);
if (i==str.length)
paint.setTextAlign(Align.RIGHT);
if (i==0)
paint.setTextAlign(Align.LEFT);
paint.setColor(Color.WHITE);
paint.setTextSize(9);
canvas.drawText( str[i], x, height - 4, paint);
}
paint.setTextAlign(Align.CENTER);
canvas.drawText(title, (graphwidth / 2) + horstart, border - 4, paint);
if (max != min) {
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
if (type == BAR) {
float datalength = values.length;
float colwidth = (width - (2 * border)) / datalength;
for (int i = 0; i < values.length; i++) {
// float val = values[i] - min;
// float rat = val / diff;
// float h = graphheight * rat;
// canvas.drawRect((i * colwidth) + horstart, (border - h) + graphheight, ((i * colwidth) + horstart) + (colwidth - 1), height - (border - 1), paint);
float graph_h = getHeight()-(border*2);
// Log.e("", "graph_h > "+graph_h);
float ind_h = graph_h/7;
//Log.e("", "ind_h > "+ind_h);
float t = values[i]/5;
float top = (graph_h - ind_h*(t));
// Log.e("", " > "+i+1);
// Log.e("", "top > "+top);
//for values between 0 and 5 ,vice versa
//Log.e("", " values[i] > "+values[i]);
float acc = ind_h/5;
acc = acc * (values[i]%5);
// Log.e("", " acc > "+acc);
canvas.drawRect((i * colwidth) + horstart, top+border-acc , ((i * colwidth) + horstart) + (colwidth - 1), graph_h+border, paint);
}
} else {
float datalength = values.length;
float colwidth = (width - (2 * border)) / datalength;
float halfcol = colwidth / 2;
float lasth = 0;
for (int i = 0; i < values.length; i++) {
float val = values[i] - min;
float rat = val / diff;
float h = graphheight * rat;
if (i > 0)
canvas.drawLine(((i - 1) * colwidth) + (horstart + 1) + halfcol, (border - lasth) + graphheight, (i * colwidth) + (horstart + 1) + halfcol, (border - h) + graphheight, paint);
lasth = h;
}
}
}
}
private float getMax() {
float largest = Integer.MIN_VALUE;
for (int i = 0; i < values.length; i++)
if (values[i] > largest)
largest = values[i];
return largest;
}
private float getMin() {
float smallest = Integer.MAX_VALUE;
for (int i = 0; i < values.length; i++)
if (values[i] < smallest)
smallest = values[i];
return smallest;
}
}

Drawing Line Effect on Touch Like Fruit Ninja or Veggie Samurai in And Engine

I want to draw a line in AndEngine with the effect of a blade similar to Fruit Ninja or Veggie Samurai.
Can anyone help me? and give a sample code?
Maybe, I am late but hope this will help others.
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
final float touchX = pSceneTouchEvent.getX();
final float touchY = pSceneTouchEvent.getY();
if (pSceneTouchEvent.isActionDown()) {
initTrail(touchX, touchY);
swipeGestureSprite = addSwipeSprite(touchX, touchY);
} else if (pSceneTouchEvent.isActionMove()) {
moveTrail(pSceneTouchEvent.getX(), pSceneTouchEvent.getY(), 0);
if (swipeGestureSprite != null) {
swipeGestureSprite.setX(touchX);
swipeGestureSprite.setY(touchY);
}
} else if (pSceneTouchEvent.isActionUp()) {
mScene.detachChild(this.particleSystem);
if (swipeGestureSprite != null) {
this.mScene.detachChild(swipeGestureSprite);
swipeGestureSprite = null;
}
return true;
}
return false;
}
private void initTrail(float mX, float mY) {
this.particleEmitter = new PointParticleEmitter(mX, mY);
this.particleSystem = new SpriteParticleSystem(particleEmitter, 1000, 1000, 5000, this.mRibbon, this.getVertexBufferObjectManager());
particleSystem.addParticleInitializer(new BlendFunctionParticleInitializer<Sprite>(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE));
particleSystem.addParticleInitializer(new ExpireParticleInitializer<Sprite>(1));
particleSystem.addParticleModifier(new ScaleParticleModifier<Sprite>(0, 1, 1, 0f));
particleSystem.addParticleModifier(new AlphaParticleModifier<Sprite>(0, 1, 1, 0));
this.mScene.attachChild(particleSystem);
}
private void moveTrail(float trailX, float trailY, int count) {
if (particleEmitter == null) {
initTrail(trailX, trailY);
}
particleEmitter.setCenter(trailX, trailY);
}
I think you have to use point particle effect and use line drawing algorithm in that to create line between points. Line drawn using particle represent more reality and also the particle represent the dynamic way so you can destroy it. Further you can ask.
EDIT : For particle generation you can use this code
public void generateParticles(float pX, float pY) {
pointParticleEmtitter = new PointParticleEmitter(pX, pY);
particleSystem = new ParticleSystem(pointParticleEmtitter, maxRate,
minRate, maxParticles, mParticleTextureRegion.deepCopy());
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
particleSystem.addParticleInitializer(new ColorInitializer(0.8f, 0.43f,
0.2f));
particleSystem.addParticleModifier(new AlphaModifier(1, 0, 0, 0.25f));
particleSystem.addParticleModifier(new ExpireModifier(0.25f));
gameObject.getScene().attachChild(particleSystem);
}
For Line algorithm you can use this one
public void drawLine() {
int x;
float y, m;
x = (int) previousX;
y = (int) previousY;
m = (currentY - previousY) / (currentX - previousX);
if (Math.round(previousX) == Math.round(currentX)) {
if (previousY < currentY) {
for (y = (int) previousY; y < currentY; ++y)
pointParticleEmtitter.setCenter(previousX, y);
} else {
for (y = (int) previousY; y > currentY; --y)
pointParticleEmtitter.setCenter(previousX, y);
}
} else {
if (previousX < currentX) {
for (x = (int) previousX; x < currentX; ++x) {
y = m * (x - previousX) + previousY;
pointParticleEmtitter.setCenter(x, y);
}
} else if (previousX > currentX) {
for (x = (int) previousX; x > currentX; --x) {
y = m * (x - currentX) + currentY;
pointParticleEmtitter.setCenter(x, y);
}
}
}
}

Categories

Resources