Making a Game of IT - Day 2 - Pygame
Note: our introduction into pygame is taken/adapted from: https://inventwithpython.com/pygame/
- Pygame - Graphics
- Pygame - Animation
- Pygame - Controls
- Pygame - Text
- Pygame - Collisions
- Putting it all together
Pygame - Graphics
Hello, Rectangle
First, let’s import the pygame package and initialize its modules.
import pygame
pygame.init()
Let’s set up game screen.
screen = pygame.display.set_mode([1200, 800])
pygame.display.set_caption("Game Name")
Let’s define some colors using RGB codes (red, green, blue). Each color is a three-item list where the intensity of each hue is described from 0 (low intensity) to 255 (high intensity).
RED = [255, 0, 0]
WHITE = [255, 255, 255]
BLACK = [0, 0, 0]
Comprehension Question
What would the code for GREEN
be?
For BLUE
?
In the coordinate system you know from math class, the origin is on the bottom left.
^
5 |
4 |
3 | (3,2)
2 | *
1 |
0 +------------->
0 1 2 3 4 5
The coordinates in pygame are a little different: the origin is on the top left.
0 1 2 3 4 5
0 +------------->
1 |
2 | *
3 | (3,2)
4 |
5 |
|
The x-axis works exactly like you’re used to, but now larger y values mean closer to the bottom of the screen.
We’ve got color and coordinates figured out, so we’re ready to draw our rectangle.
First, we define the rectangle shape.
The arguments, in order, represent left
, top
, width
, and height
.
The arguments left
and top
say where the
first_rect = pygame.Rect(
100, # left
200, # top
30, # width
150 # height
)
pygame.draw.rect(screen, RED, first_rect)
pygame.display.flip() # refresh the screen
Note that we have to call pygame.display.flip()
to get pygame to draw our changes to the screen.
This is so we can make a whole mess of changes one-by-one and then render them all at once efficiently.
Challenge: Can you draw
- a red rectangle in the top left quarter of the screen,
- a blue rectangle on the top right quarter of the screen,
- a green rectangle on the bottom half of the screen?
Getting in Shape
We can use pygame to draw a line connecting a start point to an end point.
pygame.draw.line(
screen, # where to draw the line
WHITE, # line color
[0, 0], # x,y start point
[100, 100], # x,y end point
5 # line width
)
To draw a circle or an ellipse (a squished circle), we specify a bounding rectangle. Then, we draw the ellipse inside that rectangle.
ellipse_rect = pygame.Rect(
400, # left
400, # top
40, # width
80 # height
)
pygame.draw.ellipse(
screen, # where to draw ellipse
RED, # color
ellipse_rect # rectangle to draw inside
)
pygame.display.flip() # refresh the screen
Mathematically, a polygon is defined by series of straight paths between vertices. For example, triangles, squares, and pentagons are all polygons.
In pygame, we define a polygon just like in math: using a list of (x,y)
vertex coordinates.
pygame.draw.polygon(
screen, # where to draw the polygon
RED, # color
[[0,0], [200,200], [100,0]] # x,y coordinates of vertices
)
pygame.display.flip() # refresh the screen
Challenge: Can you draw a simple house using pygame shapes?
The Cat’s Meow
We’ve got cat scratch fever and want to render a cat in PyGame. We could try to use shapes, but drawing even just a recognizable cat would be a lot of work — lots of ellipses and lines! A better idea is just to draw an image of a cat.
To make this next code work, you need to have the image cat.png saved into the same folder as your Python file.
First, we have to load the image from file.
(Note: in a game, we usually only want to do this once.)
Then, we ask for the pygame rectangle the same size as our image and recenter it to the x,y
coordinates where we’d like it to go.
Finally, we blit
the image into the rectangle we set up and refresh the screen.
cat_image = pygame.image.load('cat.png')
cat_rect = cat_image.get_rect()
cat_rect.center = [100, 400]
screen.blit(cat_image, cat_rect)
pygame.display.flip() # refresh the screen
Challenge:
- Can you draw the cat in your house’s window?
- Download another image from the interwebs and add it to your house.
Pygame - Animation
Moving on from drawing static images to simple animations isn’t too difficult in pygame. We animate images by drawing an image to the screen, and then quickly drawing a slightly different image to the screen.
'''
Code copied and adapted from https://inventwithpython.com/pygame/chapter2.html
'''
import sys
import random
import pygame
pygame.init()
FPS = 30 # Frames per second
fps_clock = pygame.time.Clock() # Helps us make sure our programs run at a certain maximum FPS
# It'll put small pauses each iteration through our game loop
# Setup the window
width = 400
height = 300
display_surface = pygame.display.set_mode([width, height])
pygame.display.set_caption('Catmation!')
cat_img = pygame.image.load('media/cat.png')
cat_x = 10
cat_y = 10
direction = 'left'
while True: # Enter the game loop
display_surface.fill([255, 255, 255])
# Position the cat randomly
# cat_x = random.randint(0, width)
# cat_y = random.randint(0, height)
# CHALLENGE: have the cat infinitely pace back and forth (move to the right
# until it reaches an edge, then move left, etc)
# -- Challenge code --
if direction == 'right':
# Move to the right
cat_x += 5
if cat_x >= 280: # Need to change directions
direction = 'left'
cat_img = pygame.transform.flip(cat_img, True, False)
elif direction == 'left':
# Move to the left
cat_x -= 5
if cat_x <= 20: # Need to change directions
direction = 'right'
cat_img = pygame.transform.flip(cat_img, True, False)
# Question: why does the back and forth look the way it does?
# Follow-up: can you make the cat go in a square loop?
# - What about a circular loop?
# Follow-up: can you make the cat face the direction it's moving?
# - Look into pygame.transform
# Update cat
display_surface.blit(cat_img, [cat_x, cat_y]) # Blit draws something on the surface
# Setup the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Update the screen
pygame.display.update()
fps_clock.tick(FPS) # Tick the clock!
|>> download catimation_finished.py
Pygame - Controls
So far, we’ve only used input
to ask for user input as text.
Now, we’ll use pygame to handle real-time keyboard and mouse input!
The Big Event
import pygame
import sys
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([100,100])
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("Quit.")
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
print("Key press.")
elif event.type == pygame.KEYUP:
print("Key up.")
elif event.type == pygame.MOUSEBUTTONDOWN:
print("Key down.")
else:
print("Unknown.")
clock.tick(60) # 60 frames per second
Keyed Up
import pygame
import sys
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([100,100])
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
print("Key press.")
if event.key == pygame.K_SPACE:
print("Space key pressed!")
elif event.key == pygame.K_w:
print("w key pressed!")
elif event.key == pygame.K_a:
print("a key pressed!")
elif event.key == pygame.K_s:
print("s key pressed!")
elif event.key == pygame.K_d:
print("d key pressed!")
else:
print("Unknown.")
clock.tick(60) # 60 frames per second
Challenge:
Can you make a game that tests how many total times the user can press the j
and/or k
keys in ten seconds?
Can you make it so that pressing other keys makes you loose points?
Hint: the frame rate is 60 frames per second, so how many times do you need to go through the outer loop?
Challenge:
Open back up your catimation.py
file… can you make the user control the movement of the cat image with the w
(up), a
(left), s
(down), and d
(right) keys?
Mousing Around
import pygame
import sys
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([100,100])
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
x, y = event.pos
print("mouse now at", x, y)
elif event.type == pygame.MOUSEBUTTONDOWN:
print("Mouse button pressed")
elif event.type == pygame.MOUSEBUTTONUP:
print("Mouse button released")
else:
print("Unknown.")
clock.tick(60) # 60 frames per second
Challenge: Can you make a game that tests how far the user can move the mouse in ten seconds? You’ll want to calculate the distance moved relative to the last mouse position each time through the outer loop and add it to a running sum. Can you make it moving the mouse through the center of the screen loses you points? Can you draw a rectangle there so the user knows to avoid it?
- hint 1: the frame rate is 60 frames per second, so how many times do you need to go through the outer loop?
- hint 2: calculate the distance between two mouse positions
[x_1, y_1]
and[x_2, y_2]
as(x_1 - x_2) ** 2 + (y_1 - y_2) ** 2
.
Challenge:
Open back up your catimation.py
file… can you make the user control the movement of the cat image with the mouse?
First, just draw the cat at the position of the mouse cursor.
Then, if you want an extra challenge, have the cat chase the mouse!
Pygame - Text
Drawing text in pygame is a lot like drawing images.
'''
Rendering text
Code copied and adapted from https://inventwithpython.com/pygame/chapter2.html
'''
import sys
import pygame
pygame.init()
FPS = 60
clock = pygame.time.Clock()
screen_width = 400
screen_height = 300
display_bg_color = [255,255,255]
display_surface = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption('This window will have some text in it. Woo?')
# Font documentation: https://www.pygame.org/docs/ref/font.html
# use the pygame.font.get_fonts() function to get a list of available fonts on your
# system
print('Available fonts:', pygame.font.get_fonts())
# To render text with pygame, first we need to create a font
# - when we create a font, we tell it which font-style to use and what font size
# we want.
# - CHALLENGE: try changing the font size and the font type (use get_fonts() to
# figure out what is possible)
font = pygame.font.SysFont('impact', 32)
# Next, we can render the font onto a surface (which we'll eventually draw on the
# display_display surface)
# - To render text, we need to specify: (1) the string we want to write, (2) use
# anti-aliasing? (smoothing technique), (3) what color we want the text to be?,
# and (4) what background color we want? (if blank, no background color)
hello_color = [0,0,0]
hello_bg = [0,255,0]
hello_surface = font.render('Hello World!', True, hello_color, hello_bg)
# Where do we want to draw the text?
hello_x = screen_width / 2
hello_y = screen_height / 2
# CHALLENGE: add some more text to the screen, try rendering a few different fonts
# at once
goodbye_color = [255,255,255]
goodbye_bg = [0,0,0]
goodbye_surface = font.render('Goodbye forever!', True, goodbye_color, goodbye_bg)
goodbye_x = 0
goodbye_y = 0
# CHALLENGE: just like the cat animation, can you make some text move around?
moving_text_color = [0,0,0]
moving_text_surface = font.render('MOVING', True, moving_text_color)
moving_text_bounding_rect = moving_text_surface.get_rect()
moving_text_bounding_rect.x = screen_width - moving_text_surface.get_rect().width
moving_text_bounding_rect.y = 0
moving_text_dir = 'southwest'
# rot_degrees = 1
while True:
# fill the background
display_surface.fill(display_bg_color)
# blit the text onto the screen
# - The top left corner of the text should be at hello_x, hello_y
display_surface.blit(hello_surface, [hello_x, hello_y])
# blit goodbye to the screen
display_surface.blit(goodbye_surface, [goodbye_x, goodbye_y])
# Animate the moving text
if moving_text_dir == 'southwest':
moving_text_bounding_rect.x -= 1 # Move text to the left by 1
moving_text_bounding_rect.y += 1 # Move text down by 1
if (moving_text_bounding_rect.bottomleft[1] >= screen_height) or (moving_text_bounding_rect.x <= 0):
moving_text_dir = 'northeast'
elif moving_text_dir == 'northeast':
moving_text_bounding_rect.x += 1 # Move text to the right by 1
moving_text_bounding_rect.y -= 1 # Move text up by 1
if (moving_text_bounding_rect.topright[1] <= 0) or (moving_text_bounding_rect.x >= screen_width):
moving_text_dir = 'southwest'
# blit the moving text
display_surface.blit(moving_text_surface, moving_text_bounding_rect)
# Events!
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Update the display
pygame.display.update()
clock.tick(FPS)
|>> download text_finished.py
Pygame - Collisions
We can detect collisions between rectangles using a colliderect
instruction. In the example below, we have two rectangles: one following your mouse around and another that doesn’t move. Anytime the mouse-following rectangle overlaps (collides) with the non-moving rectangle, we randomize the color of the mouse-following rectangle.
'''
Collision detection
'''
import sys
import random
import pygame
# Initialize pygame
pygame.init()
# Some constants
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 800
FPS = 60
LIGHT_GREY = [230, 230, 230]
# Create the display surface
display = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("Collider Demo")
# Make a clock to manage frames per second
clock = pygame.time.Clock()
# Make a rectangle that will follow the mouse around
my_rect = pygame.Rect(100, 200, 30, 150)
# Make a wall (rectangle) that we'll have the mouse-following rectangle collide with
wall = pygame.Rect(400, 400, 30, 600)
# Game loop
while True:
# Set the background color
display.fill(LIGHT_GREY)
# my_rect is going to follow the mouse around => we need to get the mouse's x,y position
pos = pygame.mouse.get_pos()
my_rect.centerx = pos[0]
my_rect.centery = pos[1]
# To start, mouse rectangle will be black
color = [0, 0, 0]
if my_rect.colliderect(wall): # <==== Here's where the collision magic happens
# If there's a collision, randomize the mouse-rectangle's color
print("collide")
color = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]
# Draw both the mouse rectangle and th e wall
pygame.draw.rect(display, [0,0,0], wall)
pygame.draw.rect(display, color, my_rect)
# Event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Update the display, tick clock
pygame.display.update()
clock.tick(FPS)
# CHALLENGE: Add a few more obstacles to the scene and test for collisions between
# the mouse and those obstacles
# - bonus: trigger different reactions depending on which obstacle you
# hit with the mouse-following rectangle
|>> download collision.py
Putting it all together
Mouse pew pew shooter
In this example, we’re going to have pygame shoot projectiles from the mouse when the mouse is clicked:
'''
Bullet shooter
'''
import sys
import random
import pygame
pygame.init() # Initialize pygame
# Some constant values
screen_width = 1200
screen_height = 800
FPS = 60 # Frames per second
# colors
RED = [255, 0, 0]
LIGHT_GREY = [230, 230, 230]
BLACK = [0, 0, 0]
# Setup the screen surface
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Bullet Shooter")
clock = pygame.time.Clock() # Get a clock to manage FPS
# Projectiles!
bullets = [] # Here's where we'll track all of the bullets on the screen
bullet_velocity_x = 10 # How fast should bullets move?
bullet_width = 7.5
bullet_height = 5
# Targets!
enemy_width = 50
enemy_height = 50
# We'll start with two, statically placed targets
enemies = [pygame.Rect([900,100],[enemy_width,enemy_height]), pygame.Rect([900,700],[enemy_width,enemy_height])]
# Game loop
while True:
screen.fill(LIGHT_GREY)
# Draw the enemies!
for enemy in enemies:
pygame.draw.rect(screen, RED, enemy)
# Challenge: (1) Every time you click, fire bullets from your mouse
# Challenge: (2) clean up off-screen bullets
# Challenge: (3) Have bullets that collide with enemies remove that enemy from the screen
# Challange: (4) spawn new enemies randomly
# Challenge: (5) spawn enemy when you press the spacebar
# Draw the projectiles
# - We don't need to track projectiles that go offscreen anymore (in fact, we
# really shouldn't track those), so we'll keep track of what projectiles are
# still on screen with on_screen_bullets
on_screen_bullets = []
for bullet in bullets:
bullet.left += bullet_velocity_x # Apply movement
pygame.draw.rect(screen, BLACK, bullet) # Draw the bullet
# Does this bullet collide with any enemies?
alive_enemies = [] # We'll use this to track which
# enemies are still alive after handling this bullet
for enemy in enemies:
if bullet.colliderect(enemy):
# If bullet collides, make some noise, and don't add to alive enemies list
print(random.choice(["AAAAHHHH","GRUNT", "UUUGGG", "SPLAT", "POP"]))
continue
alive_enemies.append(enemy) # Enemy escaped the projectile
enemies = alive_enemies # Update enemies list
# Is this projectile still on screen?
if bullet.left <= screen_width:
on_screen_bullets.append(bullet)
# Update list of projectiles with only those that are still on screen
bullets = on_screen_bullets
# Event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
# Fire bullet when player presses mouse button
pos = pygame.mouse.get_pos()
bullet = pygame.Rect(pos[0], pos[1], bullet_width, bullet_height)
bullets.append(bullet)
print(len(bullets))
pygame.display.update() # update the screen
clock.tick(FPS)
|>> download bullets_finished.py
Keyboard pew pew shooter
Can we adjust the program to have a character rectangle that the player moves around with arrow keys, and when the player presses the spacebar, it fires projectiles (instead of the mouse)?
'''
Bullet shooter game
'''
import sys
import random
import pygame
pygame.init()
# let's try to avoid magic numbers for this
screen_width = 1200
screen_height = 800
FPS = 60
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Bullet Shooter")
clock = pygame.time.Clock()
RED = [255, 0, 0]
LIGHT_GREY = [230, 230, 230]
BLACK = [0, 0, 0]
BLUE = [0,0,230]
char_start_x = 0
char_start_y = 0
char_width = 50
char_height = 50
char_speed = 5 # How fast does character move?
cur_char_x_vel = 0 # What's the character's current x speed?
cur_char_y_vel = 0 # What's the character's current y speed?
character = pygame.Rect([char_start_x, char_start_y], [char_width, char_height])
bullets = [] # Here's where we'll track all of the bullets on the screen
bullet_velocity_x = 10 # How fast should bullets move?
bullet_width = 7.5
bullet_height = 5
enemy_width = 50
enemy_height = 50
enemies = [pygame.Rect([900,100],[enemy_width,enemy_height]), pygame.Rect([900,700],[enemy_width,enemy_height])]
# Game loop
while True:
screen.fill(LIGHT_GREY)
# Determine character movement
# Is the player pressing a key?
# - Is player moving vertically?
pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_UP]:
print("up arrow")
cur_char_y_vel = -1*char_speed
elif pressed_keys[pygame.K_DOWN]:
print("down arrow")
cur_char_y_vel = char_speed
else:
cur_char_y_vel = 0
# - Is player moving horizontally?
if pressed_keys[pygame.K_RIGHT]:
print("down arrow")
cur_char_x_vel = char_speed
elif pressed_keys[pygame.K_LEFT]:
print("down arrow")
cur_char_x_vel = -1*char_speed
else:
cur_char_x_vel = 0
# Draw the character!
character.left += cur_char_x_vel
character.top += cur_char_y_vel
pygame.draw.rect(screen, BLUE, character)
# Draw the enemies!
for enemy in enemies:
pygame.draw.rect(screen, RED, enemy)
# Draw the bullets!
# Challenge: Every time you click, fire bullets from your mouse
# Challenge: Have bullets that collide with enemies remove that enemy from the screen
# Challenge: clean up off-screen bullets
# Challange: spawn new enemies
on_screen_bullets = []
for bullet in bullets:
bullet.left += bullet_velocity_x
pygame.draw.rect(screen, BLACK, bullet)
alive_enemies = []
for enemy in enemies:
if bullet.colliderect(enemy):
print(random.choice(["AAAAHHHH","GRUNT", "UUUGGG", "SPLAT", "POP"]))
continue
alive_enemies.append(enemy)
enemies = alive_enemies
if bullet.left <= screen_width:
on_screen_bullets.append(bullet)
bullets = on_screen_bullets
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
# Keydown event!
if event.key == pygame.K_SPACE:
# Fire a bullet
print("pressed space")
print(character.midright)
pos = character.midright
bullet = pygame.Rect(pos[0], pos[1], bullet_width, bullet_height)
bullets.append(bullet)
pygame.display.update()
clock.tick(FPS)
|>> download bullets_game_v0.py
Keyboard multi-direction pew pew shooter
If you did that, can you use WASD to change the direction that the projectiles are shot from the character’s rectangle? (e.g., ‘w’ points projectiles upward, ‘d’ to the right, etc)
'''
Bullet shooter game
'''
import sys
import random
import pygame
pygame.init()
# let's try to avoid magic numbers for this
screen_width = 1200
screen_height = 800
FPS = 60
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Bullet Shooter")
clock = pygame.time.Clock()
RED = [255, 0, 0]
LIGHT_GREY = [230, 230, 230]
BLACK = [0, 0, 0]
BLUE = [0,0,230]
char_start_x = 0
char_start_y = 0
char_width = 50
char_height = 50
char_speed = 5 # How fast does character move?
character = {"rect":pygame.Rect([char_start_x, char_start_y], [char_width, char_height]),
"dir": "right",
"x_vel": 0,
"y_vel": 0,
"color": BLUE}
bullets = [] # Here's where we'll track all of the bullets on the screen
bullet_speed = 10 # How fast should bullets move?
bullet_width = 7.5
bullet_height = 5
enemy_width = 50
enemy_height = 50
enemies = [{"rect": pygame.Rect([900,100],[enemy_width,enemy_height]), "dir": "left"},
{"rect": pygame.Rect([900,700],[enemy_width,enemy_height]), "dir": "left"}]
# Game loop
while True:
screen.fill(LIGHT_GREY)
# Determine character movement
# Is the player pressing a key?
# - Is player moving vertically?
pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_UP]:
print("up arrow")
character["y_vel"] = -1*char_speed
elif pressed_keys[pygame.K_DOWN]:
print("down arrow")
character["y_vel"] = char_speed
else:
character["y_vel"] = 0
# - Is player moving horizontally?
if pressed_keys[pygame.K_RIGHT]:
print("down arrow")
character["x_vel"] = char_speed
elif pressed_keys[pygame.K_LEFT]:
print("down arrow")
character["x_vel"] = -1*char_speed
else:
character["x_vel"] = 0
# Draw the character!
character["rect"].left += character["x_vel"]
character["rect"].top += character["y_vel"]
pygame.draw.rect(screen, BLUE, character["rect"])
# - indicate where character is facing
if character["dir"] == "up":
pos = character["rect"].midtop
pygame.draw.rect(screen, BLACK, pygame.Rect([pos[0], pos[1]-5], [5, 5]))
elif character["dir"] == "down":
pos = character["rect"].midbottom
pygame.draw.rect(screen, BLACK, pygame.Rect([pos[0], pos[1]], [5, 5]))
elif character["dir"] == "right":
pos = character["rect"].midright
pygame.draw.rect(screen, BLACK, pygame.Rect([pos[0], pos[1]], [5, 5]))
elif character["dir"] == "left":
pos = character["rect"].midleft
pygame.draw.rect(screen, BLACK, pygame.Rect([pos[0]-5, pos[1]], [5, 5]))
# Draw the enemies!
for enemy in enemies:
pygame.draw.rect(screen, RED, enemy["rect"])
# Draw the bullets!
# Challenge: Every time you click, fire bullets from your mouse
# Challenge: Have bullets that collide with enemies remove that enemy from the screen
# Challenge: clean up off-screen bullets
# Challange: spawn new enemies
on_screen_bullets = []
for bullet in bullets:
# What direction is the bullet going?
if bullet["dir"] == "up":
bullet["rect"].top -= bullet_speed
elif bullet["dir"] == "right":
bullet["rect"].left += bullet_speed
elif bullet["dir"] == "down":
bullet["rect"].top += bullet_speed
elif bullet["dir"] == "left":
bullet["rect"].left -= bullet_speed
# bullet["rect"].left += bullet_speed
pygame.draw.rect(screen, BLACK, bullet["rect"])
alive_enemies = []
for enemy in enemies:
if bullet["rect"].colliderect(enemy["rect"]):
print(random.choice(["AAAAHHHH","GRUNT", "UUUGGG", "SPLAT", "POP"]))
continue
alive_enemies.append(enemy)
enemies = alive_enemies
if bullet["rect"].left <= screen_width:
on_screen_bullets.append(bullet)
bullets = on_screen_bullets
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
# Keydown event!
if event.key == pygame.K_SPACE:
# Fire a bullet
print("pressed space")
pos = [0, 0]
if character["dir"] == "up":
pos = character["rect"].midtop
h = bullet_width
w = bullet_height
elif character["dir"] == "down":
pos = character["rect"].midbottom
h = bullet_width
w = bullet_height
elif character["dir"] == "right":
pos = character["rect"].midright
h = bullet_height
w = bullet_width
elif character["dir"] == "left":
pos = character["rect"].midleft
h = bullet_height
w = bullet_width
bullet = {"rect": pygame.Rect(pos[0], pos[1], w, h), "dir": character["dir"]}
bullets.append(bullet)
if event.key == pygame.K_w:
character["dir"] = "up"
if event.key == pygame.K_d:
character["dir"] = "right"
if event.key == pygame.K_s:
character["dir"] = "down"
if event.key == pygame.K_a:
character["dir"] = "left"
pygame.display.update()
clock.tick(FPS)
# Challenges:
# - Add enemy spawns
# - Add enemy movement
# - Add enemy shooting
|>> download bullets_game_v1.py