Python Arena
Step 2 of 3

Turning around at the walls

The robot of the previous step walks out of the window and is gone. Things in games usually turn around at the walls. For that, the program needs to know which way the robot is going, so it keeps the robot's velocity, how much its position changes per frame, in a variable of its own:

The image robot.png
robot.png, 40 × 40 pixels
import pygame

pygame.init()
window = pygame.display.set_mode((320, 240))
robot = pygame.image.load("robot.png")

x = 0
speed = 3
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    window.fill((0, 0, 0))
    window.blit(robot, (x, 100))
    pygame.display.flip()

    x += speed
    if x + robot.get_width() >= 320 or x <= 0:
        speed = -speed
    clock.tick(60)
pygame window320 × 240
The program's window after 150 frames
The window as text
fill (0, 0, 0)
blit robot.png at (117, 100)
The window after 150 frames.

speed is 3 while the robot goes right and -3 while it goes left: x += speed with a negative speed makes x smaller. The robot's right edge is at x + robot.get_width(). When it reaches the window's right edge, speed = -speed turns 3 into -3, and the robot heads back. When its left edge reaches 0, -3 turns back into 3.

>=, not ==

The test is x + robot.get_width() >= 320, not == 320. The robot moves 3 pixels at a time, so its right edge goes 316, 319, 322: it's never exactly 320. With == the test would never be true, and the robot would walk out of the window. In the same way, x <= 0 catches 0 and anything below it. This small program prints the positions near the right edge, with 40 for the robot's width:

x = 270
speed = 3
for frame in range(6):
    x += speed
    if x + 40 >= 320 or x <= 0:
        speed = -speed
    print(x, speed)
Output
273 3
276 3
279 3
282 -3
279 -3
276 -3

For one frame the robot sticks out 2 pixels past the edge, which nobody notices. Start the robot inside the window, though: one that starts past an edge turns around on every frame and stays stuck there.

Bouncing in two directions

A ball that moves at a slant has a velocity in each direction: speed_x across and speed_y up and down. Each one turns around at its own walls: speed_x at the left and right edges, speed_y at the top and the bottom.

The image ball.png
ball.png, 28 × 28 pixels
import pygame

pygame.init()
window = pygame.display.set_mode((320, 240))
ball = pygame.image.load("ball.png")

x = 0
y = 0
speed_x = 4
speed_y = 3
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    window.fill((0, 0, 0))
    window.blit(ball, (x, y))
    pygame.display.flip()

    x += speed_x
    y += speed_y
    if x + ball.get_width() >= 320 or x <= 0:
        speed_x = -speed_x
    if y + ball.get_height() >= 240 or y <= 0:
        speed_y = -speed_y
    clock.tick(60)
pygame window320 × 240
The program's window after 240 frames
The window as text
fill (0, 0, 0)
blit ball.png at (212, 135)
The window after 240 frames.

Your task

Challenge 1 of 3

The robot should go back and forth between the left and the right edges of the window, as in the first example, but the condition for turning around is missing two pieces. Fill in the blanks.

Challenge 2

What does this program print? Type each line it prints.

Challenge 3

The monster patrols between two boxes. The boxes stand at (0, 100) and (280, 100), and the monster walks between them along y = 100, 4 pixels per frame. On the first frame it's at (122, 100), heading right. When its right edge reaches the right box's left edge (x = 280) or goes past it, it turns around, and when its left edge reaches the left box's right edge (x = 40) or goes past it, it turns around again. Only its speed turns: as the robot in the lesson sticks out past the edge for a frame, the monster steps 2 pixels into a box for a frame and isn't moved back. Draw the left box, then the right box, then the monster. As in the lesson, move the monster after each frame is shown, then check for turning.