Collision Detection with Alpha in Box2D for AndEngine - android

I am creating my first game in Andengine (GLES 2) and using Box2D for physics.
The collision detection works but doesn't seem to take into account the alpha values on the png files (I think this is what is happening) as the collision happens way before the two sprites actually touch. I don't need the collision to be pixel perfect just reasonably accurate.
This is how I set up the collision detection:
final CharacterSprite characterSprite = new CharacterSprite(CAMERA_WIDTH/2, CAMERA_HEIGHT/2, this.mCharacterTextureRegion, this.getVertexBufferObjectManager());
mPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0, 0), false);
scene.registerUpdateHandler(mPhysicsWorld);
playerBody = PhysicsFactory.createBoxBody(mPhysicsWorld, characterSprite, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(0, 0, 0));
playerBody.setUserData("player");
characterSprite.setBody(playerBody);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(characterSprite, playerBody, true, true));
mPhysicsWorld.setContactListener(createContactListener());
attachSprites(scene);
Thank you

Well then use shape other than a box (circle might be a good choice) or use a custom sized box that doesn't go all the way around your sprite. If you want even more precision go with polygon or even multiple polygons.

Related

Android Studio Libgdx Sprite/Texture Transparency

I need to change the transparency of a texture/sprite and I really have no idea how to do it. Any help?
I see two solutions here - one is to change transparency directly in sprite:
Sprite sprite = new Sprite( yourTexture );
Sprite otherSprite = new Sprite( yourOtherTexture );
sprite.setAlpha(0.1f); // 0f is full transparent when 1f is full visible
...
batch.begin();
sprite.draw( batch ); //this one will be almost transparent
otherSprite.draw( batch ); //this one will be normal
batch.end();
you can always manipulate with Sprite color directly:
sprite.setColor( sprite.getColor.r, sprite.getColor.g, sprite.getColor.b, 0.1f);
but it seems to be a silly way for me.
The second one which I recommend is to wrap your Sprite into Scene2d Actor class like for example Image. Then you can still change aplha directly but you are also able to use Scene2d Actions mechanism, manipulating actor's alpha smoothly (like alpha changing animation step by step).
Both Scene2d and Actions are to wide to describe it here but I encourage you to read about it here:
Scene2d
Scene2d Actions
I added this to my GameRenderer.java:
private void drawTapTapChuggy() {
batcher.setColor(1, 1, 1, 0.5f);
batcher.draw(AssetLoader.tapTapChuggy, 28, 89, (83 * 0.9f), (52 * 0.9f));
batcher.setColor(1, 1, 1, 1.0f);
}

JBox2d: Negative gravity results in object going up?

