Using box2d to detect collisions, but ignore the forces - libgdx

I'm using libgdx and box2d to detect collisions, but I want some collision to be detected but the forces not to play out.
Eg, I want to detect when the character collides with a coin but don't want the coin to affect the player's movements.
Is this even possible using box2d? If so, how can I go about doing it?

I'm not sure what you want do, but if I understand what you want to do, you can create a sensor fixture type, this pseudo example:
FixtureDef fd1 = new FixtureDef();
//fd1.friction = 0.5f;
PolygonShape pSTest = new PolygonShape();
//size you want for example:
pSTest.setAsBox(4f / PIXEL_POR_METRO,
1f / PIXEL_POR_METRO,
new Vector2(22f / PIXEL_POR_METRO, -1f / PIXEL_POR_METRO),
0f);
fd1.shape = pSTest;
fd1.isSensor = true;
yourBody.createFixture(fd1).setUserData("yourId");
looks ContactListener interface, for example preSolve
note that sensor, this is not called for sensors.
info
setAsBox(float hx, float hy, Vector2 center, float angle)
Parameters:
hx the half-width.
hy the half-height.
center the center of the box in local coordinates.
angle the rotation in radians of the box in local coordinates.

Quoted from: https://gamedev.stackexchange.com/a/22542
Read up on collision filtering in the Box2D manual:
Collision filtering allows you to prevent collision between fixtures.
For example, say you make a character that rides a bicycle. You want
the bicycle to collide with the terrain and the character to collide
with the terrain, but you don't want the character to collide with the
bicycle (because they must overlap). Box2D supports such collision
filtering using categories and groups.
Box2D supports 16 collision categories. For each fixture you can
specify which category it belongs to. You also specify what other
categories this fixture can collide with. For example, you could
specify in a multiplayer game that all players don't collide with each
other and monsters don't collide with each other, but players and
monsters should collide
Link to manual here. (Search for Filtering)
.

Related

Why disabling world gravity has no effect on moving rigid body?

I am building a sandbox for playing around and testing ammo.js (a javascript port of the Bullet physic engine v2.82). So this question should apply to both Ammo and Bullet I guess.
I am starting my scene with a falling sphere and the world gravity is set to (0, -9.8, 0).
Before the sphere touch the ground, I am disabling the world's gravity:
physicsWorld.setGravity(new ammo.btVector3(0, 0, 0));
I am expecting the sphere to "freeze" it's movement, since no gravity should be applied anymore, but the sphere is still falling and hit the ground. I am wondering why.
It's due to inertia. The first Newton's law says that if the forces applied on an object is zero (the case of your sphere after your gravity change), the acceleration is zero. But it does not mean that the velocity is null. In your case, the velocity will stay constant.
Another way to convince you is with Newton's second law which is probably coded in ammo.js:
ma = F
a is the acceleration, m the mass, F the sum of external forces.
Let's say that a = (v_{t+1} - v_t) / dt. With F=0, you will get v_{t+1} = v_t, a constant velocity.
v is the velocity, dt the time step.

Primitives and sprites Z index in Cocos2D-x 3.0 is not consistent?

I have two layers. Each layer has a primitive drawing in it with OpenGL like this:
void Layer1::drawPolygon()
{
glLineWidth(1);
DrawPrimitives::setDrawColor4B(255,255,255,255);
DrawPrimitives::setPointSize(1);
// Anti-Aliased
glEnable(GL_LINE_SMOOTH);
// filled poly
glLineWidth(1);
Point filledVertices[] = { Point(10,120), Point(50,120), Point(50,170), Point(25,200), Point(10,170) };
DrawPrimitives::drawSolidPoly(filledVertices, 5, Color4F(0.5f, 0.5f, 1, 1 ) );
}
When I addChild these layers to a scene and set Z orders 1 and 2, I see that I can bring one primitive on top of another and vice versa - when I exchange the Z order values. The strange things start when I addChild a sprite into one of these layers. If I addChild a sprite, then sprite lays on top of the primitive of that layer, and not only that layer. Even if the layer has smaller Z index, anyway its sprite is on top of other layer's primitive, while its primitive is below the other primitive shape - as was expected. Is this OK? How I should understand this? What if I want to draw primitives on top of all sprites?
EDIT:
I could manipulate their order, but not drawing order, with the following:
CCDirector::getInstance()->setDepthTest(true);
myLayer->setVertexZ(-1);
But I don't understand why sprites in a layer with smaller Z order are being drawn later than the primitives of the layer with bigger Z order. In other words, seems that all the primitives from all the layers is being drawn according to their order, then the same is being done for the sprites.
Due to the new multithreader renderer on cocos2d-x 3.0, drawing with primitives requires a different approach. Take a look at my reply at this thread:
https://stackoverflow.com/a/22724319/1468700
I believe there is a bug in cocos2d-x V3 beta 2 that makes primitive drawing always appear below all layers.
It is fixed (I understand) in V3.0 RC
This is incorrect - there is no bug (I was mislead by other posts - my apologies).
See the post below for a link explaining what needs to happen to get primitives to draw in the 'right' z-order.
The summary is that all drawing operations are added to a queue in the game loop, then the queue processed - so you need to add your primitive drawing into the queue rather than drawing immediately.

