i am trying to understand how to implement the physics of sprite when it hit a wall.
lets say i have a wall, and a sprite is is hitting the wall with velocity and gravity using box2d(cocos2d), what is the simplest way to apply a physics of what happen next to the hit, regrading the velocity,gravity,angle of collision, etc ? contact listener ? do i have to calculate what happen next by my self and apply a new speed and force to the body ??
or box2d does it for me ?
any direction would be great.
thanx.
box2d calculates everthing for you. You don't have to worry about what happens after two bodies collide.
If your body hits ground it will bounce as its natural response. You dont have to apply a new force opposite to the gravity. All calculations are done by box2d physics engine. Physics engines are made for that.
In addition to this, if you want you can apply your own forces or impulses like below. It is up to you.
b2Vec2 force = b2Vec2(100, 200);
yourBody->ApplyLinearImpulse(force, yourBodyDefinition.position);
Related
On tapping on screen I`m gonna apply impulse and angular rotation to sprite to move it to the sides. But after some time OR parameters of physics body attached to sprite should go back to initial (impulse 0, angular speed = 0). What are the best ways to do that (use CCAction or on update detect parameters of physics body and change them to initial)?
If i were in your position, I would probably start a timer at the first collision of the sprite and then use a CCAction to transition to the initial state to make it look smooth. Don't know if its the best way though.
I am building an IOS game in Cocos2d - Chipmunk - Spritebuilder. I need to make a characters orbit around around a point, and I was having quite some difficulty in implementing orbits with real physics.
So far, I have tried two methods, one is creating a distance joint from the player to the planet, and then applying a 90 degree force on the player where an angle is created between the end of the distance joint and an imaginary line drawn at a 90 angle to it. He moves around crazily and this method is not working for me.
I then tried calculating 180 points on the circumference at a radius from the planet (which is the bounds of detecting and implementing its effects on the player) - and then in a scheduled update method [character.physicsbody applyForce:nextCircumferencePoint]; This does not work, as he does not follow the path exactly and is quite far from it. I am thinking that I need to also apply a gravitational force towards the planet which would cause him to circle it. Though I don't know how to calculate that force, apply it, or if it would even help.
A third method which would never work, but was used for testing was to set his position to the next circumference point. He does orbit, but any collision won't work (such as if a piece of space junk goes in his way.) He will simply be positioned right over any other object. This world great if you don't need collisions, are writing your own physics engine. This is not a polished way of doing things, so will avoid it.
Please correct anything I have already done and tell me how it would work, or shed light on other options and how to implement them.
Check out my answer here. It's for box2d, but you can do it with Chipmunk. If bodyA position will change, orbit will be same. You just need to change speed of body movement for your needs, just increase smoothness and slow down your update method.
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 am trying to learn box2d in cocos2d. I have searched for online tutorials and ray Wenderlich's seem to be the best ones!I am learning in a slow but steady pace! I am currently developing an app in which I will include a ball in the screen, and every time I touch/tap this ball, it is going to move like someone is flicking a soccer ball. I have coded the part for the upward movement(y axis) of the ball, when touching/tapping it. The problem that I encounter is that I can not find a way to give the ball the appropriate angle in order to rotate and move on the x axis. Let me give you an example. Imagine you are flicking a soccer ball, you kick the ball upwards but also there is a spinning force on the ball. I am trying to develop the spinning and moving across the x axis part. I would like to touch the ball, in its lower right "corner" for example and spin and move in a realistic way. Touching it in the lower right "corner" while the ball is in the air, means that the ball will move and spin to the left side of the screen. I hope I clarified the situation! I would be grateful if someone could help me to understand that kind of movement! If you still haven't understand the concept of my game, search for "parksoccer" and you will understand what I am trying to develop.
I did this yesterday only. In this case what you can do is when you touch or tap a screen , you take that point in ccTouchesBegan and then find the position of the ball by GetPostion() method on body. Than you have to calculate the angle between these two points and find in which direction ball will go from these two points. now you have angle and direction in which ball will go so apply linearForce on that by ApplyLinearForce(b2vec2 forceangle, body->GetPosition()). Thats it.
Enjoy.
I am developing third-person shooting game using Bullet and Ogre. When the character model collides with an object in the world, such as a power-up, the collision applies a force to the character and causes them to spin. How can I prevent the collision applying a force to the character?
I have set a method for btDynamicsWorld::setInternalTickCallback and so I know which bodies are colliding and the btManifoldPoint.
Note that I applyTorque to the body in order to rotate them smoothly so I cannot simply prevent rotation.
Thanks for your help.
I am unfamiliar with the physics engines you mentioned, but I know a thing or two about real physics...
Basically if you draw a free body diagram and arrows that represent the forces, you can determine the net effect. Or if you know the desired net effect, you can figure out where you need to add forces or remove forces.
You could add an equal and opposite force/torque at the time of impact. This would make the net forces on your object zero.
Or you could take the elements that are causing the forces and make them massless. Force = mass * acceleration. If the mass is zero and your physics engine is based on real world physics, then it shouldn't cause any net forces on collision.
Hope that helps.