Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Game Loop Basics

The whole lesson is here to read. Create a free account to run it in a live lab.

Container lab13 min read7 commands

A game is a loop

Think of a flip book. Each page is a picture, and flicking through them makes things move. A game works the same way: sixty times a second it works out where everything is now, draws one picture, and starts again. Catch the stars is a small game of that kind. Stars fall from the top, you slide a box along the bottom to catch them, and you lose a life for every star that gets past.

By the end of this lesson

Note

I can say what a game loop does on every frame, and check a game's gravity and collisions with a short script.

Key words

  • Frame: one picture of the game, drawn many times a second.
  • Game loop: the code that runs once for every frame: update, then draw.
  • Constant: a named number at the top of the code, such as GRAVITY, that you can change in one place.
  • Gravity: a number added to a falling thing's speed on every frame.
  • Collision: two things touching, found by comparing their boxes.
  • Game state: what the game remembers, such as the score and the lives.

Starter: what you already know

Note

Answer in your head. 1. If a ball is dropped, does it fall at the same speed all the way down? 2. How would you tell that two boxes drawn on paper overlap? 3. What would you want a game to show you after you have lost? Answers: no, it speeds up; check whether one starts before the other ends, across and down; a message and a way to play again.

Before you start

Note

Press Start the lab on the bar at the top of this lesson and wait until it says it is running. There is one container, jupyter, and the terminal reaches its Python with docker exec jupyter, which runs one command inside it. It has two links. JupyterLab, the first, is the editor, port 8888. Preview, the second, is the game itself, port 8000: open it in your own browser tab and play a round now. Each Run button below types its command into your lab's terminal, one after another in the same session. To watch them, or to type your own, press Open terminal on the bar.

A game is a few plain files

ls game lists the three files of the game: index.html for the page, style.css for its looks and game.js for the rules. The second command prints their sizes: 667, 442 and 4399 bytes, 5508 in all. Nearly all of the game is in game.js. There is no engine and no library, only what the browser already has.

Command
docker exec jupyter ls game

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Command
docker exec jupyter python3 steps/sizes.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The game loop

The script reads game.js and prints the named constants at the top: GRAVITY is 0.15, PLAYER_SPEED is 6 and SPAWN_EVERY is 50, one new star every 50 frames. It then lists the functions. Two matter most. update moves everything and checks what happened, and draw paints the picture. The function loop calls both and then asks the browser to call it again for the next frame, with requestAnimationFrame. That never-ending call is the game loop.

Command
docker exec jupyter python3 steps/loop.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Check

Tip

What does the loop do on every frame, and which constant sets how often a new star appears? Answer: it updates the game and then draws it; SPAWN_EVERY.

Constants and a table of levels

A good game keeps its numbers where you can find them. LEVELS is a table of data: four rows, Drizzle, Shower, Storm and Meteors, which start at scores 0, 5, 12 and 20. Each row scales the base numbers, and the script works out the result: gravity grows from 0.150 to 0.360 and the gap between stars shrinks from 50 frames to 25. So the game gets harder by changing data and not code. Try it: change GRAVITY in game.js, save, run the script again, and play the Preview.

Command
docker exec jupyter python3 steps/levels.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Gravity is a number added every frame

Gravity does not move a star by itself. On every frame it adds a little to the star's speed, and then the speed moves the star. The script follows one star for ten frames from the constant in game.js: the speed grows by 0.15 each frame, up to 1.50, and the star has fallen 8.25 pixels in all. Every frame is a bigger step than the one before, which is why a star seems to speed up as it falls.

Command
docker exec jupyter python3 steps/fall.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Collision is a question about two boxes

To catch a star the game asks whether two boxes overlap. They do when each one starts before the other one ends, both across and down. The script runs the same test in Python on six fixed pairs: overlapping pairs and a box inside another give True, boxes far apart give False, and so do boxes that only share an edge. The game does the test for every star on every frame.

Command
docker exec jupyter python3 steps/collide.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Serving the game, and playing it

The Preview is a plain file server. The script asks it for the page, the script and the stylesheet, as a browser does, and each answers 200. Nothing in the lab can play the game for you, because there is no browser in it. Open the Preview in your own tab: use the left and right arrow keys, or the buttons, to slide the box. After three missed stars the game says Game over, and Space or Restart begins again.

Command
docker exec jupyter python3 steps/serve.py

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a bigger number always makes a game better. It does not. If GRAVITY is too big the stars fall faster than anyone can react, and if PLAYER_SPEED is too small the box cannot get under them. Change one number at a time, play it, and write down what you saw before you change another.

The same checks in a notebook

Open JupyterLab from the bar and double-click start.ipynb. Its cells read the constants, run the overlap test on two boxes and ask the Preview for the page. Click a cell and press Shift and Enter to run it. The last cell is where your own change goes: change GRAVITY, save, and work out where a star is after ten frames.

Exit check

Tip

Answer without looking back. 1. What two jobs does the game loop do on every frame? 2. What does gravity change on every frame, the position or the speed? 3. When do two boxes overlap? 4. Why is a table of levels better than writing each level into the code? Answers: update and draw; the speed, and the speed then moves the star; when each starts before the other ends, across and down; you change the data and not the code.

For teachers

Tip

This lesson is a small example of a lesson worked in a lab: the steps and the Run buttons are the lesson, and the lab is each student's own copy. The lab is one service, JupyterLab with a live copy of a small game, and nothing here marks itself: the student hands in their own version of the three files in game, downloaded from JupyterLab, and a sentence on one number they changed and what it did. Key learning points: 1. A game is a loop of update and draw. 2. Gravity changes speed, and speed changes position. 3. Collision is a test on boxes, and numbers belong in named constants and tables. Common mistake: changing several numbers at once. Equipment: the lab and a browser, because the lab has none and the game is played in the student's own. Tip: ask students to predict what a change will do before they reload. The game and the scripts are written from fixed text, so every copy gives the same numbers, but where a star starts is random. Copy it into your own module and change it, or build one from scratch with the Lab menu in the lesson builder.

About this lab and its source: Game development lab: a game loop, gravity and collisions in the browser

Teaching a class? Set these lessons for your students with marking and a lab for every student.