Split screen in Actionscript 3

I'm trying to make a pure AS3 game, and need a way to split the screen so that two players can have individual "cameras" that follow the around the game world. The problem is that a sprite can't have multiple parents. I'm trying to hack my way around this problem by having classes that duplicate sprites and manage all of their updates, but I'm not getting very far and my code is getting very, very ugly.
Does anyone know a good workaround or method for doing this? I can't seem to find much on-line on the subject.
I think you should use BitmapData copyPixels method
.copyPixels(point_0, rectangle_0)---> FirstPlayerScreen
World.Bitmap -
.copyPixels(point_0, rectangle_0)---> SecondPlayerScreen
Thanks for everyone's suggestions. What I've ended up with is a World class that I can add regular Sprite objects to as children. The World object manages and updates copies of those sprites, and world.getCamera() can be called as many times as necessary to display custom copies of the game world.
The key part is making copies of the sprites, this is the function I wrote to do that:
public function bitmapCopy(original:DisplayObject):Sprite
{
var returnSprite:Sprite = new Sprite();
if (original.width == 0 || original.height == 0) return returnSprite
var x = original.x; var y = original.y
var rotation = original.rotation
original.x = 0; original.y = 0; original.rotation = 0
var bounds:Rectangle = original.getBounds(original.parent)
var m:Matrix = new Matrix()
m.tx = -bounds.x
m.ty = -bounds.y
var bitmapData:BitmapData = new BitmapData( bounds.width, bounds.height, true,
0xFF0000 );
bitmapData.draw(original, m);
var bitmap:Bitmap = new Bitmap( bitmapData );
bitmap.x = bounds.x
bitmap.y = bounds.y
returnSprite.addChild(bitmap);
returnSprite.x = original.x = position.x
returnSprite.y = original.y = position.y
returnSprite.rotation = original.rotation = rotation
return returnSprite;
}
The returned Sprite can be added to the stage and will act in exactly the same way as the original (except for being static, of course). Hopefully this should help anyone else who comes across this problem.
Your theory is on the right track - you're probably just stumbling over your implementation. Organization and keeping things object-oriented will be your best friend in this scenario.
It's hard to give you a good example based off of a limited description of your game, but in general, I'd have a Screen class that can be instantiated multiple times, and I'd keep track of each instantiation (that gives us our multiple "players"). Each Screen has a stage, and you're building your game world on that stage.
The key here is data organization and good communication. Remember, there's only one "world", and you're just showing multiple instances of it. So you'll want a central Model to store data about every object in your singular game world. That Model will drive the rendering of that world to your multiple screens. If a player changes an object on their screen (let's say they move it), then you'll update the Model with that object's new location. Then, you'll broadcast those new coordinates to each Screen instance, so that all of your screens will update.
How you "broadcast" this can vary (and depends largely on the real-time nature of your game). If your game is very real-time and you're running a game loop, then you may just want to pass the objects' data along in every loop, and they'd update that way. If your game isn't as dependent of being real-time, then you can set up event listeners or a custom notification system that'll alert all of the instances of an object to update itself.
I know this is very high-level, but it's hard to give an in-depth answer without more info about your game. Hopefully this helps point you in the right direction - what you're attempting is definitely not simple, so don't get discouraged!
If you develop your game using MVC architecture principles then it should be trivial to draw your game twice, each player having an instance of the game's "view" but positioned according to a different character. If you give a layer mask to each instance then you could put the two instances side by side and so create a split screen effect.
Happy coding!
I'm working on a split screen myself just now:
masking to draw 1 world in 2 branches of your DisplayObject tree (separated cleanly), copying pixels for a split screen is a bad idea
data object to describe the world (not Sprite or DisplayObject)
Works very well so far. I've got 1 level, 2 players who move independently from each other and 2 screens that follow one player at a time. I see the other player in one player's screen and the one player in the other player's screen.
Here is how I did the data object part:
Define a central data object which describes the world and all it's world objects.
Write: make some sprites being able to manipulate 1 object of the world.
Read: update sprites by checking the properties of the world objects. 2 Screens -> 2 sprites for every world object. Check them every frame or try events.

