Building an A Level Platform Game Project — Part 2: Creating the Game Window and Player Movement
In Part 1, we planned the platform game.
We decided that the aim was not to create the next PlayStation or Xbox masterpiece. The aim was to build a controlled, achievable, expandable 2D platform game that could be used as a strong model for an A Level Computer Science project.
We looked at success criteria, user requirements, essential features, desirable features and extension ideas.
Now we need to move from planning to programming.
This is the exciting point where the project stops being just an idea and becomes something visible on the screen.
But we still need to keep the same rule:
Start simple. Make it work. Then improve it.
In this article, we will create the first working prototype of the game. The target is deliberately small:
Create a game window, place a player on the screen, and allow the player to move left and right using the keyboard.
That may not sound like much, but it is the first proper step towards a working platform game.
Why Start With a Simple Prototype?
Students often want to start with the interesting parts first.
They want graphics, enemies, levels, sound effects and menus. That is understandable. Those are the parts that feel like a finished game.
But those are not the foundation.
The foundation of a platform game is movement.
If the player cannot move reliably, nothing else matters. The platforms, enemies, collectables and levels all depend on the player being controlled properly.
This first prototype gives us something important:
a game window
a controlled game loop
keyboard input
a visible player object
horizontal movement
screen boundary checks
a first opportunity for testing
evidence for the project write-up
A simple rectangle moving left and right is not impressive as a final game. But as a first prototype, it is exactly what we need.
Choosing the Development Tool
There are several ways to create a 2D platform game.
Students might use:
Python with Pygame
JavaScript with HTML5 Canvas
Godot
Unity in 2D mode
Java
C# with a suitable framework
For this series, I will use Python-style examples because they are easy to read and many students are familiar with them. The important ideas, however, apply to other languages as well.
The key ideas are:
create a window
repeatedly update the game
check for key presses
change the player’s position
draw the updated screen
repeat many times per second
That repeated cycle is the basis of most games.
The Game Loop
A game does not simply run once from top to bottom like a basic calculator program.
A game runs continuously.
It checks input, updates positions, draws the screen and then does the same again. This happens many times every second.
A simple game loop follows this pattern:
Check for events, such as closing the window.
Check which keys are being pressed.
Update the player’s position.
Clear the screen.
Draw the player.
Display the updated screen.
Repeat.
This is a very important idea for students to understand.
The player does not move because the program waits for one key press and then stops. The player moves because the program is constantly checking the keyboard and updating the screen.
Creating the Game Window
The first practical target is to create a game window.
A sensible starting size is 800 pixels wide and 600 pixels high.
This gives enough space for platforms, hazards and movement later, but it is still simple enough to manage.
Example design decision:
The game window will be 800 by 600 pixels because this gives enough room for a simple platform level while keeping the coordinate system manageable for testing.
This kind of explanation is useful in the project write-up. Students should not just say what they did. They should explain why they did it.
A very simple Python/Pygame-style structure might look like this:
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")
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((255, 255, 255))
pygame.display.update()
pygame.quit()
At this stage, the program does not do much.
It opens a window.
It keeps the window open.
It allows the user to close it.
That is enough for the first small test.
Why Constants Are Useful
In the example above, the screen width and height are stored as constants:
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
This is better than writing 800 and 600 throughout the program.
If the screen size needs to change later, it can be changed in one place.
This is a small programming habit, but it matters.
Good projects are easier to maintain and improve.
A student could write in their development log:
I used named constants for the screen width and height so that the window size could be changed easily later without searching through the whole program.
That is good evidence of thoughtful programming.
Drawing the Player
The next step is to put a player on the screen.
At this point, the player does not need to be a detailed sprite or animated character. A rectangle is perfectly suitable.
In fact, using a rectangle at the beginning is often better because it makes collision detection easier later.
Example player values:
player_x = 100
player_y = 500
player_width = 40
player_height = 60
This places the player near the bottom left of the screen.
To draw the player:
pygame.draw.rect(screen, (0, 0, 255), (player_x, player_y, player_width, player_height))
The full prototype now begins to look like this:
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")
player_x = 100
player_y = 500
player_width = 40
player_height = 60
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((255, 255, 255))
pygame.draw.rect(screen, (0, 0, 255), (player_x, player_y, player_width, player_height))
pygame.display.update()
pygame.quit()
Now we have a player.
It cannot move yet, but it exists on the screen.
That is progress.
Understanding Screen Coordinates
One area that can confuse students is the coordinate system.
In many maths lessons, students are used to graphs where the y-value increases as you move upwards.
Computer screens usually work differently.
On a screen:
x = 0 is the left edge
x increases as you move right
y = 0 is the top edge
y increases as you move down
So if the player’s x-coordinate increases, the player moves right.
If the player’s x-coordinate decreases, the player moves left.
If the player’s y-coordinate increases, the player moves down.
If the player’s y-coordinate decreases, the player moves up.
This will matter much more when we add gravity and jumping in the next article.
For now, it helps students understand why changing player_x moves the character horizontally.
Adding Left and Right Movement
Now we need keyboard control.
The simplest version checks whether the left or right arrow key is being pressed.
If the right arrow is pressed, increase player_x.
If the left arrow is pressed, decrease player_x.
For example:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= 5
if keys[pygame.K_RIGHT]:
player_x += 5
The value 5 is the movement speed. Each frame, the player moves 5 pixels.
This is easy to understand and easy to test.
The updated loop might look like this:
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= 5
if keys[pygame.K_RIGHT]:
player_x += 5
screen.fill((255, 255, 255))
pygame.draw.rect(screen, (0, 0, 255), (player_x, player_y, player_width, player_height))
pygame.display.update()
Now the player should move left and right.
This is the first real playable interaction.
The Problem of Speed
If students run the game at this point, they may notice a problem.
The player’s speed depends on how quickly the loop runs.
On a fast computer, the game may run very quickly. On a slower computer, it may run more slowly.
This is why games normally use a clock or frame rate control.
In Pygame, this can be done with:
clock = pygame.time.Clock()
Then inside the loop:
clock.tick(60)
This limits the game to about 60 frames per second.
The movement becomes more consistent.
The improved structure becomes:
clock = pygame.time.Clock()
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= 5
if keys[pygame.K_RIGHT]:
player_x += 5
screen.fill((255, 255, 255))
pygame.draw.rect(screen, (0, 0, 255), (player_x, player_y, player_width, player_height))
pygame.display.update()
This gives another useful project note:
I added a frame rate limit so that the player movement would be more consistent across different computers.
That is a small but important design improvement.
Preventing the Player Leaving the Screen
At this point, the player can move left and right, but there is probably another problem.
The player can leave the screen.
If the player keeps moving left, the x-coordinate becomes negative. If the player keeps moving right, the player disappears beyond the right edge of the window.
That is not desirable.
We need boundary checks.
The left boundary is simple:
if player_x < 0:
player_x = 0
The right boundary needs to include the player’s width:
if player_x + player_width > SCREEN_WIDTH:
player_x = SCREEN_WIDTH - player_width
This means the player’s right edge cannot move beyond the right edge of the screen.
The updated movement section becomes:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= 5
if keys[pygame.K_RIGHT]:
player_x += 5
if player_x < 0:
player_x = 0
if player_x + player_width > SCREEN_WIDTH:
player_x = SCREEN_WIDTH - player_width
This gives us another success criterion:
The player cannot move beyond the left or right edge of the screen.
Again, it is specific and testable.
Full Prototype Code for Part 2
At the end of this stage, the prototype might look like this:
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_x = 100
player_y = 500
player_width = 40
player_height = 60
player_speed = 5
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()
if keys[pygame.K_LEFT]:
player_x -= player_speed
if keys[pygame.K_RIGHT]:
player_x += player_speed
if player_x < 0:
player_x = 0
if player_x + player_width > SCREEN_WIDTH:
player_x = SCREEN_WIDTH - player_width
screen.fill((255, 255, 255))
pygame.draw.rect(
screen,
(0, 0, 255),
(player_x, player_y, player_width, player_height)
)
pygame.display.update()
pygame.quit()
This is still very simple, but it is a proper first version.
The player is visible.
The player can move.
The player cannot leave the screen.
The game loop is working.
The program has a clear structure.
That is enough for Part 2.
What Should Students Record in Their Development Log?
For an A Level project, the student should record development evidence as they go.
After this stage, a good development log entry might include:
Development Stage
Creating the game window and basic player movement.
Aim
To create a visible player character and allow the user to move it left and right using keyboard input.
What Was Added
800 by 600 game window
player rectangle
keyboard input
left and right movement
speed variable
frame rate control
screen boundary checks
Problems Found
The player initially moved off the edge of the screen.
Movement could behave differently if the game loop ran too quickly.
The player was only represented as a rectangle, but this was acceptable for the prototype.
Changes Made
Added boundary checks to stop the player leaving the screen.
Added a clock to control the frame rate.
Used named variables for player size and speed to make the program easier to adjust.
Evidence
screenshot of the game window
screenshot of the player at the left edge
screenshot of the player at the right edge
code showing keyboard input
test table showing movement works
This is far better than simply writing “I made the player move”.
Example Test Table
Testing should begin early.
Even this simple stage can be tested properly.
| Test Number | Test | Expected Result | Actual Result | Pass/Fail |
|---|---|---|---|---|
| 1 | Run the program | Game window opens | Game window opens | Pass |
| 2 | Press right arrow | Player moves right | Player moves right | Pass |
| 3 | Press left arrow | Player moves left | Player moves left | Pass |
| 4 | Hold left arrow at edge of screen | Player stops at left edge | Player stops at left edge | Pass |
| 5 | Hold right arrow at edge of screen | Player stops at right edge | Player stops at right edge | Pass |
| 6 | Close the window | Program exits cleanly | Program exits cleanly | Pass |
This test table may look basic, but it shows the correct habit.
Testing should not be left until the end.
Linking Back to the Success Criteria
In Part 1, we created success criteria.
This stage supports several of them:
The player can move left using keyboard input.
The player can move right using keyboard input.
The player stops moving horizontally when no movement key is pressed.
The player cannot move beyond the edge of the game screen.
This is exactly why success criteria are useful.
They connect planning, coding, testing and evaluation.
A student can later write:
The first development stage met four of the original success criteria. Testing confirmed that the player could move left and right and could not leave the game screen.
That is clear project evidence.
Possible Improvements at This Stage
Once basic movement works, students may be tempted to rush into graphics or enemies.
It is better to improve the movement slightly first.
Possible improvements include:
changing the speed value
adding smoother acceleration
adding friction
using different controls
creating a player class
replacing the rectangle with a temporary sprite
displaying coordinates for debugging
However, not all of these should be added immediately.
For a first project, simple movement is enough.
The next essential step is vertical movement: gravity and jumping.
Should Students Use a Player Class?
At this early stage, the code uses separate variables:
player_x
player_y
player_width
player_height
player_speed
This is easy to understand.
However, as the game grows, the player will need more information:
horizontal speed
vertical speed
jumping state
lives
animation frame
direction
collision rectangle
At that point, it may be better to create a player class.
For example, a class could store all the player’s properties and methods in one place.
Students do not need to do this immediately, but it is a useful design discussion.
A good project might begin with simple variables and later refactor the code into a class. That improvement itself can become useful evidence.
The student can explain:
The first version used separate variables for the player. As the program became more complex, I created a Player class to make the code easier to organise and extend.
That is a strong development point.
Avoiding the Copy-and-Paste Trap
This series is intended to guide students, not to provide a finished project for copying.
That is important.
A Level students should be able to explain their own code, justify their decisions and show their own development process.
Students using this model should adapt the ideas.
They might change:
the screen size
the controls
the player size
the movement speed
the visual style
the target user
the success criteria
the level design
the scoring system
the programming language
The aim is to understand the structure, not simply reproduce the code.
A student who copies a project without understanding it will struggle when asked to explain, test or evaluate it.
A student who adapts the project and records their decisions will have a much stronger piece of work.
Practical Task for Students
Before moving to gravity and jumping, students should complete this task.
Part 2 Student Task
Create the first prototype of your platform game.
It must include:
A game window.
A visible player character.
Left movement.
Right movement.
A controlled frame rate.
A variable for player speed.
Boundary checks so the player cannot leave the screen.
A short test table.
At least two screenshots as evidence.
A development log entry explaining what you added and what problems you found.
Extension Task
Improve the movement by adding one of the following:
different movement keys
a faster sprint key
smoother acceleration
a simple player class
a temporary sprite instead of a rectangle
Students should only attempt the extension once the basic version works.
Final Thoughts: The First Working Version Matters
At this point, the game is not exciting yet.
There are no platforms.
There is no jumping.
There are no enemies.
There is no score.
There is no way to win.
But the first working version matters.
The game has a window.
It has a player.
It responds to keyboard input.
It updates many times per second.
It prevents the player moving beyond the screen.
That is the beginning of a real game.
More importantly, it is the beginning of a properly documented project.
Students should not underestimate this stage. Many weak projects fail because students rush past the foundations and try to add complex features before the basic mechanics are reliable.
A good platform game is built one step at a time.
In the next article, we will add the feature that makes the game start to feel like a platform game: gravity and jumping.

No comments:
Post a Comment