How to make some body move in specific trajectory?
I need some body to move up and down continuously ignoring gravity. Is there any way to do this with some body, or should i make it manually creating a new body in specific position in every iteration?
You must write the code for where it should be and just set its position before each simulation step. Also set its velocity if you want other objects that might bounce off it to behave correctly. Also give it infinite mass so it is a fixed object and won't be moved by things hitting it.
Set infinite mass like this when you create the body:
bodyDef.type = b2_staticBody;
Related
I'm working on a Little Mobile Game with Cocos2D-X and Box2D.
The Point where I got stuck is the movement of a box2d-body (the main actor) and the according Sprite. Now I want to :
move this Body with a constant velocity along the x-axis, no matter if it's rolling (it's a circleshape) upwards or downwards
keep the body nearly sticking to the ground on which it's rolling
keep the Body and the according Sprite in the Center of the Screen.
What I tried :
in the update()- method I used body->SetLinearVelocity(b2Vec2(x,y)) to higher/lower values, if the Body was passing a constant value for his velocity
I used to set very high y-Values in body->SetLinearVelocity(b2Vec2(x,y))
First tried to use CCFollow with my playerSprite, which was also Scrolling along the y-axis, as i only need to scroll along the x-axis, so I decided to move the whole layer which is containing the ambience (platforms etc.) to the left of my Screen and my Player Body & Player sprite to the right of the Screen, adjusting the speed values to Keep the Player in the Center of the Screen.
Well...
...didn't work as i wanted it to, because each time i set the velocity manually (I also tried to use body->applyLinearImpulse(...) when the Body is moving upwards just as playing around with the value of velocityIterations in world->Step(...)) there's a small delay, which pushes the player Body more or less further of the Center of the Screen.
... didn't also work as I expected it to, because I needed to adjust the x-Values, when the Body was moving upwards to Keep it not getting slowed down, this made my Body even less sticky to the ground....
... CCFollow did a good Job, except that I didn't want to scroll along the y-axis also and it Forces the overgiven sprite to start in the Center of the Screen. Moving the whole Layer even brought no good results, I have tried a Long time to adjust values of the movement Speed of the layer and the Body to Keep it negating each other, that the player stays nearly in the Center of the Screen....
So my question is :
Does anyone of you have any Kind of new Approach for me to solve this cohesive bunch of Problems ?
Cheers,
Seb
To make it easy to control the body, the main figure to which the force is applied should be round. This should be done because of the processing mechanism of collisions. More details in this article: Why does the character get stuck?.
For processing collisions with the present contour of the body you can use the additional fixtures and sensors with an id or using category and mask bits. For of constant velocity is often better to use SetLinearVelocity, because even when using impulse velocity gets lost at sharp uphill or when jumping. If you want to use the implulse to change the position of the body, then you need to use the code for the type of this:
b2Vec2 vel = m_pB2Body->GetLinearVelocity();
float desiredVel = mMoveSpeed.x; //set there your speed x value
float velChange = desiredVel - vel.x;
float impulse = m_pB2Body->GetMass() * velChange;
m_pB2Body->ApplyLinearImpulse( b2Vec2(impulse, mMoveSpeed.y), m_pB2Body->GetWorldCenter());
This will allow maintain a constant speed most of the time. Do not forget that these functions must be called every time in your game loop. You can combine these forces, depending on the situation. For example, if the at the beginning you need to make a small acceleration, it is possible to use ApplyForce to the body, and when a desired speed is to use ApplyLinearImpulse or SetLinearVelocity. How correctly to use it is described here: Moving at constant speed
If you use world with the normal gravity(b2Vec2(0, -9.81)), then it should not be a problem.
I answer for this question here: Cocos2D-x - Issues when with using CCFollow. I use this code, it may be useful to you:
CCPoint position = ccpClamp(playerPosition, mLeftBounds, mRightBounds);
CCPoint diff = ccpSub(mWorldScrollBound, mGameNode->convertToWorldSpace(position));
CCPoint newGameNodePosition = ccpAdd(mGameNode->getPosition(), mGameNode->getParent()->convertToNodeSpace(diff));
mGameNode->setPosition(newGameNodePosition);
P.S. If you are new to box2d, it is advisable to read all the articles iforce2d(tuts), they are among the best in the network, as well as his Box2D Editor - RUBE. At one time they really helped me.
I do not know if this is possible but I have an idea:
Keep the circle at a fixed position and move the background relatively. For example, during the course of the game, if the circle has a velocity of 5 towards left then keep circle fixed and move screen with velocity 5 towards right. If circle has 5 velocity towards left and screen has 3 velocity towards right, then keep circle fixed and move screen with 8 velocity towards left and so on. This should allow you to fix the circle at the center of the screen.
Another method would be to translate the entire screen along with the ball. Make everything on the screen an object that can have a velocity. And the x-component of the velocity of the ball (circle) should be the velocity of all other objects. This way, whenever the circle moves, all the other objects will try and keep up with it.
I have two dynamic bodies with a Contact Listener and lets call the bodies A and B.
When body (A.tag == Car) collides with body (B.tag == Cat) I don't want the car to be pushed back, I want the cat to be pushed but not push back on the car (Causing the car to stop too!)
I feel like I'm missing something simple but can someone please explain how I can manipulate the b2Contact so that one object does not change is velocity but the other does?
Thanks!
You can use PreSolve and PostSolve callbacks.
In PreSolve save the car velocity, angular velocity, angle and position somewhere - for example, as instance variables on car's userData object. In the PostSolve restore those values back.
PreSolve called just before those bodies collide and PostSolve is called right after the collision - when velocities are changed. Doesn't tried it myself, but should work.
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
Using physical engine Box2d C++, how to check the possibility of moving in a straight line a body to coordinate without collision (that is, how to know whether the obstacles to the body to coordinate) ?
Example:
We want to move Body A to Body B
Look picture:
Left example - get true, right - false.
I would create a dummy sensor, using the distance between A and B as height and A's width. Place the sensor halfway A and B and rotate it according to the path. Then you can place the sensor in one frame, check for collisions and remove the sensor whenever you want.
I'm making a game in which a certain object (modelled as a box2d body) has to follow a fixed path. Is there a way by which I can specify the path coordinates and make the object advance over it for each dt?
Thanks
Another option:
Attach a mouse joint to your body
Use setTarget method of the mouse joint to move the body
You should use a Kinematic body, but you can't change its position manually, you have to change its speed for the dynamics and collisions to be applied correctly.
I suggest the following algorithm:
1st - Calculate the position on the track that the body should be in on the next dt.
2nd - Make a vector going from the position where the body is to the next position.
3rd - Normalize it.
4rd - Calculate how much speed you need so that the body will be in that position on the next loop, and multiply that speed on the vector.
5th - Apply this vector to the Linear Velocity of the body.
Note: make sure the kinematic body has zero drag so that calculating the 4th step is easier.
I never did something like this, I think it can be done this way.
Hope it helps :)