Actionscript collisions: solving exceptions and strange cases

I have created a collision class to detect collisions using pixels. In my class I've also developed some functions for determining the collsion angle. Based on this I created some examples:
http://megaswf.com/serve/25437/
http://megaswf.com/serve/25436/
(Space to change gravity, right/left to give some speed to the ball.)
As you will probably notice, there are strange things that happen:
When the ball speed is very low
When the direction of the ball is
almost tangent to the obstacle.
collision http://img514.imageshack.us/img514/4059/colisao.png
The above image shows how I calculate the collision angle.
I call the red dots the keypoints. I search for a maximum number of keypoints (normally 4). If I find more then 2 keypoints, I choose the 2 farthest ones (as shown in one of the blue objects). Thats how I then find the normal angle to where in the surface the object collided. I don't know if this is an obsolete way of doing things.
based on that angle, I rotate the speed vector to do the bouncing.
The piece of code to do the maths is here:
static public function newSpeedVector(speedX: Number, speedY: Number, normalAngle: Number): Object{
var vector_angle: Number = Math.atan2(speedY, speedX) * (180/Math.PI);
var rotating_angle: Number = (2*(normalAngle - vector_angle) + 180) % 360;
var cos_ang: Number = Math.cos(rotating_angle/DEGREES_OF_1RAD);
var sin_ang: Number = Math.sin(rotating_angle/DEGREES_OF_1RAD);
var final_speedX: Number = speedX * cos_ang - speedY * sin_ang;
var final_speedY: Number = speedX * sin_ang + speedY * cos_ang;
return {x_speed: final_speedX, y_speed: final_speedY};
}
This is how the new speed vector is calculated...
My question is, has anyone faced this kind of problem or has some idea on how to avoid this from happening?
Without seeing your code, this is the best I can provide.
Collision physics should have some velocity threshold that is considered "stopped". That is, once the velocity gets small enough you should explicitly mark an object as stopped and exempt it from your collision code. This will help stabilize slow moving objects. Trial and error is required for a good threshold.
When a collision happens, it is important to at least attempt to correct any inter-penetration. This is most likely the reason why tangent collisions are behaving strangely. Attempt to move the colliding object away from what it hit in a reasonable manner.
Your method of determining the normal should work fine. Game physics is all about cheating (cheating in a way that still looks good). I take it rotation and friction isn't a part of what you're going for?
Try this. You have the contact normal. When you detect a collision, calculate the penetration depth and move your object along the normal so that is isn't penetrating anymore. You can use the two points you have already calculated to get one point of penetration, you'll need to calculate the other though. For circles it's easy (center point + radius in direction of normal). There are more complex ways of going about this but see if the simple method works well for you.
I have read and recommend this book: Game Physics Engine Development
I did something a little like that and got a similar problem.
What I did is that when the pixels from the bouncing object (a ball in your case) overlap with the pixels from the obstacle, you need to move the ball out of the obstacle so that they are not overlapping.
Say the ball is rolling on the obstacle, before your render the ball again you need to move it back by the amount of 'overlap'. If you know at what angle the ball hit the obstable just move it out along that angle.
You also need to add some damping otherwise the ball will never stop. Take a (very) small value, if the ball velocity is bellow that value, set the velocity to 0.
You can try one more thing, which I think is very effective.
You can make functions such as getNextX() and getNextY()(Which of course give their position coordinated after the next update) in your game objects and Check collision on objects based on their next position instead of their current position.
This way, the objects will never overlap, you'll know when they are about collide and apply your after collision physics gracefully!

