Intermediate — Day 3
Game Loop & Wall Collision
Day Schedule
Online
| Time | Activity |
|---|---|
| 10:00 | Game Loop Review Walk through the while True structure line by line |
| 10:10 | Wall Detection xcor(), ycor(), halfSize boundary check |
| 10:25 | reset_game() Function to restore head to center; reset heading too |
| 10:35 | Breakout Groups Guided coding: full game loop + wall collision |
| 11:00 | Break |
| 11:10 | Breakout Groups Guided coding continued |
| 12:20 | Reminders |
In-Person
| Time | Activity |
|---|---|
| 8:00 | Warm-Up Review Day 2: test arrow keys for everyone |
| 8:20 | Game Loop Review Walk through the while True structure line by line |
| 8:35 | Wall Detection xcor(), ycor(), halfSize boundary check |
| 8:55 | reset_game() Function to restore head to center; reset heading too |
| 9:20 | Breakout Groups Guided coding: full game loop + wall collision |
| 9:40 | Break |
| 9:50 | Breakout Groups Guided coding continued |
| 11:00 | Break |
| 11:10 | Extra Activity Add a countdown display before the game restarts after a collision |
| 11:50 | Open Coding Catch up or polish collision detection |
| 12:20 | Reminders |
Learning Objectives
- Detect wall collision using xcor() and ycor()
- Write a reset_game() function to restore game state
- Understand why the game loop never exits — it resets instead
- Use halfSize = 290 (not 300) as the playable boundary
Main Topic
# INSTRUCTOR — Day 3: While Loops & Boundaries (Intermediate)
# -----------------------------------------------
# TEACH: The game loop pattern: while True runs every frame.
# Each frame: update screen → move snake → check walls → sleep.
# Boundary detection: xcor() and ycor() return the head's current position.
# If outside bounds, call reset_game() — the game never exits, it just resets.
#
# TEACH: halfSize = 300 means the playable area goes from -300 to +300.
# We use 290 in practice (not 300) so the snake visually stays inside the border.
import turtle
import time
screen = turtle.Screen()
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0)
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
halfSize = 290 # TEACH: boundary is 10px inside the screen edge
def reset_game():
# TEACH: reset_game restores the snake to its starting state — no exit needed
head.goto(0, 0)
head.setheading(0)
# TEACH: walk through the while True loop line by line before students run it
while True:
screen.update() # step 1: redraw the screen
head.forward(20) # step 2: move snake one step
# step 3: check all four walls
if (head.xcor() > halfSize or head.xcor() < -halfSize or
head.ycor() > halfSize or head.ycor() < -halfSize):
print("Hit the wall!") # TEACH: print helps debug — remove later
reset_game()
time.sleep(0.1) # step 4: pause (controls speed)
# TEACH: ask — what does 'or' mean here?
# The snake hits a wall if it goes too far left OR right OR up OR down.
# Any one of these four is enough to trigger reset.
Project — Full Game Loop
# INSTRUCTOR — Day 3: Project: Snake: Game Loop & Wall Collision (Intermediate)
# -----------------------------------------------
# TEACH: Cumulative from Day 2. Students add the full game loop and reset_game().
# Check: snake moves, arrow keys work, wall collision resets to center.
# Common issue: snake moves but wall doesn't reset. Likely: wrong halfSize, or
# the condition uses > 300 but screen is only 600px (so ±300 is the edge, not 290).
import turtle
import time
screen = turtle.Screen()
screen.title("Snake Game")
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0)
head = turtle.Turtle()
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
def go_up():
if head.heading() != 270:
head.setheading(90)
def go_down():
if head.heading() != 90:
head.setheading(270)
def go_left():
if head.heading() != 0:
head.setheading(180)
def go_right():
if head.heading() != 180:
head.setheading(0)
screen.listen()
screen.onkeypress(go_up, "Up")
screen.onkeypress(go_down, "Down")
screen.onkeypress(go_left, "Left")
screen.onkeypress(go_right, "Right")
halfSize = 290
# TEACH: reset_game resets head position and direction. No score yet — that's Day 4/5.
def reset_game():
head.goto(0, 0)
head.setheading(0)
# TEACH: this is the full game loop — every future day adds into this while True block
while True:
screen.update()
head.forward(20)
if (head.xcor() > halfSize or head.xcor() < -halfSize or
head.ycor() > halfSize or head.ycor() < -halfSize):
reset_game()
time.sleep(0.1)
Extra — Countdown
# INSTRUCTOR — Day 3: Extra Activity: Countdown Timer (Intermediate)
# -----------------------------------------------
# TEACH: Standalone exercise using while loop with a counter.
# Reinforces while condition, loop body modification, and time.sleep().
# Three blanks: starting value, stop condition, decrement.
# Students who get the challenge should use an if check inside the loop.
import time
countdown = 10 # starting value
while countdown > 0: # stop when countdown reaches 0
if countdown == 1: # TEACH challenge: special case for final second
print("FINAL SECOND!")
else:
print("Time left: " + str(countdown))
time.sleep(1)
countdown = countdown - 1 # decrement
print("Time's up!")
# TEACH: ask — what happens if we write `while countdown >= 0`?
# The loop runs one extra time (prints "Time left: 0") before stopping.
# Details like this matter in games for correct behavior.