Other Game Types¶
On this page we will learn
- how GameFrame can make platform, top-down and scrolling games
- how gravity and collisions make a player land on platforms
- how to build a level from a list of strings
- how to scroll the background to make the player feel like they're moving
Terminology
- platform game – a game where the player runs and jumps between platforms while gravity pulls them down.
- gravity – a force in a game that pulls objects down, making them fall faster and faster.
- top-down game – a game where we look down on the player from above as they move up, down, left and right.
- four-way movement – movement where the player can only go up, down, left or right, and not diagonally.
- scrolling game – a game where the background moves past the player to make it feel like they are travelling.
Space Rescue is a side-on shooter, but GameFrame can make lots of other kinds of games. This page has three small demo games to show how. Each one is a starting point for your own game, not a finished game.
Setting up a demo¶
Each demo is in the tutorial files, in the own_game folder. The demos use images from the Space Rescue resources, so the easiest way to try one is:
- Make a copy of your Space Rescue folder, or clone the Space Rescue Resources repo again into a new folder.
- In the copy, delete the files in Objects and Rooms, except __init__.py and notes.md.
- Copy the demo's Objects, Rooms and GameFrame folders into the copy, and replace the files.
- Run MainController.py.
Each demo's Globals.py sets the window to 1280 × 800 and lists just one Room in levels, and each __init__.py imports the demo's classes.
All three demos use a Block class for walls and floors. It uses the repair kit image as a crate:
| Objects/Block.py | |
|---|---|
Code explanation
- line 1 → imports the
RoomObjectclass. - line 3 → defines the
Blockclass as a subclass ofRoomObject. - lines 4–6 → a docstring that explains what the class is for.
- lines 7–8 → define
__init__and runRoomObject's__init__method. - lines 11–12 → give the block the crate image at 42 × 42 pixels. A Block has no other code: it just sits there for other objects to bump into.
Platform game¶
In a platform game, the player runs and jumps between platforms, and gravity pulls them down. Think Super Mario Bros.
The key ideas are:
- gravity: every RoomObject has a
gravityvariable. GameFrame adds it toy_speedevery frame, so the player falls faster and faster - landing: when the player hits the top of a block, we put them on top of it and stop them falling
- jumping: the player can only jump when they're standing on something
The player¶
Code explanation
- lines 1–2 → import
RoomObjectand Pygame. - line 4 → defines the
Jumperclass as a subclass ofRoomObject. - lines 5–7 → a docstring that explains what the class is for.
- lines 8–9 → define
__init__and runRoomObject's__init__method. - lines 12–13 → give the Jumper the astronaut image.
- line 16 → sets
gravityto1, soy_speedgrows by 1 every frame and the Jumper falls faster and faster. - line 17 → creates the
on_groundflag. The Jumper starts in the air. - line 20 → registers for key events.
- line 21 → registers collisions with
Blockobjects. - line 23 → defines the
key_pressedevent handler. - lines 24–26 → a docstring that explains what the method does.
- lines 27–28 → move left while A is held.
- lines 29–30 → move right while D is held.
- lines 31–32 → stop moving sideways when neither key is held.
- line 34 → checks if W is pressed and the Jumper is on the ground…
- line 35 → …and jumps by giving it a big upwards speed. Gravity slows it down, stops it, then pulls it back down.
- line 37 → defines the
stepmethod. - lines 38–40 → a docstring that explains what the method does.
- lines 41–42 → limit the falling speed to 20, so the Jumper can't fall so fast it skips straight through a 42-pixel block.
- line 43 → assumes the Jumper is in the air. If it's standing on a block, the collision below sets
on_groundback toTruebefore the next frame. - line 45 → defines
handle_collision. - lines 46–48 → a docstring that explains what the method does.
- line 49 → checks if the Jumper hit a Block.
- line 50 → checks if the bottom of the Jumper was above the top of the block in the last frame (
prev_y), which means it has just landed on it… - lines 52–54 → …so it puts the Jumper on top of the block, stops it falling and sets
on_groundtoTrue. - line 55 → otherwise, checks if the top of the Jumper was below the block last frame, which means it jumped into the block from underneath…
- lines 57–58 → …so it moves the Jumper below the block and stops it rising.
- line 59 → otherwise, it must have hit the side of the block…
- lines 61–62 → …so it moves the Jumper back to where it was and stops it moving sideways.
The Room¶
Code explanation
- lines 1–3 → import
Level,BlockandJumper. - line 5 → defines the
Platformerclass as a subclass ofLevel. - lines 6–8 → a docstring that explains what the class is for.
- lines 9–10 → define
__init__and runLevel's__init__method. - line 13 → sets the background image.
- lines 16–17 → use a
forloop to place a row of blocks every 42 pixels along the bottom of the screen, to make a floor. - lines 20–21 → make a floating platform of five blocks.
- lines 22–23 → make a higher platform.
- line 26 → adds the Jumper above the floor. Gravity drops it onto the floor.
PRIMM
- Predict what will happen if you change
gravityto2. - Run the demo and try it.
- Modify: add more platforms, and an object to collect at the top.
Top-down game¶
In a top-down game, we look down on the player, who moves up, down, left and right. Think of the original Legend of Zelda or Pac-Man.
The key ideas are:
- four-way movement: the player only moves while a key is held, like the "in motion while a key is pressed" option in Lesson 4
- walls: GameFrame's
blockedmethod moves an object back to where it was in the last frame, so it can't move into a wall - a level from a list: instead of placing every wall by hand, we draw the maze as a list of strings and turn each character into an object
The player¶
Code explanation
- lines 1–2 → import
RoomObjectand Pygame. - line 4 → defines the
Explorerclass as a subclass ofRoomObject. - lines 5–7 → a docstring that explains what the class is for.
- lines 8–9 → define
__init__and runRoomObject's__init__method. - lines 12–13 → give the Explorer the astronaut image at 36 × 36 pixels, so it fits through the 42-pixel corridors.
- line 16 → registers for key events.
- lines 17–18 → register collisions with walls (
Block) and theExit. - line 20 → defines the
key_pressedevent handler. - lines 21–23 → a docstring that explains what the method does.
- lines 24–25 → stop the Explorer at the start of every frame, so it only moves while a key is held.
- lines 26–33 → move left, right, up or down depending on which arrow key is held. Using
elifmeans only one direction at a time, so no diagonal moves. - line 35 → defines
handle_collision. - lines 36–38 → a docstring that explains what the method does.
- line 39 → if the Explorer hit a wall…
- line 40 → …
blockedmoves it back to where it was last frame and stops it. - line 41 → if the Explorer reached the exit…
- line 42 → …ends the Room.
The Exit class is just like Block, with the shield image.
The Room¶
Code explanation
- lines 1–4 → import
Level,Block,ExplorerandExit. - line 6 → defines the
Mazeclass as a subclass ofLevel. - lines 7–9 → a docstring that explains what the class is for.
- lines 10–11 → define
__init__and runLevel's__init__method. - line 14 → sets the background image.
- lines 17–37 → draw the maze as a list of 19 strings, each 30 characters long. Each character is a 42 × 42 square on the screen:
#is a wall,.is empty,Pis where the player starts andEis the exit. - line 40 → loops through each string, with
enumerategiving its row number… - line 41 → …and loops through each character in the string, with its column number.
- lines 42–43 → work out the square's position on the screen from its column and row.
- lines 44–45 → if the character is
#, add a wall. - lines 46–47 → if it's
E, add the exit. - lines 48–49 → if it's
P, add the Explorer, moved 3 pixels in so it sits in the middle of its square.
PRIMM
- Predict what will happen if you change one of the
.characters to#. - Run the demo and find your way out of the maze.
- Modify: design your own maze. Keep every string the same length.
Scrolling game¶
In a scrolling game, the background moves past the player to make it feel like they're travelling. Think of classic shooters like 1942 or Galaga.
The key ideas are:
- a scrolling background: GameFrame's
set_background_scrollmoves the background down the screen every frame, and wraps it around so it never runs out - objects coming towards the player: rocks fall from the top of the screen, while the player moves left and right to dodge them
- rotating an image: our ship image faces right, so we turn it to face up
The player¶
Code explanation
- lines 1–2 → import
RoomObject,Globalsand Pygame. - line 4 → defines the
Fighterclass as a subclass ofRoomObject. - lines 5–7 → a docstring that explains what the class is for.
- lines 8–9 → define
__init__and runRoomObject's__init__method. - lines 12–13 → give the Fighter the ship image at 80 × 80 pixels.
- line 14 → rotates the image 90° anticlockwise, so the ship points up the screen.
- line 17 → registers for key events.
- line 18 → registers collisions with
Rockobjects. - line 20 → defines the
key_pressedevent handler. - lines 21–23 → a docstring that explains what the method does.
- line 24 → if A is held and the ship isn't at the left edge…
- line 25 → …moves left.
- line 26 → if D is held and the ship isn't at the right edge…
- line 27 → …moves right.
- lines 28–29 → otherwise, stop. Checking the edges here means we don't need a
keep_in_roommethod. - line 31 → defines
handle_collision. - lines 32–34 → a docstring that explains what the method does.
- lines 35–36 → end the Room when a rock hits the ship. The demo only has one Room, so it starts again.
The falling rocks¶
Code explanation
- line 1 → imports
RoomObjectandGlobals. - line 3 → defines the
Rockclass as a subclass ofRoomObject. - lines 4–6 → a docstring that explains what the class is for.
- lines 7–8 → define
__init__and runRoomObject's__init__method. - lines 11–12 → give the rock the asteroid image.
- line 15 → starts the rock moving at
90°, which in GameFrame is straight down. - line 17 → defines the
stepmethod. - lines 18–20 → a docstring that explains what the method does.
- lines 21–22 → delete the rock once it has gone past the bottom of the screen.
The Room¶
Code explanation
- lines 1–4 → import
Level,Globals,Fighter,Rockandrandom. - line 6 → defines the
Scrollerclass as a subclass ofLevel. - lines 7–9 → a docstring that explains what the class is for.
- lines 10–11 → define
__init__and runLevel's__init__method. - line 14 → sets the background image.
- line 15 → scrolls the background down 4 pixels every frame.
- line 18 → adds the Fighter near the bottom of the screen.
- line 21 → starts a timer that drops the first rock after one second. Rooms have a
set_timermethod too. - line 23 → defines the
drop_rockmethod. - lines 24–26 → a docstring that explains what the method does.
- line 27 → chooses a random
xposition across the screen. - line 28 → adds a rock just above the top of the screen, so it slides into view.
- line 29 → starts the timer again with a random time, so rocks keep falling.
PRIMM
- Predict what will happen if you change the scroll speed on line 15 to
10. - Run the demo and try it.
- Modify: add a score that goes up the longer the player survives.
Mix and match
These ideas combine. A platform game could scroll, and a top-down game could have enemies that move by themselves like Zork. Start from the demo closest to your idea, then add the features you need one at a time.