Actionscript 3 pixel perfect collision. How to? (learning purposes)

I know that there are people out there creating classes for this (ie http://coreyoneil.com/portfolio/index.php?project=5). But I want to learn how to do it myself so I can create everything I need the way I need.
I've read about BitMap and BitMapData. I should be able to .draw the MovieClips onto a BitMap so I could then cycle the pixels looking for the collisions. However, It's weird and confusing dealing with the offsets.. And it seams like the MyBitMap.rect has always x = 0 and y = 0... and I can't seam to find the original position of the things...
I'm thinking of doing a hitTestObject first, then if this was positive, I would investigate the intersection betwen the movieclips rectangles for the pixel collisions.
But then there is also another problem (the rotation of movieclips)...
...I need some enlightment here on how to do it.
Please, any help would be appreciated..
If you're using BitmapData objects with transparency you can use BitmapData.hitTest(firstPoint:Point, firstAlphaThreshold:uint, secondObject:Object, secondBitmapDataPoint:Point = null, secondAlphaThreshold:uint = 1):Boolean.
You'll have to change from global coords to the local BitmapData coords which will require a bit of math if it is rotated. That's easily achieved (look up affine transform for more info on wiki):
var coordTransform:Matrix = new Matrix();
coordTransform.rotate(rotationRadians);
coordTransform.translate(x, y);
coordTransform.transformPoint(/* your point */);
A classic reference for pixel perfect collision detection in flash is this Grant Skinner's article. It's AS2, but the logic is the same for AS3 (there are ports available if you google a bit).
If I recall correctly, this particular implementation worked as long as both tested objects had the same parent, but that can be fixed.
About BitmapData x and y values, I understand it could be confusing; however, the way it works makes sense to me. A BitmapData is just what the name implies: pixel data. It's not a display object, and cannot be in the display list; so having x or y different than 0 doesn't really make sense, if you think about it. The easiest way to deal with this is probably storing the (x,y) offset of the source object (the display object you have drawn from) and translate it to the global coordinate space so you can compare any objects, no matter what's their position in the display list (using something like var globalPoint:Point = source.parent.localToGlobal(new Point(source.x,source.y)).
I've previously used Troy Gilbert's pixel perfect collision detection class (adapted from Andre Michelle, Grant Skinner and Boulevart) which works really well (handles rotation, different parents, etc.):
http://troygilbert.com/2007/06/pixel-perfect-collision-detection-in-actionscript3/
http://troygilbert.com/2009/08/pixel-perfect-collision-detection-revisited/
and from there he has also linked to this project (which I've not used, but looks really impressive):
http://www.coreyoneil.com/portfolio/index.php?project=5
I managed to do it after all, and I already wrote my class for collision detections,/collisions angle and other extras.
The most confusing process is maybe to align the bitmaps correctly for comparing. When whe draw() a movieclip into a a BitmapData, if we addChild() the corresponding Bitmap we can see that part of it is not visible. it appears to be drawn from the center to right and down only, leaving the top and left parts away from beeing drawn. The solution is giving a transform matrix in the second argument of the draw method that aligns the bitmap and makes it all be drawn.
this is an example of a function in my class to create a bitmap for comparing:
static public function createAlignedBitmap(mc: MovieClip, mc_rect: Rectangle): BitmapData{
var mc_offset: Matrix;
var mc_bmd: BitmapData;
mc_offset = mc.transform.matrix;
mc_offset.tx = mc.x - mc_rect.x;
mc_offset.ty = mc.y - mc_rect.y;
mc_bmd = new BitmapData(mc_rect.width, mc_rect.height, true, 0);
mc_bmd.draw(mc, mc_offset);
return mc_bmd;
}
in order to use it, if you are on the timeline, you do:
className.createAlignedBitmap(myMovieClip, myMovieClip.getBounds(this))
Notice the use of getBounds which return the rectangle in which the movie clip is embedded. This allows the calculation of the offset matrix.
This method is quite similar to the on shown here http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
By the ways, if this is an interesting matter for you, check my other question which I'll post in a few moments.