Java-Gaming.org Hi !
 Featured games (91) games approved by the League of Dukes Games in Showcase (799) Games in Android Showcase (237) games submitted by our members Games in WIP (865) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Using delta time messes up movement  (Read 9247 times) 0 Members and 1 Guest are viewing this topic.
Ivan Vinski

Senior Devvie

Medals: 5
Projects: 1
Exp: 3 years

Learning how to place those pixels nicely.

 « Posted 2015-04-19 09:15:21 »

Using delta time with my speed variables actually don't make it so nice, after all. The movement is smooth, but still the speed is different on all computers.

I want to have some kind of a constant speed, but also a smooth movement, on all computers. My girlfriend has an older laptop and when she runs my game Sokobanski, the character really moves slowly, while on my computer it's like the normal speed. And when my brother runs my game on his new powerful PC, the character there moves too quickly.

So, my question is, how do I create a smooth constant movement? How to make the movement same on all computers?

rwatson462
 « Reply #1 - Posted 2015-04-19 10:28:17 »

Do you know what sort of numbers you are getting with your delta time?  i.e, on your computer is your delta time around 20 and on your girlfriend's laptop is it around 100?  That could be a problem if delta is the same on all machines when they're actually running at different frame rates.

Also, you need to make sure you're scaling the distance moved by delta so they move the same amount over a set period of time (i.e. 100 pixels per second) which when multiplied by delta gives you a movement value:

 1  2 `distance_per_second = 100; // pixels per seconddistance = distance_per_second / (1000 / delta);`

Usually this should result in moving barely a pixel or 2 per frame to create a smooth looking movement.

Difficult to tell really without seeing some code of yours
trollwarrior1
 « Reply #2 - Posted 2015-04-19 16:56:13 »

You need to get delta time between frames. You can do that manually, or try to find some kind of function that is already made in the framework / engine you are using. If you are using Libgdx that would be:
 1  2 `float deltaTime = Gdx.graphics.getDeltaTime(); // interpolated delta time, secondsfloat deltaTime = Gdx.graphics.getRawDeltaTime(); // raw delta time, seconds`

Next, you need to make a speed variable. It would mean the distance the moving object covers in 1 second. For example:
 1 `float speed = 100.0f; // object will move 100 pixels per second`

When updating the position of the object, you simply multiply speed by delta time and add it to the position of the object.
 1 `object.position += speed * deltaTime;`

This way the object will move the same amount of distance regardless of the frame rate.
Ivan Vinski

Senior Devvie

Medals: 5
Projects: 1
Exp: 3 years

Learning how to place those pixels nicely.

 « Reply #3 - Posted 2015-04-19 23:30:31 »

Thank you for replies, trollwarrior1 and rwatson462!

I figured out there is something else wrong with the movement of entity. So, here's how the movement works. Once entity's destination (variables newX and newY) are set, entity moves towards those coordinates first on x-axis, then on y-axis. But, there is a problem. This only works if speed is set to 16, otherwise either newX or newY will never be equal to entity's x or y. Here's the code:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32 `    public void update(float delta){        float x = sprite.getX();        float y = sprite.getY();        float speed = (float) Math.floor(950 * delta);        if(speed < 16 || speed > 16)            speed = 16;                if(x != newX){            if(x < newX){                sprite.setX(x + speed);            }else if(x > newX){                sprite.setX(x - speed);            }                        moving = true;        }                if(y != newY){            if(y < newY){                sprite.setY(y + speed);            }else if(y > newY){                sprite.setY(y - speed);            }                        moving = true;        }                if(x == newX && y == newY){            moving = false;        }    }    `

I tried working around this problem, but then the movement turned to tile-based on x-axis, and never finished on y-axis. Here's the code:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43 `    public void update(float delta){        float x = sprite.getX();        float y = sprite.getY();        float speed = 64;                if(x != newX){            if(x > newX - 1){                sprite.setX(newX);                return;            }else if(x < newX + 1){                sprite.setX(newX);                return;            }else{                if(x < newX){                    sprite.setX(x + speed * delta);                }else if(x > newX){                    sprite.setX(x - speed * delta);                }                                moving = true;            }        }                if(y != newY){            if(y - 1 > newY && y + 1 < newY){                sprite.setY(newY);            }else{                if(y < newY){                    sprite.setY(y + speed * delta);                }else if(y > newY){                    sprite.setY(y - speed * delta);                }                                moving = true;            }        }        if(x == newX && y == newY){            moving = false;        }    }    `

I'm not sure if I'm becoming dumber because it seems like this problem has a very simple solution. Someone help me, please?

trollwarrior1
 « Reply #4 - Posted 2015-04-20 05:31:05 »

