Skip to main content

Stage 1: Build the Game Screen

Course progressStage 1 of 10
~40 min
One game, one Trinket

Keep building in the workspace on the right.

This stage is part of the same Python Arcade project you started in Setup. Type each new code block into the Trinket rail and keep building on the last stage.

Build

a game window, screen boundaries, and a player cannon

Learn

how coordinates name positions on the screen

Ship

a cannon sitting at the bottom of the playfield

The big idea

Before we draw anything, we need a map — a way to say "this thing is here." Python's Turtle library gives us one. The screen has a center point at (0, 0). X values move left and right. Y values move up and down.

Think of the screen like a sheet of graph paper with the middle marked. Every alien, every laser, and every cannon we build over the next nine stages will live somewhere on that paper.

A coordinate is just a pair of numbers — (x, y) — that says where something is. A Turtle is a thing the library draws for you; you tell it a coordinate, and it goes there.

(0, TOP)


(LEFT, 0)─────(0, 0)─────(RIGHT, 0)


(0, BOTTOM)

Today we will name the four edges (LEFT, RIGHT, TOP, BOTTOM) and a fifth one called FLOOR_LEVEL — the line the player cannon sits on. Once those names exist, every later stage gets to say "spawn at the TOP" instead of "spawn at y = 312." Names that mean something today become the vocabulary of the whole game.

Before you start

Use the Trinket workspace on the right. If the setup test is still there, replace it with the Stage 1 code below.

Build it

Step 1 — Open the screen and name its edges

Every game needs a playfield before anything can happen on it. We create the screen first, then save its edges with names we will reuse for the rest of the course.

Why name them at all, instead of just typing the numbers later? Because LEFT tells the next reader which wall-300 tells them nothing. Named numbers are the difference between code you can still read in nine stages and a pile of mystery values.

Start the current program with this:

Think first

Read the variable names

If `LEFT` is a negative number and `RIGHT` is a positive number, which one should the cannon use when it needs to stop at the left wall?

Check your thinking

It should compare against `LEFT`. The name tells you which side of the playfield it describes.

Your turn

Write the screen setup

Type the setup block yourself. Say each variable name out loud before you type the value so it connects to the screen edge it represents.

Need a hint?

Use one assignment per edge: `LEFT`, `RIGHT`, `TOP`, `BOTTOM`, then give `FLOOR_LEVEL` its own fixed number.

Python code task
Start your file

main.py

Where it goes: Replace the setup smoke test with this new Stage 1 starter file. Keep the first line as line 1.

This starts the actual game file. Leave the first line at the top.

#!/bin/python3
import turtle

screen = turtle.Screen()
screen.bgcolor("black")

LEFT = -300
RIGHT = 300
TOP = 200
BOTTOM = -200
FLOOR_LEVEL = -150

turtle.done()

Run it. You should see a black game window appear. It is empty — that is fine. The four edge values are fixed on purpose so every student gets the same playfield in Trinket.

Step 2 — Drop a cannon at the floor

The cannon is the player. It needs a position before it can shoot, move, or take damage. We will create one Turtle, give it a color and a basic shape, and place it at FLOOR_LEVEL.

Now write the cannon setup above turtle.done():

Trace it

Trace the cannon setup

  1. turtle.Turtle() creates the object that will draw the cannon.
  2. penup() means moving it will not drag a line.
  3. setposition(0, FLOOR_LEVEL) puts it centered on the floor line.
Python code task
Write this part

main.py

Where it goes: Put this below the edge constants and above `turtle.done()`.

This creates the cannon Turtle before the program stops at `turtle.done()`.

cannon = turtle.Turtle()
cannon.penup()
cannon.color("white")
cannon.shape("square")
cannon.setposition(0, FLOOR_LEVEL)

Run the game again. You should see a white square near the bottom, centered left-to-right. Notice that the square is exactly at FLOOR_LEVEL — the name we picked in Step 1 is already doing real work.

Step 3 — Give it a cannon shape

A single square is not very cannon-looking. Instead of importing an image, we will stamp several squares into a simple ship shape. A stamp is a snapshot of the Turtle's current shape — once stamped, the Turtle can move on and the stamp stays behind.

We use one Turtle and stamp it five times rather than making five Turtles. Each Turtle is a little more work for the computer to track, and by Stage 5 we'll have dozens of lasers and aliens that each need their own — so we keep decoration cheap here to leave room for them later.

Now write the drawing function above turtle.done():

Your turn

Predict the stamps

Before typing the function, point to the stamp() calls and predict which ones draw the base, body, and tip.

Need a hint?

Every `stamp()` leaves a copy of the current square. Every `setposition(...)` moves the same Turtle before the next stamp.

Python code task
Write this part

main.py

Where it goes: Put this function below the cannon setup and above the first `draw_cannon()` call.

Functions must be defined before you call them.

def draw_cannon():
cannon.clear()
cannon.shape("square")
x = cannon.xcor()
cannon.setposition(x - 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x + 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 20)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 40)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.hideturtle()

Then call it before turtle.done():

Python code task
Write this part

main.py

Where it goes: Put this one line below the `draw_cannon()` function and above `turtle.done()`.

This call runs the drawing function once.

draw_cannon()

Run it. Now your cannon has a base, a body, and a tip — a small stack of square stamps instead of one square.

Optional — Skin the square cannon with the ship sprite

