Multiple Objects Exercises¶
In these exercises, you will go through making objects and using them for different things.
These examples assume that you are using the basic pygame template. If you don’t have it, find it here
Anatomy of the Pygame loop¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ##### INIT SECTION
# import pygame
# any functions you want to use should be defined right away
# create pygame variables
# create variables you want to use inside the game loop
##### WHILE LOOP SECTION
while not done:
# check for events
# fill the screen with white
##### ACTION CODE
# do any actions that we want to do
# this could be moving the box, etc
##### FINISHING CODE
# end of while loop code, mostly the clock.tick()
#### POST WHILE LOOP SECTION
# once the code hits here, we can assume that the while loop is over and game is done
# do any last finishing code things here
# the important one is to tell pygame shut down
|
Exercises¶
Exercise 0¶
Clean your environment (click here)!
Exercise 1¶
This week, we will start making the Hero of a game.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Hero:
def __init__(self, x, y, w, h):
''' this is a constructor function
when you create a new Hero, it requires these 4 variables
'''
# Remember that classes act like factories
# when we are inside this function, we are inside a single Hero instance
# and we need to be able to reference the current hero
# so, a self variable is a way of referencing the current Hero
self.x = x
self.y = y
self.w = w
self.h = h
hero1 = Hero() # this will break.
hero1 = Hero(10, 10, 50, 50)
print(hero1.x)
|
Add the following
- A variable into the constructor (
__init__
function) for the hero’s name - don’t forget to “save” it to the hero using
self.name = name
- don’t forget to “save” it to the hero using
- A variable into the constructor (
Exercise 2¶
This week, we will start making the Hero of a game.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Hero:
def __init__(self, x, y, w, h):
''' this is a constructor function
when you create a new Hero, it requires these 4 variables
'''
# Remember that classes act like factories
# when we are inside this function, we are inside a single Hero instance
# and we need to be able to reference the current hero
# so, a self variable is a way of referencing the current Hero
self.rect = Rect(x, y, w, h)
def say_hi(self):
print("Hello, my name is {}".format(self.name))
def move_right(self, step_size=0):
self.rect.x += step_size
hero1 = Hero(10, 10, 50, 50)
print(hero1.x) # this will break
print(hero1.rect)
hero1.say_hi()
|
We are going to save the coordinate information into Pygame’s Rect
class.
They offer some really neat functions if we do this.
Also, Rect
has the following variables:
x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height
w,h
Add the following:
Add the
name
code from the first exercise into this class.- The three other functions that move the hero:
def move_left(self, step_size=0)
def move_down(self, step_size=0)
def move_up(self, step_size=0)
Code that does the following:
1 2 3 4 | hero1.move_right(100)
hero1.move_down(100)
hero1.move_left(100)
hero1.move_up(100)
|
Exercise 3¶
Let’s make the hero move on their own!
Note: this code assumes you have done the Clean Environment exercise
because it assumes the SPEEDX
and SPEEDY
variables.
NOTE: here we will pass in SPEEDX
and SPEEDY
explicitly into the move functions.
However, you could (and should) change the defaults inside those functions to SPEEDX
and SPEEDY
.
Add the following code into the Hero.__init__
function:
1 2 | self.going_right = True
self.going_down = True
|
And now, a new function inside the Hero
class:
1 2 3 4 5 6 7 8 9 10 | def drift(self):
if self.going_right:
self.move_right(SPEEDX)
else:
self.move_left(SPEEDX)
if self.going_down:
self.move_down(SPEEDY)
else:
self.move_up(SPEEDY)
|
Add the following:
1. Inside def drift(self)
, after the code which moves the hero,
check to see if self.rect
is outside of the screen. I have done the first one for you.
# this will assume WINDOW_SIZE
WIDTH = WINDOW_SIZE[0]
HEIGHT = WINDOW_SIZE[1]
# you can also do "unpacking"
# WIDTH, HEIGHT = WINDOW_SIZE
if self.rect.right > WIDTH:
# we will now switch directions
self.going_right = False
# we will also set the left side to be equal to the window side
# this means we won't go off screen and bug out
self.rect.right = WIDTH
elif self.rect.left < 0:
print("you should write code here!")
elif self.rect.top < 0:
print("you should write code here!")
elif self.rect.bottom > HEIGHT:
print("you should write code here!")
Exercise 4¶
Now, we will give our hero a wall to bump into!
This will demonstrate why we use Rect
.
Check out this documentation: PyGame Rect Docs for Colliding
This code should go into the INIT SECTION part of the code:
1 2 3 4 5 6 | # this will assume WINDOW_SIZE
WIDTH = WINDOW_SIZE[0]
HEIGHT = WINDOW_SIZE[1]
# you can also do "unpacking"
# WIDTH, HEIGHT = WINDOW_SIZE
wall1 = Rect(WIDTH // 2, 0, WIDTH // 10, HEIGHT)
|
Then, after having moved, inside the while
loop ACTION CODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ### assume hero moves here in some way
### could be calling hero1.move()
if hero1.rect.colliderect(wall1):
print("The hero has collided with the wall!")
print("You should be adding code here!")
if hero1.rect.right > wall1.left:
hero1.rect.right = wall1.left
hero1.going_right = False
elif hero1.rect.left < wall1.right:
print("Add code here!")
elif hero1.rect.bottom > wall1.top:
print("Add code here!")
elif hero1.rect.top < wall1.bottom:
print("Add code here!")
|
You should finish the code inside the if
statements.
Exercise 5¶
Move the above code into the Hero
class.
1 2 3 | def handle_collision(self, other_rect):
if self.rect.colliderect(other_rect):
print("The code is basically the same from Exercise 4!")
|
The major differences will be that hero1
is used to refer to the hero OUTSIDE of itself,
but when the code is INSIDE itself, you use the self
variable to reference it.
What should the code look like now inside the while
loop?
Exercise 6¶
Now you will add multiple walls.
1 2 3 4 5 6 7 8 9 10 | two_thirds_height = 2 * HEIGHT//3
one_tenth_width = WIDTH // 10
one_third_width = WIDTH // 3
### Rects want x, y, w, h
### x and y are for the TOP LEFT corners.
wall1 = Rect(one_third_width, 0, one_tenth_width, two_thirds_height)
wall2 = Rect(2 * one_third_width, HEIGHT - two_thirds_height, one_tenth_width, two_thirds_height)
walls = [wall1, wall2]
|
Inside the loop:
1 2 | for wall in walls:
hero1.handle_collision(wall)
|
You should draw out a maze and plan the x, y, w, and h coordinates. You should be using at least 5 walls.
Bonus Exercise¶
If you want to add human movement to the hero, you can do the following:
1 2 3 4 5 6 7 8 | ### inside WHILE LOOP section
for event in pygame.event.get():
## standard quit
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
hero1.move_left()
|