I am trying to use bullet physics library in my opengl game engine for collision detection.
I am not trying to do anything complicated, I only want to know when things collide in the 3d world. I am only using box shapes and I have no interest in moving the objects using physics (I have even disabled collision response for my rigid bodies).
I have managed to get the collision to work doing the following:
First, each frame I update the rigid bodies world transform based on the entity's transform it is attached to. For example I move my player right, the rigid body (and the bounding box) moves with me.
I am checking if 2 objects are colliding using this code:
void PhysicsManager::myTickCallback(btDynamicsWorld *world, btScalar timeStep)
{
int numManifolds = world->getDispatcher()->getNumManifolds();
if (numManifolds > 0)
cout << "COLLISION" << endl;
}
myTickCallback is the dynamics world internal tick call back: dynamicsWorld->setInternalTickCallback(myTickCallback);
What is weird now is that when I start up the game, I move my player on the other object I want it to collide with and it starts spamming COLLISION. If I leave the player on the object it will keep spamming it. However, if go away from the object and go back into it several times, after a while it just stops writing COLLISION.
I have checked if the rigid bodies are moving (if there is collision response) and there isn't.
This could be a problem in the game I am trying to create because I want the player to be hit by projectiles and it wouldn't be right if he stops getting hit after a while.
Related
I am working on a game in cocos2d / box2d, and have everything working well, moving sprite, collisions, etc.
I want to add some elements that influence my moving sprite without the sprite touching or colliding with them, and have no idea how to do that.
My sprite can collide with objects, and I can do that no problem - but I am looking for an object that influences my sprite WITHOUT a collision - for example a fan that would blow wind that would push the sprite away, or a magnet type device that would attract my sprite to it.
If my sprite collides with such objects then it should register a collision and die, but if it just moves NEAR to the objects, then it should be attracted or repelled.
Any thoughts?
You can apply forces (as in F = ma) to objects at any time to make them move.
Gravity in box2d is doing this all the time to make objects fall "down" if you have defined a gravity vector.
So, your fan doesn't have to be a real "object" in the sense that it has a body. You can apply the force from the fan at any time using the methods in box2d to the thing you want the fan to blow on. I have some code for an "EntityController" that applies thrust so it moves in a certain direction (target direction). This is the code for it:
void ApplyThrust()
{
// Get the distance to the target.
Vec2 toTarget = GetTargetPos() - GetBody()->GetWorldCenter();
toTarget.Normalize();
Vec2 desiredVel = GetMaxSpeed()*toTarget;
Vec2 currentVel = GetBody()->GetLinearVelocity();
Vec2 thrust = desiredVel - currentVel;
GetBody()->ApplyForceToCenter(GetMaxLinearAcceleration()*thrust);
}
In this case, the body is moving towards a target. But it could just as easily been the target is the direction the fan is blowing in and now the center of mass of the "thing being blown" is being pushed away from the fan.
All my objects have a maximum speed (GetMaximumSpeed(...)), so this function will only apply force until the object is moving at the max speed and then not apply any more (it is a natural feedback loop).
You are welcome to look at the rest of the code base here on git hub. It is also talked about in this post. Note that this is in cocos2d-x (C++), but the same c++ code will work in cocos2d if you declare the files as .mm (allows c++ code). Or just use the technique without the code as you see fit.
Was this helpful?
Im using Level Helper and SpriteHelper to create my sprites, images, levels and more importantly animations and physics.
Note, by physics i mean the debugdraw you can see on the simulator that is used for collision detection.
I created a swimmer and added physics to this. Done the code so the physics follows the swimmer around the pool as they move. I have now come to animate the swimmer, make the legs kick etc. Now when i load my game and only the first sprite of the animation is the outline for the physics. So i can see the legs kicking on the swimmer but the debugdraw mesh of the physics doesn't animate as well. Now this is not really a problem until for example my swimmer loses their legs (weird game i know). I change the animation to now a swimmer with no legs but again the physics mesh still shows the legs. So any collisions with stuff still happens where the legs were but they shouldnt. This make sense?
Is there a way to update the physics on the new animation or do i need to remove my whole swimmer and draw a new one?
Any help at all would be great. Thanks
This makes sense, since your sprite uses the same box2d mesh in both states. If you want to have a different collision behavior after altering your Sprite, you should assign another (smaller) mesh body.
Note that even in cocos2d side, your sprite still has the same container box with the new animation.
In order to keep using the SpriteHelper functionality you might want to create 2 different sprite-body sets: one with the full body, then after the "accident" replace it with the legless sprite.
Now, gameplay-wise, my opinion is that there shouldn't be any collision for the legs anyway. since they are moving, players will not find it weird to have them not colliding. You could use a mesh body with no legs and use it for both sprites. Except if you want to have different collisions as a gameplay feature (Like giving the player the choice to cut his legs in order to fit in a smaller cave etc)
I am trying to make an object get attached on a collision point to a circle that is rotating, but the player needs to get attached with a constant point on the player. For example the player is moving back and forth and when the user touches the screen and the player jumps up but what I need is that when the player collides with the circle it attaches it's legs to it and continues rotating with the circle. So I wanted to know how to make this kind of collision joint in cocos2d box2d?
When the collision between the user and the circle is detected, you could run an action that calls a callback function (perhaps a CCCallFuncND). The callback function could be passed pointers to both bodies (wrapped in NSValue valueWithPointer) and create an arbitrary joint between them. This would be done by first instantiating a b2JointDef of the desired type, defining bodyA and bodyB for that joint as the two bodies you'd like "stuck together", and then calling b2World->CreateJoint().
In terms of attaching the player body to a specific point on the circle body, you'd have to do so via some parameter of the joint def like anchorPoint. For example b2PrismaticJoints have anchorPoint which defines the center of the joint's range of motion.
I have a simple question about a game I am making using box2D and cocos2D. I started using the physics engine yesterday so I am rather inexperienced with its usage and capabilities. My game involves rolling a ball around the screen using the accelerometer. I want to add holes to the ground that if the ball rolls into, it will then require a greater acceleration via the accelerometer to escape the hole pocket. I've toyed with friction, linear damping, modifying the accelerometer's gravity vector, and tried adding attractive forces but I haven't had too much success and some of it doesn't really simulate well what I want happening. Basically I just want to create some sensors and give them the properties of a small pocket a ball can fall in to. Any tips and advice is much appreciated. Thanks
I suggest you to use Level Helper . Its an awesome tool to create physic based games.
You can find it here
You could take the y position of the ball every frame and if it is below a certain threshold, then it is in a hole. Based off on this, if the ball is in a hole, reduce the sensitivity. When the ball exits the hole, put the sensitivity back to normal.
As for creating the holes, use Vertex Helper to create bodies that will correspond to your sprites.
If you need more explanation, feel free to ask.
Elaborated:
Now, basically in the picture, I am depicting what I tried to describe earlier. All you really have to do is to change the tilt sensitivity if the player's Y position is below a certain point. I just used 50 as an example.
Some pseudocode:
- (void)update:(ccTime)dt
{
if (player.position.y >= 50) { //If the player's y position is above or equal to 50
if (sensitivity != normalSensitivity) { //We don't need to set it every frame, so lets check
sensitivity = normalSensitivity;
}
}
if (player.position.y < 50) { //If player's position is below our threshold of 50
if (sensitivity != limitedSensitivity) { //Check so we don't set the sensitivity every frame
sensitivity = limitedSensitivity;
}
}
}
Now, as far as Vertex Helper is concerned, it is an open source tool (I believe) that helps you define vertices for custom shapes that can then be copied and pasted directly into your box2d or chipmunk cocos2d project. It can be fond here.
I suggest googling around for tutorials on how this is used. It is very simple, but you may need a quick reference to get you started.
Finally, something to remember, is that box2d can only work with convex shapes, not concave.
A convex shape is a shape where in is impossible to draw a line from any vertex to another without passing through the shape itself. Basically something that has no indentations in it.
I hope this helped. I'm not sure I can elaborate anymore than I have, but if you have more specific questions, feel free to ask.
I'm making a game in cocos2d with box2d and I'm running into some issues.
I have the program iterate through a tilemap's (.tmx) rows and columns , searching for tiles with a "collidable" property set to "true". If one is found, a square static box2d body (with fixtures and all) is set at that tile's position. So essentially, I should end up with a bunch of square bodies set up where I need them (depending on the tilemap) after the iteration is complete. I also have a square dynamic body that is controlled by gesture (up gesture slides it upward, down gesture downward, etc.), and it is supposed to only move in one of four directions: up, down, left, right. The restitution of the body is 0.0f so that it stops on impact with no rebound, and the friction is 0.0f as well because it's not needed (gravity of the world is 0.0f, 0.0f too). Since the iteration through the tilemap can only place bodies that are square, the "walls" in the game are composed of several of these squares lined up adjacent to each other, end to end, which creates a flush edge for the dynamic body to collide with.
The problem arises when the dynamic body collides with the wall of squares. I control movement of the body by setting the velocity of the body according to the gesture. An example of movement to the right would be:
#define bodyVel 100
...
if (gestureRight)
{
body->SetLinearVelocity( b2Vec2(bodyVel / PTM_RATIO, 0) );
}
I have the body set as a bullet so that when it collides with the wall it will not become embedded, but I have encountered some weird results. An example would be this:
I move the body rightwards into a wall and it stops. Good. Next, I want to move it up, so I gesture upwards. Good. But then, at times, as it is sliding up the wall, the body seems to "catch" on to something and it spins out of control and in multiple directions. Bad.
The only explanation I can come up with is that the dynamic body is in fact becoming imbedded in the wall upon the first head on contact, and as it slides up the wall upon the next given gesture for movement, it gets caught on the one of edges of the squares that make up the wall and becomes jarred from a straight path. I confirmed this strange activity by setting the body to have a fixed rotation (not rotate at all), and consequently, instead of the body spinning out of control, it would simply stop. This was expected given my hypothesis. So the dynamic body is becoming embedded is what I'm trying to say.
I don't understand why this is happening because I have the body set to behave like a bullet to avoid problems exactly like this. All I want the object to do is be able to move along a straight path - either up, down, left, or right -, stop upon contact with a wall, and move along the wall without interference from the bodies that make up the wall.
I feel like unless I have a misunderstanding of how bullet bodies work, the embedding that is occurring should not be an issue.
I also used to DebugDraw to see if the square static bodies created a flush wall and they did.
Unfortunately, this is a known issue in Box2d... from the FAQ:
Tile Based Environment
Using many boxes for your terrain may not work well because box-like
characters can get snagged on internal corners. A future update to
Box2D should allow for smooth motion over edge chains. In general you
should avoid using a rectangular character because collision
tolerances will still lead to undesirable snagging.
For more information see this post:
http://box2d.org/forum/viewtopic.php?f=3&t=3048