It should like something like this:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27 `if(x != newX){    if(x > newX - 1 && x < newX + 1){        sprite.setX(newX);    }else{        if(x < newX){            sprite.setX(x + speed * delta);        }else if(x > newX){            sprite.setX(x - speed * delta);        }                moving = true;    }}if(y != newY){    if(y > newY - 1 && y < newY + 1){        sprite.setY(newY);    }else{        if(y < newY){            sprite.setY(y + speed * delta);        }else if(y > newY){            sprite.setY(y - speed * delta);        }                moving = true;    }}`
Ivan Vinski

Senior Devvie

Medals: 5
Projects: 1
Exp: 3 years

Learning how to place those pixels nicely.

 « Reply #5 - Posted 2015-04-20 14:03:39 »

Thank you! It works perfectly now! Thank you very much!

jonjava
 « Reply #6 - Posted 2015-04-26 07:59:17 »

Or better yet use a fixed step game loop. A variable step loop is more often than not a mistake.

Roquen

JGO Kernel

Medals: 518

 « Reply #7 - Posted 2015-05-01 14:54:10 »

Fixed time steps for the win.
Ivan Vinski

Senior Devvie

Medals: 5
Projects: 1
Exp: 3 years

Learning how to place those pixels nicely.

 « Reply #8 - Posted 2015-05-05 13:57:25 »

Currently I'm using LibGDX which means I'm stuck with variable step loop until I start developing my own library.

Springrbua
 « Reply #9 - Posted 2015-05-05 14:44:29 »

You are not really stuck with variable step loop.
You could do something like this
So basicly you store a float, which stores the remaining frametime. The you cycle through a loop, as long as the remaining frametime is bigger then or equals your TIME_STEP.
You update the logic, using TIME_STEP as delta and decrease the remaining frametime by TIME_STEP.

Example:

TIME_STEP of 1/60 = 0,017sec

1) 60FPS: frametime = TIME_STEP, logic update once
2) 10FPS: frametime = TIME_STEP * 6, logic updated 6 times
3) 120FPS: frametiem = TIME_STEP/2, logic updated every 2 Frame only.

The result is drawn once per frame, but the logic is calculated more accurate, with lower delta times.

You might limit the maximum frametime, as low frametimes mean many calculations, which may increase frametime, which means even more calculations...
jonjava
 « Reply #10 - Posted 2015-05-06 08:44:53 »

What @Springrbua is describing is a simple time accumulator.

In code it could look like this (javascript):

 1  2  3  4  5  6  7  8  9  10 `module.exports = function(rate) {   var accum = 0;   return function(time, callback) {      accum += time;      while (accum >= rate) {         accum -= rate;         callback(rate);      }   };};`

source: https://github.com/ericlathrop/time-accumulator

Might also want to check out this:

Riven

« JGO Overlord »

Medals: 1370
Projects: 4
Exp: 16 years

 « Reply #11 - Posted 2015-05-08 08:01:06 »

except the 'rate' variable should be renamed to 'interval', or the logic should be changed.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Ivan Vinski

Senior Devvie

Medals: 5
Projects: 1
Exp: 3 years

Learning how to place those pixels nicely.

 « Reply #12 - Posted 2015-05-10 12:41:55 »

Thank you guys for telling me this! I appreciate it!

I will finish the current game I'm developing using variable step loop because I'm almost finished with it and I'd have to change a lot of things. I certainly will try your ideas out on the game I'll develop next.

Pages: [1]
 ignore  |  Print

 Riven (203 views) 2019-09-04 15:33:17 hadezbladez (4941 views) 2018-11-16 13:46:03 hadezbladez (1820 views) 2018-11-16 13:41:33 hadezbladez (5217 views) 2018-11-16 13:35:35 hadezbladez (1028 views) 2018-11-16 13:32:03 EgonOlsen (4402 views) 2018-06-10 19:43:48 EgonOlsen (5235 views) 2018-06-10 19:43:44 EgonOlsen (2976 views) 2018-06-10 19:43:20 DesertCoockie (3878 views) 2018-05-13 18:23:11 nelsongames (4311 views) 2018-04-24 18:15:36
 Java Gaming Resourcesby philfrei2019-05-14 16:15:13Deployment and Packagingby philfrei2019-05-08 15:15:36Deployment and Packagingby philfrei2019-05-08 15:13:34Deployment and Packagingby philfrei2019-02-17 20:25:53Deployment and Packagingby mudlee2018-08-22 18:09:50Java Gaming Resourcesby gouessej2018-08-22 08:19:41Deployment and Packagingby gouessej2018-08-22 08:04:08Deployment and Packagingby gouessej2018-08-22 08:03:45
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org