Keep the square cannon code working first. Once it works, you can make the same player object look like the white pixel ship from the hero image.

If you uploaded player-ship.gif in Setup, add this block after screen.bgcolor("black") and before you create the cannon:

Python code task
Optional polish

main.py

Where it goes: Put this after `screen.bgcolor(...)` and before `cannon = turtle.Turtle()`.

Skip this if you are keeping the plain square cannon.

USE_PLAYER_SPRITE = True

try:
screen.addshape("player-ship.gif")
except:
USE_PLAYER_SPRITE = False

Then replace your draw_cannon() function with this version. It keeps the square fallback, but uses the uploaded ship sprite when Trinket can find it:

Python code task
Optional polish

main.py

Where it goes: Replace the entire old `draw_cannon()` function with this version.

Do not keep two `draw_cannon()` functions. The second one would replace the first.

def draw_cannon():
cannon.clear()
x = cannon.xcor()
cannon.setposition(x, FLOOR_LEVEL)

if USE_PLAYER_SPRITE:
cannon.setheading(90)
cannon.shape("player-ship.gif")
cannon.showturtle()
return

cannon.shape("square")
cannon.setposition(x - 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x + 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 20)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 40)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.hideturtle()

Run it. If the GIF is uploaded correctly, the player looks like a white pixel ship pointed upward. The setheading(90) line matters in Trinket because a Turtle starts out facing right, and uploaded image shapes can follow that heading. If you see only one white square, Trinket did not load player-ship.gif; check that the sprite setup block is above cannon = turtle.Turtle() and that the uploaded filename is exactly player-ship.gif.

File order checkpoint

By the end of Stage 1, your main.py should be ordered like this:

  1. #!/bin/python3 and import turtle
  2. Screen setup and edge constants
  3. Optional sprite setup, if you are using player-ship.gif
  4. Cannon setup
  5. draw_cannon()
  6. draw_cannon() call, then turtle.done()

Understand it

The cannon you just built is still one Turtle that moved through several positions, leaving a stamp behind at each one. That is a design choice worth pausing on.

We could have used several separate Turtles — one for each stamped square — but every Turtle adds a little work for the computer to track. By the end of the course we will have lots of lasers and aliens that each need their own Turtle, so we keep "decoration" cheap and reuse one Turtle wherever we can.

Wrapping the stamping into a draw_cannon function also means we can call it again later, after the player moves. Calling cannon.clear() first wipes the old stamps so we do not pile up forty cannons on top of each other.

Try this

Learning beat

Try this

Three short experiments. Predict before you run, then test your guess.

Predict first

Change FLOOR_LEVEL = -150 to FLOOR_LEVEL = -50. Where will the cannon end up? Decide before you run — then run it. Were you right?

Compare

Swap the cannon's shape("square") for shape("triangle") and run. Which one looks more like a cannon to you? Which one would a brand-new player understand faster?

Connect

Where else in this game will you need a position at the bottom of the screen? (Hint: when aliens reach the player, they have to know they got there.)

Test your stage

Stuck? Compare carefully
Answer check
Debug compare only

main.py

Where it goes: Compare this against your whole Stage 1 file from top to bottom. Do not paste it over later-stage work.

Use this only if your Stage 1 file will not run after you have checked the smaller tasks.

#!/bin/python3
import turtle

screen = turtle.Screen()
screen.bgcolor("black")

LEFT = -300
RIGHT = 300
TOP = 200
BOTTOM = -200
FLOOR_LEVEL = -150

cannon = turtle.Turtle()
cannon.penup()
cannon.color("white")
cannon.shape("square")
cannon.setposition(0, FLOOR_LEVEL)

def draw_cannon():
cannon.clear()
cannon.shape("square")
x = cannon.xcor()
cannon.setposition(x - 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x + 20, FLOOR_LEVEL)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 20)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL + 40)
cannon.stamp()
cannon.setposition(x, FLOOR_LEVEL)
cannon.hideturtle()

draw_cannon()

turtle.done()
  • The window opens with a black background.
  • The cannon appears near the bottom of the screen.
  • The cannon is centered left-to-right.
  • Running the program twice does not pile up extra cannons.
  • Optional sprite check: if player-ship.gif is uploaded, the same player object renders as the white pixel ship.
  • Design check. Read your code out loud. Do LEFT, RIGHT, and FLOOR_LEVEL sound like real things, or like mystery numbers?
  • From memory. Without looking, write the line that places the cannon on the floor. Compare — did you use cannon.setposition(0, FLOOR_LEVEL)?

If it breaks

  • The window is blank. draw_cannon() probably needs to be above turtle.done(). The turtle.done() line is the "we are done setting up" signal — nothing after it runs.
  • The cannon is missing entirely. Check the spelling on cannon.color("white"). Color names are case-sensitive in some setups, and a typo silently leaves the cannon invisible against the black background.
  • The cannon is way too high or way too low. Re-read FLOOR_LEVEL = -150 carefully. More negative numbers go lower. Less negative numbers go higher.
  • The cannon is one fat square, not a small stack of squares. The cannon.setposition(...) calls between stamps need to actually run between the stamps. Read your draw_cannon function top-to-bottom and check the order.
  • The sprite skin does not show. The file must be uploaded to Trinket as exactly player-ship.gif. If the filename is different, USE_PLAYER_SPRITE falls back to the square cannon.