Pushing a spaceship around - cocos2d-iphone

I have a spaceship with two thrusters on it's base, one on the left and one on the right.
When the right thruster is on it should push the space ship in a parabolic curve towards the left as it is accelerating. and the reverse for the left thruster.
How do I implement this?
I've found something called "radian impulse" on box2d, would this do the job?
I would also like the physics the reverse the right thrust for a little bit (a bit like one of those cheap RC cars with just the one button) but only if the other thruster was used within a certain amount of time prior.
A working example (or something pointing in the right direction) with any library would suffice.

When you have rockets off center and only one fires, you are giving your ship torque. To simulate this you would need to split your rocket's thrust into two components. First one pushes your ship forward (in direction in which it is facing), second increases your rate of rotation. Example:
pos_x,pos_y - position
vel_x,vel_y - velocity
angle - angle where ship is facing in deg
angle_vel - speed of rotation in deg/s
thrust - how much to add to speed
torque - how much to add to angle
thruster_left, thruster_right - boolean, true if left or right truster is firing
function love.update(dt)
if thruster_left then
angle_vel=angle_vel+dt*torque
end
if thruster_right then
angle_vel=angle_vel-dt*torque
end
angle=angle+angle_vel
vel_x=vel_x+thrust*math.sin(math.rad(angle))*dt
vel_y=vel_y-thrust*math.cos(math.rad(angle))*dt
pos_x=pos_x+vel_x*dt
pos_y=pos_y+vel_y*dt
end

Related

Clamp angle with continuous result

I'm writing my own Inverse Kinematics and working on joint constraints currently. It's mostly fine but I want to remove all discontinuities from the resulting animation, and constraints are the biggest problem.
For example let's say you're looking at a ball rotating around your head. It rotates right and you look right, up to your neck twisting limit. The ball still moves and when it passes your back then your head will suddenly be clipped against opposite limit, looking left. This is what we get with typical clamping and it gives me frame-to-frame discontinuity.
What I need is that your head will get from right to left during few frames. My first idea is to reflect the source direction with my X axis (between shoulders) and if the reflected direction meets constraint limits - return it. If it doesn't meet the limits - clip the reflected direction instead of the source one.
This should give me the nice and continuous movement and it's not a rocket science but there're a lot of details to take care of. My limits may be like min < max but also max < min, they may pass through switching angle value (like 360->0, or 180->-180) or not. Besides, when my allowed range is bigger than 180deg then the logic should be slightly different.
The amount of different cases build up very fast so I'm wondering if I could find it already done somewhere?
BTW: I'm using Unreal engine if it makes any diffference.
EDIT:
I'm sorry if I've misguided you with my head example - it was just an analogy to visualize my needs. I'm not going to use this code to orient a head bone (nor any other) in a final animation. I'm planning to use it as a very basic operation in solving IK. It's going to be used in every iteration in every IK chain, for every bone, many times. So it need to be as fast as possible. All the higher level concepts, like movement planning, dynamics, etc. will be added on another layer, if needed.
For now I'm just asking for a function like:
float clampAngle( float angle, float min, float max )
that would return a continuous value for changing inputs.
I'm working on different issues currently, but I'll post my code when I get back to this one.
If you think of this as a simulation it will be a lot clearer. You won't need any planning, as in your comment, because the next frame is calculated using only information available on the current frame.
Set up one joint for the neck as described in your first two paragraphs. It will flip from left to right in one frame as the ball comes around.
Then set up a second identical joint and write an angular spring that will rotate it towards the first joint over time. By adjusting spring coefficients - strength, damping etc - you will have control over the way the head rotates.
How to write an angular spring?
This may not the best way, but the code is pretty short and easy, so here goes...
Lets call the 2 joints master and a slave. You need to store rotation phi and angular velocity omega on the slave joint.
phi and omega are axis-angle vectors - a 3d vector whose magnitude is the number of radians to rotate around the axis defined by the vector. It makes simulating rotations pretty easy. Whether your joint rotations are stored as euler angles or matrices or quaternions, you'll probably have some classes un UE API to help extract axis/angle vectors.
When master joint changes, convert its rotation to axis-angle. Lets call this phi_m.
On the start frame, the Slave rotation phi should be set to the same value as master. phi = phi_m. It has no angular velocity, so omega is set to the zero vector (0,0,0).
Then you move forward one frame. A frame's length dt is maybe 1/60 sec or whatever.
While simulating you first work out a new value for phi_m. Then the difference between master and slave ( the vector phi_m - phi) represents the torque acting on the slave joint. The bigger the angle the stronger the torque. Assume mass is 1.0 then using F=ma, angular acceleration alpha is equal to the torque. That means the change in angular velocity for the slave joint over that frame is alpha*dt. Now we can work out new angular velocity: omega = omega + (alpha*dt). Similarly, the new rotation is the old rotation plus change in rotation over time (angular velocity). phi = phi + (omega * dt)
Putting it all together and adding in a coefficient for spring strength and damping, a simulation step can go something like this:
damping = 0.01 // between 0 and 1
strength = 0.2 // ..experiment
dt = currentTime-lastTimeEvaluated
phi_m = eulerToAxisAngle(master.rotate)
if (currentTime <= startTime || dt < 0) {
slave.phi = phi_m
slave.omega = (0,0,0)
} else {
alpha = (phi_m - slave.phi)*strength
slave.omega = (slave.omega * (1.0 - damping)) + (alpha*dt)
slave.phi = slave.phi + slave.omega*dt
}
slave.rotate = axisAngleToEuler(slave.phi)
lastTimeEvaluated = currentTime
Notice that damping just kills off a little of the stored velocity. If damping is very low, the joint will overshoot and oscillate into place - boing!!
one approach:
define the region where the constraint cannot be satisfied (cone behind the head)
measure of how far into this region your target is (angle between target and center of cone divided by half cone angle)
us this scalar value to smoothly mix your constrained object back to some pre-defined neutral position (ie turn head back to center/rest position smoothly as target moves behind the head)

