Help with simple physics update!!

Started by
6 comments, last by Julian90 16 years, 1 month ago
I'm working on a platform game with some people in a class, and I'm having a problem with my physics class update. First of all, here is the physics code:

acceleration = force + gravity + (velocity * dragCoefficient);	
velocity = velocity + acceleration * dt;
position = position + velocity * dt; // UPDATES THE POSITION
force = force * frictionCoefficient; // SLOW DOWN!
dt is deltaTime and is in seconds. obviously it's a very very small number. acceleration, force, gravity, velocity, and position are all vectors (2D vectors with only an X and Y). I know that "frictionCoefficient" isn't the correct term for this, but i needed a way to slow the player down, and change their friction on icy terrain. I have some frictions #defined, such as #define FRICTION_AIR 0.998 and #define FRICTION_GRASS 0.6 Right now i have gravity set to Vector2D(0.0f, 100.0f). Yes, I know that 9.81 is proper. The real problem I'm having is that jump won't always work. And in order to get it to work I have to set force to -4000 in the Y. otherwise i just stay stuck. SO....yes...I know this is a bit scattered. If you need ANY info i'm not giving then let me know please. Basically I know there is something wrong with my physics update but i'm not sure what it is. I need to apply an initial force that makes more sense to make the character jump. -4000 is a bit much. in order to walk i'm currently doing force.x += 25 (for right...-= 25 for left) Please help..and thanks in advance!
Advertisement
The first thing that occurs to me to wonder about is that your air friction seems to be greater than your grass friction - surely this relationship should be the other way around?

It's perhaps worth noting, by the way, that unlike the forces that allow your character to walk, your jump force has gravity to overcome, so I would expect it, in this case, to at least be greater than 100 (or less than -100, it seems).

As to the actual equations, I'm not sure that your position equation is entirely valid, when the velocity equation is taken into account.

For zero acceleration, it's fine. However, when the acceleration is non-zero, it expands to

pos = pos + vel_old*dt + acc*dt*dt

However, I believe that the correct form of the equation is

pos = pos + vel_old*dt + 0.5*acc*dt*dt

That said, I'm not sure that it is likely to make much difference for a game - I think that I do something similar in my own code.

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Your problem is that :

force = force * frictionCoefficient;


...does not take into account the delta time. So if your game is running at 200 fps, your line becomes (after one second) :

force = force * pow(frictionCoefficient, 200);


While if you're running at 30 fps, it becomes :

force = force * pow(frictionCoefficient, 30);


So your game character will be much more slowed down at high frame rates. There's simple way to solve this but I can't think of it right now... You'll have to find a way to get "dt" into that equation.
Quote:Original post by Thaumaturge
The first thing that occurs to me to wonder about is that your air friction seems to be greater than your grass friction - surely this relationship should be the other way around?


like i said..friction is a bad word to describe this...basicallyt his just slows down the force so it won't stay constant. the reason FRICTION_AIR has a higher value than FRICTION_GRASS is because the close you get to 1 the less you're actually retarding the force. (i.e. if i had a force of 500. 500 * 0.6 = 300 but 500 * 0.998 = 499)

Quote:Original post by Thaumaturge
As to the actual equations, I'm not sure that your position equation is entirely valid, when the velocity equation is taken into account.

i thought that the equations for going from accel->vel-> position were all the same vel += accel * dt
pos += vel * dt
...am i wrong? :/


Quote:Original post by Trillian
Your problem is that :

force = force * frictionCoefficient;



...does not take into account the delta time. So if your game is running at 200 fps, your line becomes (after one second) :

force = force * pow(frictionCoefficient, 200);



While if you're running at 30 fps, it becomes :

force = force * pow(frictionCoefficient, 30);



So your game character will be much more slowed down at high frame rates. There's simple way to solve this but I can't think of it right now... You'll have to find a way to get "dt" into that equation.


yeah, i realize that my slowing of forces isn't effected by time right now, but i'm not really sure how to..besides just doing force = (force * friction) * dt but then won't i be required to add even more force to keep the player moving, since it will now be dropping even faster?

I keep a read out of my FPS on screen and it stays fairly steady. i know not having my friction be effected by a delta time isn't good...but i don't think that's the entire problem. of course i could be wrong...i'll play around with that.



I really appreciate the help. If anyone has any ideas on how to revise my current physics update it would be greatly appreciated. I have 3 different physics update algorithms i'm playing with and none seem to be working right...of course it is all my code...haha.

[Edited by - Holland on March 18, 2008 6:22:35 PM]
Quote:yeah, i realize that my slowing of forces isn't effected by time right now, but i'm not really sure how to..besides just doing force = (force * friction) * dt but then won't i be required to add even more force to keep the player moving, since it will now be dropping even faster?

