Building an A Level Platform Game Project — Part 4: Adding Platforms and Collision Detection
In Part 1, we planned the platform game and set realistic success criteria.
In Part 2, we created the game window and added basic left and right movement.
In Part 3, we added gravity and jumping, so the player could rise, fall and land on the ground.
Now we reach one of the most important stages in the whole project: platforms and collision detection.
This is where the game stops being a character jumping on a single ground line and starts to become a proper platform game world.
It is also where many students discover that game programming is not quite as simple as it first appears.
A platform looks simple. It is just a rectangle on the screen.
But the program has to answer some awkward questions:
Has the player landed on top of the platform?
Has the player hit the side of the platform?
Has the player jumped into the underside of the platform?
Should the player stand on the platform or fall through it?
What happens if the player is moving quickly?
How does the program know which platform the player is touching?
This is why collision detection is such a good A Level Computer Science topic. It takes a simple visual idea and turns it into a proper programming problem.
Why Platforms Matter
A platform game needs a world for the player to interact with.
So far, our player can move, jump and land, but only on the bottom of the screen. That is useful for testing, but it is not enough for a game.
Platforms allow us to create:
different routes through the level
jumps of different difficulty
collectables placed in interesting positions
hazards that must be avoided
areas that require planning and timing
a proper start and finish point
Once platforms work, we can begin to design levels.
That is why this article is so important. Collision detection is the bridge between movement and level design.
The Aim for Part 4
The aim of this stage is:
Add rectangular platforms to the game and allow the player to land on them without falling through.
By the end of this stage, the game should include:
several visible platforms
a player affected by gravity
collision detection between the player and platforms
the ability to land on top of platforms
prevention of repeated jumping while in the air
testing evidence showing that platforms work correctly
This is still a prototype, but it is now much closer to a real game.
Representing Platforms
The simplest platform can be represented as a rectangle.
In Pygame-style code, a platform might be written as:
platform = pygame.Rect(200, 450, 200, 20)
This creates a rectangle with:
x-position: 200
y-position: 450
width: 200
height: 20
Instead of one platform, we can store several platforms in a list:
platforms = [
pygame.Rect(0, 580, 800, 20),
pygame.Rect(150, 480, 200, 20),
pygame.Rect(450, 380, 200, 20),
pygame.Rect(250, 280, 180, 20)
]
This gives us a basic level layout:
a ground platform at the bottom
one platform slightly higher
another platform further across
a higher platform above
This simple list is already important.
It means the level is not just drawn manually. It is stored as data.
That is a key idea for future articles, because later we can develop this into proper level design.
Drawing the Platforms
Once the platforms are stored in a list, they can be drawn using a loop:
for platform in platforms:
pygame.draw.rect(screen, (0, 0, 0), platform)
This is better than writing a separate drawing command for every platform.
It also makes the project easier to extend.
If we want to add another platform, we add another rectangle to the list. The drawing loop does not need to change.
This is a good point for students to mention in their project documentation:
I stored the platforms in a list so that the program could process them using a loop. This made it easier to add, remove or change platforms without rewriting the drawing code.
That shows good programming thinking.
Representing the Player as a Rectangle
In earlier versions, the player used separate variables such as:
player_x
player_y
player_width
player_height
For collision detection, it is useful to create a rectangle for the player as well:
player_rect = pygame.Rect(player_x, player_y, player_width, player_height)
A rectangle makes it easier to check whether the player overlaps a platform.
For example:
if player_rect.colliderect(platform):
print("Collision detected")
This is the basic idea behind rectangle collision detection.
It is not perfect, but it is ideal for a first platform game.
What Is Collision Detection?
Collision detection means checking whether two objects are touching or overlapping.
In this project, we need to know when the player touches:
the ground
a platform
a wall
a hazard
a collectable
a finish point
For now, we will focus only on platforms.
The simplest approach is rectangle collision detection.
If the player rectangle overlaps a platform rectangle, a collision has happened.
That sounds easy.
The difficult part is deciding what to do after the collision.
Why Collision Response Is Harder Than Collision Detection
Detecting a collision simply tells us that two rectangles overlap.
It does not automatically tell us where the collision happened.
The player might have:
landed on top of the platform
hit the platform from below
run into the side
touched a corner
The response should be different in each case.
If the player lands on top, they should stand on the platform.
If the player hits the underside, they should stop moving upwards.
If the player hits the side, they should not pass through the platform.
For this stage, we will keep things simple and focus on landing on top of platforms.
Side collisions can be developed later.
This is a sensible project decision because it controls the scope.
A Simple Landing Algorithm
To land on a platform, the program needs to check whether the player is falling and whether the bottom of the player has reached the top of the platform.
The player is falling when:
player_y_velocity > 0
The bottom of the player is:
player_rect.bottom
The top of the platform is:
platform.top
If the player is falling and collides with a platform, we can place the player on top of the platform:
player_rect.bottom = platform.top
player_y_velocity = 0
on_ground = True
This means:
the player is no longer falling
the player is positioned exactly on top of the platform
the player is allowed to jump again
That is the basic idea.
Updating the Player Position
One important issue is that the player’s rectangle must be updated as the player moves.
A sensible structure is:
Check input.
Move horizontally.
Apply gravity.
Move vertically.
Check collisions with platforms.
Draw everything.
The order matters.
If the order is wrong, collisions may behave strangely.
For example, if the program checks collisions before the player moves, it may be using old position data.
Example Code for Platforms and Landing
Here is a simplified version of the Part 4 prototype:
import pygame
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Escape the Platforms")
clock = pygame.time.Clock()
player_rect = pygame.Rect(100, 500, 40, 60)
player_speed = 5
player_y_velocity = 0
gravity = 0.5
jump_strength = -12
on_ground = False
platforms = [
pygame.Rect(0, 580, 800, 20),
pygame.Rect(150, 480, 200, 20),
pygame.Rect(450, 380, 200, 20),
pygame.Rect(250, 280, 180, 20)
]
running = True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
# Horizontal movement
if keys[pygame.K_LEFT]:
player_rect.x -= player_speed
if keys[pygame.K_RIGHT]:
player_rect.x += player_speed
# Screen boundary checks
if player_rect.left < 0:
player_rect.left = 0
if player_rect.right > SCREEN_WIDTH:
player_rect.right = SCREEN_WIDTH
# Jumping
if keys[pygame.K_SPACE] and on_ground:
player_y_velocity = jump_strength
on_ground = False
# Apply gravity
player_y_velocity += gravity
player_rect.y += player_y_velocity
# Assume the player is not on the ground until a platform proves otherwise
on_ground = False
# Platform collision detection
for platform in platforms:
if player_rect.colliderect(platform) and player_y_velocity > 0:
player_rect.bottom = platform.top
player_y_velocity = 0
on_ground = True
# Draw everything
screen.fill((255, 255, 255))
for platform in platforms:
pygame.draw.rect(screen, (0, 0, 0), platform)
pygame.draw.rect(screen, (0, 0, 255), player_rect)
pygame.display.update()
pygame.quit()
This is a major step forward.
The player now interacts with platforms.
The player can jump, fall and land on different surfaces.
The level is still basic, but it is becoming a real platform game.
Why on_ground = False Is Reset Each Frame
This line is important:
on_ground = False
It appears before checking platform collisions.
At first, this may look strange.
Why set on_ground to False when the player might be on a platform?
The reason is that each frame, the program should check the current situation again.
The player is assumed to be in the air unless a collision with a platform proves they are standing on something.
If the player is touching a platform from above, the collision code sets:
on_ground = True
This keeps the jumping logic accurate.
Without this, the game might incorrectly think the player is still on the ground after walking off the edge of a platform.
That is an excellent bug to discuss in the project write-up.
The Walk-Off-the-Platform Problem
One of the most important tests is what happens when the player walks off a platform.
The expected result is simple:
The player should fall.
However, if the on_ground variable is not updated correctly, the player may be able to jump in mid-air after walking off the edge.
That would be a bug.
The solution is to reset on_ground each frame and only set it to True when a platform collision confirms that the player is standing on something.
This is a good example of state management.
The program must keep track of whether the player is grounded, but that state must be checked and updated continuously.
Common Collision Detection Bugs
This stage is likely to produce bugs. That is not a failure. It is exactly why this makes a good A Level project.
Bug 1: The Player Falls Through Platforms
This can happen if the player is moving too fast or if the collision check is in the wrong place.
Possible fixes include:
checking collisions after vertical movement
reducing gravity
limiting the maximum falling speed
checking whether the player was above the platform in the previous frame
Bug 2: The Player Gets Stuck Inside a Platform
This often happens when the player overlaps a platform but is not moved back to a safe position.
A simple fix is:
player_rect.bottom = platform.top
This places the player exactly on top of the platform.
Bug 3: The Player Can Jump After Walking Off a Platform
This usually happens because on_ground remains True after the player leaves the platform.
Resetting on_ground each frame helps solve this.
Bug 4: The Player Lands on the Side of a Platform
If the collision detection is too simple, the game may treat a side collision as a landing.
This is one reason why more advanced collision detection often separates horizontal and vertical movement.
For now, we are focusing mainly on landing from above. Later, students may improve the algorithm to handle side collisions more accurately.
Separating Horizontal and Vertical Collision
A more advanced approach is to deal with horizontal and vertical movement separately.
The program can:
Move the player horizontally.
Check for side collisions.
Move the player vertically.
Check for floor or ceiling collisions.
This is more complex, but it gives better control.
For example, if the player moves horizontally into a wall, the program can stop sideways movement without affecting vertical movement.
If the player falls onto a platform, the program can stop vertical movement without affecting horizontal movement.
This is something students could add as an extension once the basic version works.
It would also make a strong discussion point in the evaluation.
Using Platform Data for Future Levels
At the moment, our platforms are stored like this:
platforms = [
pygame.Rect(0, 580, 800, 20),
pygame.Rect(150, 480, 200, 20),
pygame.Rect(450, 380, 200, 20),
pygame.Rect(250, 280, 180, 20)
]
This is already a simple form of level design.
If we change the numbers, we change the level.
For example, moving a platform higher makes the jump harder.
Making a platform narrower makes landing more difficult.
Placing platforms further apart changes the route.
Adding a platform creates a new possible path.
This is where students can begin to see the connection between code and game design.
The level is not just decoration. It is data.
In the next part of the series, we can develop this further by creating proper levels, perhaps storing them as lists, dictionaries or external files.
Designing a First Test Level
A good first test level should not be too difficult.
The aim is to test the mechanics, not frustrate the player.
A sensible first level might include:
a wide ground platform
one low platform that is easy to jump onto
a second platform slightly higher
a third platform further away
a finish point that will be added later
For now, the goal is simply to check that the player can land on each platform.
Students should avoid making the platforms too small too early.
Difficult levels should come after reliable mechanics.
Testing Platforms and Collision Detection
Testing is essential at this stage.
Students should create a test table that checks normal movement and awkward cases.
| Test Number | Test | Expected Result | Actual Result | Pass/Fail |
|---|---|---|---|---|
| 1 | Run the program | Player appears and platforms are visible | Player and platforms appear | Pass |
| 2 | Player falls onto ground platform | Player lands and stops falling | Player lands correctly | Pass |
| 3 | Jump onto first raised platform | Player lands on top of platform | Player lands correctly | Pass |
| 4 | Walk off a raised platform | Player falls downwards | Player falls correctly | Pass |
| 5 | Press jump while standing on platform | Player jumps upwards | Player jumps correctly | Pass |
| 6 | Press jump after walking off platform | Player should not jump again in mid-air | Player cannot jump in mid-air | Pass |
| 7 | Land on second platform | Player lands and can jump again | Player lands correctly | Pass |
| 8 | Hit side of platform | Player should not behave unpredictably | Needs improvement | Fail/Partial |
| 9 | Fall from top platform to ground | Player lands on lower surface | Player lands correctly | Pass |
| 10 | Move to screen edge | Player remains inside screen | Player remains inside screen | Pass |
Notice that one test may not fully pass.
That is acceptable if it is recorded honestly.
A project that identifies limitations and suggests improvements is often stronger than one that pretends everything is perfect.
Linking Back to Success Criteria
This stage supports several success criteria from the planning article:
The game contains several platforms.
The player can stand on the top of each platform.
The player falls when not standing on a platform.
The player can jump from a platform.
The player cannot repeatedly jump while in the air.
The player can move left and right while jumping.
The player remains within the screen boundaries.
Students should keep referring back to the original criteria.
This makes the project feel coherent rather than random.
A good development log entry might say:
This stage met the success criteria relating to platforms, jumping and landing. The player can now land on several rectangular platforms. Testing showed that walking off a platform causes the player to fall, which fixed an earlier problem where the player could still jump after leaving the platform.
That is strong project evidence.
Evidence Students Should Collect
For this stage, useful evidence might include:
screenshot of the platform layout
screenshot of the player standing on a platform
screenshot of the player falling between platforms
code showing the platform list
code showing collision detection
test table for landing and falling
notes about bugs and fixes
short video showing the player jumping between platforms
The most important thing is to collect evidence while the work is happening.
Trying to recreate evidence at the end of the project is much harder.
Personal Reflection: This Is Where Students Start to Understand Games Differently
This is one of my favourite stages when teaching programming projects.
At the beginning, students often think of games mainly in terms of graphics.
They talk about characters, backgrounds and visual style.
But when they add platforms and collision detection, they begin to see that a game is really a system of rules.
A platform is not just a rectangle.
It is something the player can stand on, fall from, jump from and interact with.
The program has to decide what touching means.
That is a powerful lesson.
Students begin to understand that programming is not simply making something appear on screen. It is defining behaviour.
That is why a simple retro platform game can be such a good project.
It looks small, but it contains real computational thinking.
Practical Task for Students
Before moving on to level design, students should complete this task.
Part 4 Student Task
Add platforms and collision detection to your platform game.
Your program should include:
At least four platforms, including the ground.
Platforms stored in a list.
A loop to draw all platforms.
A player rectangle used for collision detection.
Gravity applied each frame.
Collision detection between the player and platforms.
A landing response that places the player on top of the platform.
An
on_groundvariable that updates correctly.A test table for platform collisions.
Screenshots or video evidence of the player landing on platforms.
Extension Task
Improve the platform system by adding one of the following:
side collision detection
ceiling collision detection
moving platforms
one-way platforms
different platform types
platforms stored in a separate level data structure
a simple finish point
a debug mode showing collision rectangles
Students should only attempt extensions once the basic collision detection is reliable.
Development Log Example
A good development log entry might look like this:
Development Stage
Adding platforms and collision detection.
Aim
To allow the player to land on raised platforms instead of only landing on the bottom of the screen.
What Was Added
platform list
platform drawing loop
player rectangle for collision detection
collision detection using rectangle overlap
landing response when falling onto a platform
updated
on_groundlogic
Problems Found
The player could initially jump after walking off a platform.
The player sometimes overlapped slightly with a platform before being corrected.
Side collisions were not handled accurately in the first version.
Changes Made
Reset
on_groundto False each frame.Set
on_groundto True only when landing on a platform.Set the bottom of the player rectangle to the top of the platform after collision.
Recorded side collision as an area for later improvement.
Evidence Collected
screenshots of the player on platforms
code showing the platform list
code showing collision detection
test table
notes explaining the walk-off-platform bug
This sort of development record is exactly what students need for a strong A Level project.
Preparing for Levels
Once platforms work, we are ready for the next major step: level design.
A level is more than a random collection of platforms.
A good level has:
a start point
a route
increasing challenge
safe areas
risk areas
a finish point
opportunities for scoring
suitable difficulty for the target user
At the moment, our platforms are hard-coded into one list.
That is fine for the prototype.
But as the game grows, we can improve this by storing levels as separate data structures.
For example, we might eventually have:
level_1_platforms = [...]
level_2_platforms = [...]
level_3_platforms = [...]
Or we might store level data in dictionaries:
level_1 = {
"platforms": [...],
"player_start": (100, 500),
"finish": (700, 520)
}
This opens the door to multiple levels.
It also creates excellent A Level project material because the student can explain how the game data is organised.
Final Thoughts: Collision Detection Turns Movement Into a Game
Adding platforms and collision detection is a major step in the project.
The player is no longer just moving around a blank screen.
The player is now interacting with a world.
They can jump onto platforms, fall from them, land on them and begin to move through a level.
This stage also creates some of the best learning moments in the whole project. The bugs are real. The problems are interesting. The solutions require thought.
The player may fall through platforms.
They may get stuck.
They may jump when they should not.
They may collide from the side in unexpected ways.
All of that is valuable.
A good A Level project is not one where everything works perfectly first time. It is one where the student can show how they found problems, tested them, improved the program and explained the decisions they made.
With platforms now working, the project is ready to move from mechanics to design.
In the next article, we will look at how to turn these platforms into proper levels, with routes, difficulty, start points, finish points, collectables and hazards.

