|This page has links to websites or programs not trusted by Scratch or hosted by Wikipedia. Remember to stay safe while using the Internet, as we can't guarantee the safety of other websites.|
The game loop is a method for writing games. The entire game runs on one loop, which handles the updating and rendering of content. Control over program execution is performed by a state machine. State machines are helpful as behavior grows more complicated. For this tutorial, we will create a simple top-down shooter based off of a game loop.
The main loop
when gf clicked set [game state v] to [start] reset timer forever set [old time v] to (timer) broadcast [update v] and wait broadcast [render v] and wait set [delta time v] to ((timer) - (old time)) end
The game loop broadcasts the "update" broadcast, a message to recalculate the game's data based on new information, such as pressed keys. The "render" message tells sprites to update the screen to reflect the updated data. The body of the game loop is known as a "tick." The "delta time" variable gets the execution time of a tick, so programmers may give their sprites constant speeds despite frame rate changes.
The update message
The update message updates the game's variables and handles the game logic.
when I receive [update v] if <(game state) = [game]> then set [show? v] to [true] if <key [left arrow v] pressed?> then change [x v] by ((-10) * (delta time)) end if <key [right arrow v] pressed?> then change [x v] by ((10) * (delta time)) end if <key [space v] pressed?> then create clone of [laser v] end else set [show? v] to [false] end
This script should appear in the player spaceship sprite. Its code is basically self-explanatory; the spaceship is moved with the left and right arrow keys, and the space bar shoots a laser.
when I receive [init enemies v] set [clone? v] to [true] set [y v] to  repeat (5) set [x v] to [-240] repeat (25) change [x v] by (20) end change [y v] by (-20) end set [clone? v] to [false] when I receive [update v] if <(game state) = [game]> then if <(my state) = [attacking]> then if <touching [laser v]?> then set [my state v] to [exploding] set [animation counter v] to  else change [y v] by ((-10) * (delta time)) set [costume v] to  if <(y) < (-160)> then set [game state v] to [lose] // If the enemy gets to the player, then the game is lost. end end if <(my state) = [exploding]> then if <(animation counter) > (4)> then //Replace 4 with the costume number of the last costume of the explosion animation delete this clone end set [costume v] to ((2) + (animation counter)) //Replace 2 with the costume number of the first costume of the explosion animation end else set [show? v] to [false] end
This is the behavior of the enemy sprite. This sprite has its own state machine because it has different behaviors for advancing towards the player and dying. The "animation counter" variable holds the current frame of its animation.
when I start as a clone hide set [x v] to ([x v] of [player v]) set [y v] to ([y v] of [player v]) set [clone v] to [true] when I receive [update v] change [y v] by ((10) * (delta time)) if <<(y) > (180)> or <touching [enemy v]?>> then delete this clone end
This is the code for the laser. It goes up, and disappears if it hits an enemy or goes offscreen.
when I receive [update v] set [x v] to  set [y v] to [-100] if <<(game state) = [start]> or <(game state) = [lose]>> then set [show? v] to [true] if <<touching [mouse pointer v]?> and <mouse down?>> then broadcast [init enemies v] and wait set [game state v] to [game] end end
This is the code for the play button. It appears at the start and after the player loses, and clicking it transitions the game to the playing state.
The "game state" variable is a global variable representing the entire game's state. The spaceship code should only run during a specific state. The other variables are local to their sprite.
The state machine
With the game loop method, program execution is determined by a state machine. A state machine is an abstract machine consisting of a set of states, which may transition to each other.
The render message
The render message tells the sprites to update their appearances.
when I receive [render v] if <(show?) = [true]> then show else hide end go to x: (x) y: (y)
Place this code in the player sprite and the button sprite.
when I receive [render v] if <(clone?) = [true]> then if <(show?) = [true]> then show else hide end go to x: (x) y: (y) end
Place this script in the enemy sprite and the laser sprite.