I keep a read out of my FPS on screen and it stays fairly steady. i know not having my friction be effected by a delta time isn't good...but i don't think that's the entire problem. of course i could be wrong...i'll play around with that.


This will give a accumulated force of force0 * pow(friction * dt, N/dt) where N is the number of seconds which still isn't what you want, you need to do, force = force * pow(friction, dt) which will yield a total force of force0 * pow(pow(friction, dt), N/dt) = force0 * pow(friction, N) which is independent of the time step and so probably what you want.
Quote:Original post by Julian90
This will give a accumulated force of force0 * pow(friction * dt, N/dt) where N is the number of seconds which still isn't what you want, you need to do, force = force * pow(friction, dt) which will yield a total force of force0 * pow(pow(friction, dt), N/dt) = force0 * pow(friction, N) which is independent of the time step and so probably what you want.


but if i use force = force * pow(friction, dt) wouldn't that always set my force to 0 if i said i wanted 0 friction? should it be friction^dt or dt^friction?
Quote:Original post by Holland
Quote:Original post by Thaumaturge
The first thing that occurs to me to wonder about is that your air friction seems to be greater than your grass friction - surely this relationship should be the other way around?


like i said..friction is a bad word to describe this...basicallyt his just slows down the force so it won't stay constant. the reason FRICTION_AIR has a higher value than FRICTION_GRASS is because the close you get to 1 the less you're actually retarding the force. (i.e. if i had a force of 500. 500 * 0.6 = 300 but 500 * 0.998 = 499)


Aah, fair enough - that makes sense, then. ^_^

While I do agree with those who have mentioned your not including time in your calculation of friction, it doesn't seem to be likely to be the full problem here - if anything, from what you've said, I would think that for a given time period the resistance would be lower, and thus a jump should call for less force.

Quote:Original post by Holland
Quote:Original post by Thaumaturge
As to the actual equations, I'm not sure that your position equation is entirely valid, when the velocity equation is taken into account.

i thought that the equations for going from accel->vel-> speed were all the same vel += accel * dt
pos += vel * dt
...am i wrong? :/


That seems to be what my physics book indicates, I'm afraid. ^^;

Copied from that book:
v = v0 + a*t
x = x0 + v0*t + 0.5*a*t*t
v*v = v0*v0 + 2*a*(x - x0)
x - x0 = ( (v0 + v) / 2 )*t

These all, I believe, assume constant acceleration - which is probably an acceptable approximation, I think.

Note that if you choose to assume that there is no acceleration when the position is changed (i.e. that all forces act instantaneously), then x = x0 + v0*t - although in this case the velocity in question should, if I'm not much mistaken, be the velocity as measured after the instantaneous force (or forces) have taken effect.

(variables with an appended '0' indicate initial values - so "v = v0 + a*t" should be equivalent to "v += a*t")

As to your main problem...

Hmm... Let me see... If the velocity is high, a higher additional force is imparted, and if the "dragCoefficient" is high, a higher additional force is imparted.

This seems strange to me - you're actually adding force to an object, rather than retarding its motion. It also means that objects are retarded less the faster they go, which I think is the inverse of what should be happening.

Drag should surely be a force operating against the direction of motion - although it should, indeed, be proportional to the velocity.

I may, however, be missing something - I'll confess to being pretty tired. ^^;

It seems to me that there are three notable differences between motion in a jump and motion along the ground:
1) Jumping motion should (or at least could) have a higher initial velocity, I would imagine - at the least if it were combined with horizontal movement.
2) Jumping motion proceeds through air, which has a higher "dragCoefficient".
3) Jumping motion is subject to the additional force of gravity.

The additional force of gravity is set to 100, according to your first post - perhaps that's too high? Have you tried 10 instead? (Simple, I realise, but it's worth asking, just in case. ^^; )

That said, the higher initial velocity and higher "dragCoefficient" should counter that, to at least some degree... :/

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Quote:Original post by Holland
Quote:Original post by Julian90
This will give a accumulated force of force0 * pow(friction * dt, N/dt) where N is the number of seconds which still isn't what you want, you need to do, force = force * pow(friction, dt) which will yield a total force of force0 * pow(pow(friction, dt), N/dt) = force0 * pow(friction, N) which is independent of the time step and so probably what you want.


but if i use force = force * pow(friction, dt) wouldn't that always set my force to 0 if i said i wanted 0 friction? should it be friction^dt or dt^friction?


If you wanted no 'friction' then according to what you wrote previously you would set friction = 1 not 0, having friction = 0 roughly corresponds to infinite 'friction'.

This topic is closed to new replies.

Advertisement