implement 2D gravity and basic collision C++ and OpenGL Tile based side scroller game

I have some questions for correctly implementing a system that add gravity to my player while still detecting and correcting collision with the floor. I understand the basic math for the AABB and adding gravity vector to the players velocity vector then adding it to the position. For some reason when I try the player stops for the first few frames then eventually the velocity builds up to be more than the tile width and it goes through. I guess my real question is how to properly implement the gravity with the collision. Do I make gravity vector 0, 0 when it hits the floor or when I am just standing on the floor my collision detection will constantly move me out of the floor? I really don't know the flow of the logic with this situation.
Edit 1:
I am trying to make the simple engine myself to gain experience with programming. I kind of solved the one problem, I now can stop on the floor. My current logic is:
add gravity to velocity, check for collision, adjust the velocity by the offset of the collision, if any, add velocity to the position then set velocity to 0.
m_velocity += m_gravity;
glm::vec2 mtd = collideWithObject(objectVector);
m_velocity -= mtd;
m_position += m_velocity;
m_velocity.x = 0.0f;
m_velocity.y = 0.0f;
It works but I am not sure if that is the flow, I guess I just want to know what is the most common way to implement this.
For some reason when I try the player stops for the first few frames then eventually the velocity builds up to be more than the tile width and it goes through.
If you are applying physics in increments - such as once every frame - you must account for the infinite increments that exist between each of those points.
For a simple "plane collision", like your floor, don't test if your current AABB collides with the floor. Create the smallest AABB that includes your current AABB and the last AABB. If that box collides, you've collided with the plane.
as #MorphingDragon mentioned, you should consider Box2D, many games use Box2D.
For your question "Do I make gravity vector 0, 0 when it hits the floor or when I am just standing on the floor my collision detection will constantly move me out of the floor? I really don't know the flow of the logic with this situation.". I just assume you know Verlet integration, for calculate your new position, you don't need to change your gravity, [as you know, gravity is everywhere on earth, or you want to do a game in space, ;)] you just need to handle the collision detection logic as "when collision happens, just make the collision point satisfy my constraints", and your constraint should be "all point should not be placed under the floor, otherwise just move it and make it sit on the floor".
The collection detection and constraint solver theory should be very common in modern physical engine and easy to understand and implement.
Hope this help.
Thanks
An

How to apply Orbital Gravity in cocos2d chipmunk

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.

Rotation and Movement with rigid body in Bullet Physics

I have made a rigid body for the player and have been trying to get the rigid body moving along with the player's controls.
What I mean is that whenever I press forward I want the rigid body to move forward in the direction the player is facing, same with back, left, right. So far I'm able to use apply force to move the rigid body in static directions.
My straight question is how do I move the player's rigid body in the direction the player is facing.
Other Details:
I don't really want to use kinematic bodies if not necessary mostly because their very fiddly at the moment
I'm using glfw3 for input
This is quite amazing that you would not see how to do that after you actually managed to apply forces in static directions to something you configured over bullet.
Come on, you HAVE the skill to figure it out.
Here, just a push in the direction (hehe), hem. Just take the vector of the facing direction (which could be determined by camera, 1st or 3rd view, or even something else...).
Congrats, this vector is your force by a k factor.
You should also modulate this force according to speed, you don't need to accelerate to infinite speed, just accelerate lots at first and then regulate force to tend to desired walk speed.
Then, the side directions are obtained by rotating the facing vector by 90 degrees around the standing axis (most surely the vertical). You can obtain that by simply swapping components and multiplying by -1 one of them. x,y,z becomes y,-x,z
To go backward, its just -x, -y, -z on the facing vector.
So your up key is not bound to 0,1,0 but to facing_dir actually. This facing dir can change with mouse or some other view controls, like numeric keys 2,6,8,4 for example. Or you could drop up,left,right,down for movement and use w,a,s,d like everybody else, and use direction keys to rotate facing direction. (+mouse)
It is much more difficult to obtain the facing vector from mouse movement or direction keys than finding out how to apply the force, so if you already have the facing vector I'm puzzled that you even have a problem.

Keeping Velocity Constant and Player in Position - Sidescrolling

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.