I am a newbie learner to JBox2D. I was just trying JBox2D for the first time on Android(I know Android development and I'm good in it) because my project needed physics.
Now, the tutorials and "Official User Manual" of Box2D said that negative gravity would result in objects being attracted downwards. But, in my case the object is being attracted upwards when I set Vec2's second parameter to be negative! Weird.
Here's the code which results in a circle shape going up on its own:
The Gravity:
Vec2 gravity = new Vec2(0.0f, -50.0f);
boolean doSleep = true;
world = new World(gravity, doSleep);
The circle shape is being made by following code:
//body definition
BodyDef bd = new BodyDef();
bd.position.set(200, 500);
bd.type = BodyType.DYNAMIC;
//define shape of the body.
CircleShape cs = new CircleShape();
cs.m_radius = 10f;
//define fixture of the body.
FixtureDef fd = new FixtureDef();
fd.shape = cs;
fd.density = 1f;
fd.friction = 0.2f;
fd.restitution = 0.8f;
//create the body and add fixture to it
body = world.createBody(bd);
body.createFixture(fd);
And I'm using SurfaceView canvas to draw:
canvas.drawCircle(body.getPosition().x, body.getPosition().y, 10, paint);
And stepp-ing as follows:
float timeStep = 1.0f / 60.f;
int velocityIterations = 6;
int positionIterations = 2;
world.step(timeStep, velocityIterations, positionIterations);
So, what's wrong within my code? I am unable to identify the mistake I've done.
Also,
I'm making a tennis-like 2D game on Android for which I'll be using JBox2D. So, can anybody tell me a tutorial/book on JBox2D? Though I googled vigorously, I couldn't find a good tutorial on it. (Though Box2D seems to be much popular instead of JBox2D)
I would be extremely grateful if someone could help me out here. Thank you.
In Box2D there is standard coordinate system: Y directed up, X to the right. In the graphic systems, usual, coordinate system has Y directed down, because window has static top-left corner. Looks like at your graphic system all the same. So, what in Box2D is moving down, you see as moving up.
It is the irritable problem, and directing gravity up is not the best solution. If you change only gravity, then you will need think about up-down problem in many other cases, for example, when define bodies, apply forces and so on. The most irritable, that it is not easy to understand, how physic coordinates conform graphic (for example, in one of my projects I had to draw points on paper, then turn paper back, rotate on 180 grades and look on the light :).
You can't change Box2D coordinate system, but, most likely, you can easy change coordinate system of graphic system by changing translation matrix. For example, in OpenGL it looks like this:
glScalef(1.0, -1.0, 1.0);
But take attention, after this, all that have positive Y coordinate will be not visible on the screen (it will be above the top edge of the window). So, you will need work with negative coordinates. If you don't want this, you can translate matrix down like this:
glTranslatef(0.0, -windowHeight.0, 0.0)
But before, think what to do if window would be resized.
About second question. I doubt whether you can find anywhere tutorial or book for JBox2D. JBox2D is port of Box2D (that means, it is exact copy of Box2D), and writing special book for it looks strange. Learn Box2D, and you will have no problem with JBox2D. For example, you can look there.

AndEngine Vector2 class

I want to ask a basic question just to make sure. When we use Vector2 class for representing some vector in andengine like when we use in joint creation as:
jointDef.localAnchorA.set(new Vector2(1, 1));
Do the values passed i.e. 1, 1 represent 1 meter each?
A little more explanation. Suppose I have created two bodies as:
Rectangle rect1 = new Rectangle(10, 10, 100, 100, vertexBufferObjectManager);
Body body1 = PhysicsFactory.createBoxBody(mPhysicsWorld, rect1, BodyType.DynamicBody, FIXTURE_DEF);
Rectangle rect2 = new Rectangle(110, 110, 50, 50, vertexBufferObjectManager);
Body body2 = PhysicsFactory.createBoxBody(mPhysicsWorld, rect2, BodyType.DynamicBody, FIXTURE_DEF);
And want to create a revolute joint at the position shown in the image below:
So what values for vectors localAnchorpointA and localAnchorPointB should I set to place the upper right corner of red rectangle touching the center of white rectangle? Like:
jointDef.localAnchorA.set(new Vector2(?, ?));
jointDef.localAnchorB.set(new Vector2(?, ?));
This would be very helpful in understanding the usage of vector2 class.
You need to understand what does a Vector2 class represent and stands for in game development. It basically encapsulates the provided coordinates in the 2D space. Taking it a step further, it has numerous applications for which it can be used, from distance calculations to other basic algebraic calculations. Stiegart Blog will give you a much clear idea about Vector2 in android. Hope it clarifies the confusion and misunderstanding.
The Vector2 has no associated units, you decide what the coordinates space looks like on the screen, when you render it (by choosing an appropriate camera). For angels You have to use radians.
But as I can see, You are passing it to the Box2D physics engine. It is recommanded to use units close to m/kg/s. Making your character 2m high would be a good choice. Making your spaceship Enterprise 10km across in Your asteroids game would be too much.
More information can be found in this post: http://box2d.org/2011/12/pixels/ .

Collision detection with bitmaps on SurfaceView's canvas in Android

In Android I use a SurfaceView to display a simple 2D game. The bitmaps (.png) with alpha (representing the game objects) are drawn on the canvas.
Now I would like to do a simple but accurate collision detection. Checking whether these bitmaps are overlapping is quite easy.
But how do I check for collisions when these bitmaps have transparent areas? My challenge is detecting whether two balls collide or not. They fill up the whole bitmap in width and height both but in all four edges, there are transparent areas of course as it's a circle in a square.
What is the easiest way to detect collisions there only if the balls really collide, not their surrounding bitmap box?
Do I have to store coordinates of as many points on the ball's outline as possible? Or can Android "ignore" the alpha-channel when checking for collisions?
Another method I can think of will work with simple objects that can be constructed using Paths.
Once you have two objects whose boundaries are represented by paths, you may try this:
Path path1 = new Path();
path1.addCircle(10, 10, 4, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(15, 15, 8, Path.Direction.CW);
Region region1 = new Region();
region1.setPath(path1, clip);
Region region2 = new Region();
region2.setPath(path2, clip);
if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) {
// Collision!
}
Once you have your objects as Paths, you can draw them directly using drawPath(). You can also perform movement by transform()ing the path.
If it is ball collision you can perform analitical collision detection - it will be much faster then per-pixel detection. You only need to have two centers of balls (x1,y1) and (x2,y2) and radius r1 for the first ball and r2 for second one. Now if distance between centers of ball is less or equal of sum of radius then the balls are colliding:
colide = sqrt((x1-x2)^2+(y1-y2)^2)<=r1+r2
but a little faster way is to compare square of this value:
colide = (x1-x2)^2+(y1-y2)^2<=(r1+r2)^2
It's much easier to use an existing library like AndEngine instead of reinventing the wheel. I'm not sure if it can be used with a SurfaceView though. Check this article: Pixel Perfect Collision Detection for AndEngine.

Pixel based collision detection problem with OpenGLES 2.0 under Android

This is my first post here, therefore apologize for any blunders.
I'm developing a simple action game with the usage of OpenGL ES 2.0 and Android 2.3. My game framework on which I'm currently working on is based on two dimensional sprites which exists in three dimensional world. Of course my world entities possess information such as position within the imaginary world, rotational value in form of float[] matrix, OpenGL texture handle as well as Android's Bitmap handle (I'm not sure if the latter is necessary as I'm doing the rasterisation with the usage of OpenGl machine, but for the time being it is just there, for my convenience). This is briefly the background, now to the problematic issue.
Presently I'm stuck with the pixel based collision detection as I'm not sure which object (here OGL texture, or Android Bitmap) I need to sample. I mean, I've already tried to sample Android's Bitmap, but it completely didn't worked for me - many run-time crashes in relation to reading outside of the bitmap. Of course to be able to read the pixels from the bitmap, I've used Bitmap.create method to obtain properly rotated sprite. Here's the code snippet:
android.graphics.Matrix m = new android.graphics.Matrix();
if(o1.angle != 0.0f) {
m.setRotate(o1.angle);
b1 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, false);
}
Another issue, which might add to the problem, or even be the main problem, is that my rectangle of intersection (rectangle indicating two dimensional space mutual for both objects) is build up from parts of two bounding boxes which were computed with the usage of OpenGL matrices Matrix.multiplyMV functionality (code below). Could it be, that those two Android and OpenGL matrices computation methods aren't equal?
Matrix.rotateM(mtxRotate, 0, -angle, 0, 0, 1);
// original bitmap size, equal to sprite size in it's model space,
// as well as in world's space
float[] rect = new float[] {
origRect.left, origRect.top, 0.0f, 1.0f,
origRect.right, origRect.top, 0.0f, 1.0f,
origRect.left, origRect.bottom, 0.0f, 1.0f,
origRect.right, origRect.bottom, 0.0f, 1.0f
};
android.opengl.Matrix.multiplyMV(rect, 0, mtxRotate, 0, rect, 0);
android.opengl.Matrix.multiplyMV(rect, 4, mtxRotate, 0, rect, 4);
android.opengl.Matrix.multiplyMV(rect, 8, mtxRotate, 0, rect, 8);
android.opengl.Matrix.multiplyMV(rect, 12, mtxRotate, 0, rect, 12);
// computation of object's bounding box (it is necessary as object has been
// rotated second ago and now it's bounding rectangle doesn't match it's host
float left = rect[0];
float top = rect[1];
float right = rect[0];
float bottom = rect[1];
for(int i = 4; i < 16; i += 4) {
left = Math.min(left, rect[i]);
top = Math.max(top, rect[i+1]);
right = Math.max(right, rect[i]);
bottom = Math.min(bottom, rect[i+1]);
};
Cheers,
first note that there is a bug in your code. You can not use Matrix.multiplyMV() with source and destination vector being the same (the function will correctly calculate an x coordinate which it will overwrite in the source vector. However, it needs the original x to calculate the y, z and w coordinates - which are in turn flawed). Also note that it would be easier for you to use bounding spheres for the first detection collision step, as they do not require such a complicated code to perform matrix transformation.
Then, the collision detection. You should not read from bitmaps nor textures. What you should do is to build a silhouette for your object (that is pretty easy, silhouette is just a list of positions). After that you need to build convex objects that fill the (non-convex) silhouette. It can be acheived by eg. ear clipping algorithm. It may not be the fastest, but it is very easy to implement and will be done only one time. Once you have the convex objects, you can transform their coordinates using a matrix and detect collisions with your world (there are many nice articles on ray-triangle intersections you can use), and you get the same precision as if you were to use pixel-based collision detection.
I hope it helps ...

Categories

Resources