Game Loop: Difference between revisions
No edit summary |
No edit summary |
||
| Line 68: | Line 68: | ||
==Independent Update and Draw== | ==Independent Update and Draw== | ||
Ideally game logic should be fixed step for a consistent experience, but game rendering should be able to run independently at the display's refresh rate. To achieve this <code>Update()</code> must be able to run independently of <code>Draw()</code>, a separation many programmers are familiar with (back end / front end, model / view, etc.). | |||
===Frame Interpolation=== | |||
The easiest way to implement this separation is with Frame Interpolation. | |||
[[Category:Basics]] | [[Category:Basics]] | ||
Revision as of 14:49, 9 June 2024
A game loop is a continuous loop that handles both running game logic and renders the game to the player.
Simple Game Loop
In the simplest example of a game loop, the game updates and draws at the same rate.
void GameLoop()
{
while (true)
{
Update(); // updates game logic (handle input, physics, collision, interaction, etc.)
Draw(); // renders game to player (images, sounds, 3d models, text, etc.)
}
}
In practice game loops may have a lot more code. They may wait a certain amount of time between passes, do less processing on certain passes than others, contain exit logic, etc.
This was a common way to design video games when they were first made, and came with the following pros and cons:
- Pros
- Even when the game slows down, physics and game logic are still processed in a consistent manner.
- Cons
- If either the
Update()or theDraw()took too much time, the game would slow down. - Game may not run at full speed on weaker hardware.
- Different versions of the game must be made in order to run at different framerates.
- If either the
Timesteps
There are two main types of timesteps:
- Fixed Step - the game loop processes equal intervals of game time
- Variable Step - the game loop processes varying intervals of game time based on how much real time has passed
While simple game loops originally all used fixed timesteps, some began to use variable timesteps as a way to address known issues:
// time of last iteration through game loop
DateTime lastTime;
void GameLoop()
{
lastTime = GetRealTime();
while (true)
{
// calculate elapsed real time
var time = GetRealTime();
var dt = time - lastTime;
Update(dt); // updates game logic (handle input, physics, collision, interaction, etc.)
Draw(dt); // renders game to player (images, sounds, 3d models, text, etc.)
lastTime = time;
}
}
This solved a few important issues but introduced new issues as well:
- Pros
- Game runs at full speed on weaker hardware.
- If either the
Update()or theDraw()took too much time, the game would keep running at full speed. - One version of the game can run at different framerates.
- Cons
- When the game slows down
- Physics and game logic are not processed in a consistent manner.
- Player inputs may be dropped.
- When the game slows down
Independent Update and Draw
Ideally game logic should be fixed step for a consistent experience, but game rendering should be able to run independently at the display's refresh rate. To achieve this Update() must be able to run independently of Draw(), a separation many programmers are familiar with (back end / front end, model / view, etc.).
Frame Interpolation
The easiest way to implement this separation is with Frame Interpolation.