GameLoop: Difference between revisions

From Pico-8 Wiki
Jump to navigation Jump to search
imported>Abchiptop
(Added see also)
imported>Dddaaannn
No edit summary
Line 1: Line 1:
== Game Loop ==
The game loop is the mechanism that drives a game's logic and rendering processes. Because each cycle of the loop updates the display, it is important for the loop to run at regular intervals to keep the animation smooth and the game feeling responsive to user input.
A Game Loop refers to the steps taken in order while a game is running.  


Pico-8 divides this into three major steps, [[Init]], [[Update]], and [[Draw]]. The Update-Draw loop runs 30 times per second.
Pico-8 has a built-in game loop that runs 30 times per second. You use this in your code by defining three functions: [[Init|_init()]], [[Update|_update]], and [[Draw|_draw()]].


=== Init ===
Both <code>_update()</code> and <code>_draw()</code> must be defined for Pico-8's game loop to execute. <code>_init()</code> is optional.
Init is arguably not a part of the game loop, because it happens before the loop begins, however, it's still important as part of the overall architecture. Init can be called later to reinitialize a cartridge, as a handy reset button.


=== Update ===
<pre>
Update is where you will store your game logic. Input and audio are handled here, as well as the calculations to bring the game to the next step. Update runs every frame, and is never skipped (unlike _draw(), which can be skipped).
-- initialize the position to be the center of the screen
function _init()
  xpos = 64
  ypos = 64
end


=== Draw ===
-- update the position based on the player pressing buttons
Draw is where the graphics are handled. Here you can make calls to other functions to help manage game state, or you can handle all drawing directly inside of the _draw() function. _draw() can be skipped during a frame, however, should the calculations and draw time combined take longer than a 1/30th second window.
function _update()
  if (btn(0) and xpos > 0) xpos -= 1
  if (btn(1) and xpos < 127) xpos += 1
  if (btn(2) and ypos > 0) ypos -= 1
  if (btn(3) and ypos < 127) ypos += 1
end


=== See Also: ===
-- clear the screen, then draw a circle at the current position
function _draw()
  cls()
  circfill(xpos, ypos, 10, 8)
end
</pre>
 
== Init ==
 
The [[Init|_init()]] function is called once when the cartridge is initialized. It is not part of the main game loop. However, it is a good practice when using the game loop to put all statements that initialize the cartridge in this function, instead of using statements at the top level of your code.
 
Pico-8 calls <code>_init()</code> automatically before starting the game loop if the game loop is being used.
 
== Update ==
 
The [[Update|_update()]] function is where the game performs all of its logic for the next frame. This is where you read user input, update the game world simulation, and start (asynchronous) music and sound events.
 
== Draw ==
 
The [[Draw|_draw()]] function is where the game does all of the work to draw the current state of the game to the screen.
 
Pico-8 attempts to call both <code>_update()</code> and <code>_draw()</code> 30 times per second. If the code takes longer than 1/30th of a second to execute, Pico-8 will skip the occasional call to <code>_draw()</code> so that the game world simulation has a chance to "catch up" to real time. The player is less likely to notice a missing <code>_draw()</code> call than slowness in the game simulation is slow.
 
== Writing your own game loop ==
 
If for some reason you want different behavior for your game loop than is provided by [[Update|_update()]] and [[Draw|_draw()]], you can implement a custom loop in your own code.
 
At the end of each frame, the Pico-8 game loop copies the graphics buffer to the screen, then waits until the next tick of the frame timer. To do this in your code, call the [[Flip|flip()]] function.
 
You can use the [[Stat|stat()]] function to measure the amount of time between ticks of the frame timer is spent executing your code. If <code>stat(0)</code> returns a value greater than 1, that means you passed a frame deadline without calling <code>flip()</code>, and you might need to do less work during the next frame (such as skipping draw calls) to catch up. This is how the built-in game loop determines whether to skip a call to <code>_draw()</code>.
 
== See Also: ==
* [[Init]]
* [[Init]]
* [[Update]]
* [[Update]]

Revision as of 22:02, 21 June 2016

The game loop is the mechanism that drives a game's logic and rendering processes. Because each cycle of the loop updates the display, it is important for the loop to run at regular intervals to keep the animation smooth and the game feeling responsive to user input.

Pico-8 has a built-in game loop that runs 30 times per second. You use this in your code by defining three functions: _init(), _update, and _draw().

Both _update() and _draw() must be defined for Pico-8's game loop to execute. _init() is optional.

-- initialize the position to be the center of the screen
function _init()
  xpos = 64
  ypos = 64
end

-- update the position based on the player pressing buttons
function _update()
  if (btn(0) and xpos > 0) xpos -= 1
  if (btn(1) and xpos < 127) xpos += 1
  if (btn(2) and ypos > 0) ypos -= 1
  if (btn(3) and ypos < 127) ypos += 1
end

-- clear the screen, then draw a circle at the current position
function _draw()
  cls()
  circfill(xpos, ypos, 10, 8)
end

Init

The _init() function is called once when the cartridge is initialized. It is not part of the main game loop. However, it is a good practice when using the game loop to put all statements that initialize the cartridge in this function, instead of using statements at the top level of your code.

Pico-8 calls _init() automatically before starting the game loop if the game loop is being used.

Update

The _update() function is where the game performs all of its logic for the next frame. This is where you read user input, update the game world simulation, and start (asynchronous) music and sound events.

Draw

The _draw() function is where the game does all of the work to draw the current state of the game to the screen.

Pico-8 attempts to call both _update() and _draw() 30 times per second. If the code takes longer than 1/30th of a second to execute, Pico-8 will skip the occasional call to _draw() so that the game world simulation has a chance to "catch up" to real time. The player is less likely to notice a missing _draw() call than slowness in the game simulation is slow.

Writing your own game loop

If for some reason you want different behavior for your game loop than is provided by _update() and _draw(), you can implement a custom loop in your own code.

At the end of each frame, the Pico-8 game loop copies the graphics buffer to the screen, then waits until the next tick of the frame timer. To do this in your code, call the flip() function.

You can use the stat() function to measure the amount of time between ticks of the frame timer is spent executing your code. If stat(0) returns a value greater than 1, that means you passed a frame deadline without calling flip(), and you might need to do less work during the next frame (such as skipping draw calls) to catch up. This is how the built-in game loop determines whether to skip a call to _draw().

See Also: