Movement relative to framerate

Blitz3D Forums/Blitz3D Programming/Movement relative to framerate

fall_x(Posted 2005) [#1]
Hi,

Originally I programmed my game to run at 40 fps. Then I decided I did not want this limit (mainly because my own computer couldn't run it that fast) and just let it run as fast as possible but then make all the movement relative to the current framerate. This was fairly simple, I have a variable like this :

unit=Float(frameDuration)/25.0

(frameduration is the difference between the last time and this time in milliseconds).

Then if I would want to move a character 0.5 unit every 40 frames, I just move it 0.5*unit. If the game runs at only 20fps, this would move it by 1 each frame, if the game runs at 80fps this will move it by 0.25 - so that's correct.

The only problem is when jumping. Basically my jumping works like this (simplified) :

If you press jump :
player\dy#=0.55

Every frame :
player\dy#=player\dy#-0.05

MoveEntity player\entity,0,player\dy#,0

Now my question is, how do I modify this so it also uses my unit variable, and that the player still jumps equally fast and equally high no matter what the framerate is (just more or less smoothly)? I just can't seem to get my head around this...

Thanks.


Koriolis(Posted 2005) [#2]
--==forget it==--


Gabriel(Posted 2005) [#3]
You may find it easier to use two variables to store the amount that each object ( in this case the player ) has moved this frame. Every time you find yourself modifying the position, just add to or subtract from these variables instead. Then at the end of your update function, right before you moveentity ( you only have to move entity once now ) multiply the change variables by your unit multiplier and move the player.


fall_x(Posted 2005) [#4]
--==forget it==--

why?

Sybixsus : I'm not sure if I fully understand, but I'll experiment and see if I get it to work. Thanks!


DJWoodgate(Posted 2005) [#5]
multiply both by 1/unit.


fall_x(Posted 2005) [#6]
multiply by 1/unit

Multiple what by 1/unit? The amount I move the player with moveentity? The amount I substract from dy#?
Thanks.


DJWoodgate(Posted 2005) [#7]
Yes, sorry, both of the forces..

player\dy#=0.55 * 1 / unit

Every frame :
player\dy#=player\dy#-0.05 * 1 / unit

Hmm. No that's not right either. Back to physics 101


Koriolis(Posted 2005) [#8]
why?
LOL, sorry for not having been crystal clear. I just made a post that I wanted to remove, that's all.


Gabriel(Posted 2005) [#9]
Sybixsus : I'm not sure if I fully understand, but I'll experiment and see if I get it to work. Thanks!


Sorry if my explanation wasn't great. All I'm saying is store up all your movements ( in variables or type fields ) until the end of the game loop. Then combine them all into one single total amount which your character will move on each axis, and multiply *THAT* by your unit multiplier.

EG: In a complex game, where your character is being affected by all sorts of things, it might be something like this :

The Y value might be affected by +0.2 due to an airflow from below, -0.05 from gravity, and -0.1 from some other force.

Total them to make +0.05 and multiply *THAT* number by your multiplier.


fall_x(Posted 2005) [#10]
Ok, but that wouldn't work. For instance, let's say the multiplier is 1 when it's running at 50fps, and 2 at 25 fps.

Now after 80 millisecs (4 frames at 50fps or 2 frames at 25fps), I will have added (Y * 1) 4 times at 50fps, and (Y *2) two times at 25fps.

If I give Y an intial value of 5, and each frame I decrement Y by 1 at 50 fps and by 2 at 25 fps :

At 50 fps : 4 + 3 + 2 + 1 = 10 total movement
At 25 fps : 0 + 3 + 0 + 1 = 4 total movements

(The zeroes are frames that aren't executed because it runs at half the fps, they're just there as dummy numbers, hope this is clear).

After Experimenting a lot in excell with collumns showing the progress at different FPS, I figuered out this formula :

dy=dy-unit

i=((unit^2)-unit)/2

(^ couldn't think of a fitting name for this variable :))

At 50 fps, i will be 0. At 25fps, i will be 1. At 12.5fps, i will be 6, at 100 fps, i will be -0.125.

movement = (dy*unit)+abs(i)


50.0 fps : 4 + 3 + 2 + 1 = 10 total movement
25.0 fps : 0 + 7 + 0 + 3 = 10 total movement
12.5 fps : 0 + 0 + 0 + 10 = 10 total movement


Sorry if I didn't explain it clearly, it's a bit complicated, but as far as I can see, it's correct.


fall_x(Posted 2005) [#11]
To clarify, here's an export of my excel document I used :

http://www.ontspoord.com/stuff/jumpspeed2.htm

The collumn on the left is the milliseconds. The number under the "move"-collumn shows the amount I have to move my player character that frame, and can be calculated with the formula I posted in my last post.


fall_x(Posted 2005) [#12]
Correction... If you want to modify dy# by another amount than unit, i needs to be multiplied by that amount :

dy=dy-(AmountToSubstractFromDY*unit)

i=(((unit^2)-unit)/2)*AmountToSubstractFromDY

movement = (dy*unit)+abs(i)

That seems correct, but could still be wrong. I'll do some more testing, if I find something I'll post it here.


RGR(Posted 2005) [#13]
;--


DJWoodgate(Posted 2005) [#14]
He is talking about jumping. Now the physics stuff I have seen usually work this out with elapsed time from the start of the event and absolute positioning, so you would have something like :

Ypos = Inital_Ypos+0.5*gravity*jumptime^2+jumpforce*jumptime

for instance (which will obviously work well given any reasonable frame time).

So the problem was to get it to work with delta time and relative positioning which I think he has got pretty close to. It should be possible to convert the above formula to a delta time method, but I have not worked it out yet or improved on what fall_x has come up with.

I guess you can avoid the problem by running your code at a set frame rate and using render tweening, as seen in the castle demo, although that can introduce other issues.