Hi so i am making a small sort of physics engine, but if your fps is really slow the physics will update slower and objects will move slower. How do i make the speed of objects greater if the fps is lower so that on a computer with 5 fps the object will land at the same time as on a 60 fps computer? (just with that slow framerate)
-
\$\begingroup\$ Just keep in mind to separate game engine and render thread \$\endgroup\$– SataCommented Dec 17, 2015 at 22:00
-
\$\begingroup\$ ...and this. \$\endgroup\$– Vaillancourt ♦Commented Dec 17, 2015 at 22:16
-
\$\begingroup\$ Please include examples of your code so that people can more effectively help. It also shows that you put effort into researching/figuring out the problem before you asked. \$\endgroup\$– Caleb LimbCommented Dec 17, 2015 at 22:43
2 Answers
Don't use frame rate as your mechanism of time. Rather, use time itself. If you want thing to run at '60' frames per second, you need to calculate everything in terms of time.
Lets say we choose milliseconds as our unit of time.
Now we can do the following:
int fps = 60;
double msPerFrame = 1000/fps;
When calculating your movements, rather than using the 'currentFrame', use the current running time of the sequence. Start the sequence, and on each frame tick, measure the time since start, and interpolate your values that way.
// assume calling 'now()' returns the time, GMT in ms.
long start = now();
void Update()
{
// get current time each Update
long now = now();
// total duration since starting the 'event'
long durationMs = now - start;
// use actual frames passed to do your 'physics' updates
// so erratic calls to update won't appear to make your movement
// incorrect.
long actualFramesPassed = durationMs / msPerFrame;
// ...
}
When handling games with a fixed time step, which is what you would need to simulate a physics system, it is best not to go with the system Timer as it is not as precise as other methods (even though the difference is small). Here is an example of how you might go about running a game loop that iterates 60 times a second.
I chose Java as you did not specify your target language.
public void run() {
double ns = 1000000000.0 / 60.0;
double delta = 0;
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
tick();
delta--;
}
render();
}
}
The running boolean would be set to true at the start of a program and is better practice than simply putting true, especially if there are multiple threads.
What makes this method better than using a Timer is if there is a hiccup or delay in one of the game ticks it is able to compensate. (ie. if the game for whatever reason only iterates 59 times in a second, the next second it will run 61 times) This is important considering performance issues will occur occasionally for whatever reason.
This also gives priority to updates since it will complete every update in query before it will render. Also if you have a different thread controlling the camera or something, it will continue rendering as long as there are available recourse. This is something you want especially in a first person game. (You don't want to limit how fast someone can look around based off of how fast the physics engine runs)
The tick() method would consist of all of the code to run the game. (The parts that include movement and such) The render() method would consist of all of the code to render a frame.