Python 'Breakout!' code
Week 5
Here's all the code for the platform game, as it should be at the start of Week 4. Your code may not look exactly the same: maybe you used different variable names, put things in a different order, or missed out the comment tags.
Things written in green are the first things to complete today, getting the score to go up, and the lives to go down.
The bits in red will let you display a game over/start screen, which dramatically improves the way the game feels.
# Screen related variables and constants
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 400
# Game related variables and constants
score = 0
lives = 3
game_state = 'ready'
# Variables for the start button
start_X = 150
start_y = 100
start_w = 100
start_h = 30
# Bat related variables and constants
bat_x = 120
bat_y = 0
bat_vel_x = 0
BAT_W = 60
BAT_H = 15
# Ball related variables and constants
ball_x = 180
ball_y = 50
ball_vel_x = 2
ball_vel_y = 2
BALL_D = 15
# Wall related variables and constants
BRICK_W = 40
BRICK_H = 15
NUM_BRICKS_IN_ROW = 9
NUM_BRICK_ROWS = 4
bricks = []
BRICK_COLOURS = ['red','green','yellow','blue']
BRICK_SCORES = [1, 2, 3, 4]
def setup():
global SCREEN_WIDTH, SCREEN_HEIGHT
global NUM_BRICKS_IN_ROW, NUM_BRICK_ROWS
global bricks
# Create the screen canvas at the specified width and height
createCanvas(SCREEN_WIDTH,SCREEN_HEIGHT)
# Set the frame refresh rate
frameRate(60)
create_wall()
def draw():
global SCREEN_WIDTH, SCREEN_HEIGHT, score, lives, game_state
global start_button_X, start_button_y, start_button_w, start_button_h
global ball_x, ball_y, ball_vel_x, ball_vel_y, BALL_D
global bat_x, bat_y, BAT_W, BAT_H, bat_vel_x
global BRICK_H,BRICK_H, BRICK_COLOURS, BRICK_SCORES
# Set the background colour
background("black")
# Show score and lives
textSize(20);
fill(255);
text('Score: '+str(score), 10, 374);
text('Lives: '+str(lives), 320, 374);
if game_state == 'ready':
show_start()
else:
if bricks == []:
create_wall()
#--------------- CHECK COLLISIONS ----------------#
# Check if the BALL has HIT a BRICK in the wall
for row_index, row in enumerate(bricks):
for brick_index, brick in enumerate(row):
x = 4+brick_index*(BRICK_W+4)
y = 300+row_index*(BRICK_H+2)
if ball_x > x - BALL_D/2 and ball_x < x + BRICK_W + BALL_D/2:
if ball_y > y - BALL_D/2 and ball_y < y + BRICK_H + BALL_D/2:
if brick == 'B':
bricks[row_index][brick_index] = 'X'
ball_vel_y = -ball_vel_y
score += BRICK_SCORES[row_index]
# Check if the BALL has HIT the BAT
# Check if the ball is within the width of the bat
if ball_x >= bat_x and ball_x <= (bat_x + BAT_W):
# Check if the ball has reached the bat
if ball_y <= BAT_H + BALL_D/2:
# Send the ball back up the screen
ball_vel_y = -ball_vel_y
# Otherwise, check if the ball is below the bat
elif ball_y < BAT_H:
# Reset the bat to the starting values
bat_x = 120
bat_y = 0
bat_vel_x = 0
# Reset the ball to the starting values
ball_x = 180
ball_y = 50
ball_vel_x = 2
ball_vel_y = 2
lives -=1
if lives == 0:
bricks = []
game_state = 'ready'
# Check if the BALL has gone off the LEFT or RIGHT of the SCREEN
if ball_x >= SCREEN_WIDTH - BALL_D/2:
ball_vel_x = -ball_vel_x
elif ball_x < BALL_D:
ball_vel_x = -ball_vel_x
# Check if the BALL has gone off the TOP of the SCREEN
if ball_y >= SCREEN_HEIGHT - BALL_D/2:
ball_vel_y = -ball_vel_y
# Check if the BAT is going off the SCREEN
if bat_x > SCREEN_WIDTH - BAT_W:
bat_x = SCREEN_WIDTH - BAT_W
elif bat_x < 0:
bat_x = 0
#--------------- MOVE OBJECTS ----------------#
# Move the bat
bat_x = bat_x + bat_vel_x
# Move the ball
ball_x = ball_x + ball_vel_x
ball_y = ball_y + ball_vel_y
#----------------- DRAW OBJECTS ---------------------#
# Draw the bat on the screen
fill('white')
rect(bat_x, bat_y, BAT_W, BAT_H)
# Draw the ball on the screen
fill('white')
circle(ball_x,ball_y,BALL_D)
# Draw the bricks on the screen if they are a 'B'
for row_index, row in enumerate(bricks):
fill(BRICK_COLOURS[row_index])
for brick_index, brick in enumerate(row):
if brick == 'B':
rect(4+brick_index*(BRICK_W+4),300+row_index*(BRICK_H+2),BRICK_W,BRICK_H)
def show_start():
# This function displays a start screen with a clickable button
global start_X, start_y, start_w, start_h, game_state, score, lives
fill('white')
textSize(64);
text('Game Over', 30, 240);
fill('purple')
rect(start_X, start_y, start_w, start_h)
fill('white')
textSize(20);
text('Start', start_X+25, start_y+9);
if mouseIsPressed:
print(mouseX, start_X)
if mouseX>start_X and mouseX < start_X + start_w:
if mouseY > start_y and mouseY < start_y + start_h:
game_state = 'play'
score = 0
lives = 3
def create_wall():
# Create the wall as a list of lists of bricks (ie. 2D array of bricks) named 'B'
global NUM_BRICKS_IN_ROW, NUM_BRICK_ROWS, bricks
for j in range(NUM_BRICK_ROWS):
row = []
for i in range(NUM_BRICKS_IN_ROW):
row.append('B')
bricks.append(row)
def keyPressed():
global bat_vel_x
# Check if the player is moving the bat to the left
if key == "ArrowLeft":
# set the velocity of the bat to the left
bat_vel_x = -2
# Otherwise check if the player is moving the bat to the right
elif key == "ArrowRight":
# set the velocity of the bat of the right
bat_vel_x = 2