import pygame
pygame.init() # Initialize pygame
screen = pygame.display.set_mode((800, 600)) # Set the screen
pygame.display.set_caption('My Pygame Window') # Set the window title
running = True
while running:
# Check for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Update game state
# Render graphics
pygame.display.flip() # Update the display
pygame.quit()02-19-24 (Monday)
Lord, you reveal your glory in every thing you made
Let us today engage with this creation so that we may participate in your beauty and wisdom
May the technology we use or even develop point us toward that,
Instead of dragging us towards our own vicious desires and illusions of freedom
Help us, and our society, to know your ways and be still, for yours is the glory
And our hearts are restless till they find rest in You.
Amen.
1 PyGame basics
What do I have to know?
1.1 Main game loop
- Import
pygame - Initialize
- Set up the display screen
- Create the main game loop, with usually the steps:
- Catch events
- Update game states
- Draw everything
- Quit the game in the event “QUIT”
1.2 Drawing/Rendering
import pygame
pygame.init() # Initialize pygame
screen = pygame.display.set_mode((800, 600)) # Set the screen
pygame.display.set_caption('My Pygame Window') # Set the window title
running = True
while running:
# Check for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Fill the screen with white
screen.fill(WHITE)
# Draw a red circle in the center of the screen
pygame.draw.circle(screen, RED, (400, 300), 50)
pygame.display.flip() # Update the display
pygame.quit()- Example 2: rendering sprites (get the image here)
- Load the sprite before the game loop
- Use “blit” to draw the sprite
import pygame
pygame.init() # Initialize pygame
# Set constants
WIDTH, HEIGHT = 800, 600
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((800, 600)) # Set the screen
pygame.display.set_caption('My Pygame Window') # Set the window title
# Load the smiley face image
smiley_image = pygame.image.load("smiley.png")
smiley_rect = smiley_image.get_rect()
smiley_rect.center = (WIDTH // 2, HEIGHT // 2)
running = True
while running:
# Check for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Draw
screen.fill(WHITE)
screen.blit(smiley_image, smiley_rect)
pygame.display.flip() # Update the display
pygame.quit()1.3 Animating
- Add parameters for center, radius and speed to make our smiley rotate
- Update position according to each run of the game loop
- Use
clock.tick()to set a constant FPS rate at the game
import pygame
import math
pygame.init() # Initialize pygame
# Set constants
WIDTH, HEIGHT = 800, 600
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((800, 600)) # Set the screen
pygame.display.set_caption('My Pygame Window') # Set the window title
# Load the smiley face image
smiley_image = pygame.image.load("smiley.png")
smiley_rect = smiley_image.get_rect()
# Animation parameters
radius = 200
angle = 0
speed = 0.02 # Controls the speed of the animation
clock = pygame.time.Clock() # start the clock
running = True
while running:
# Check for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Update state
### Update position
x = WIDTH // 2 + int(math.cos(angle) * radius)
y = HEIGHT // 2 + int(math.sin(angle) * radius)
smiley_rect.center = (x, y)
### Update angle for next frame
angle += speed
# Draw
screen.fill(WHITE)
screen.blit(smiley_image, smiley_rect)
pygame.display.flip() # Update the display
clock.tick(60)
pygame.quit()1.4 Catching events
- You can catch more events such as mouse clicks or keyboard presses. For a list of event types, see here.
- Let’s add the event of right and left arrow pressing to change the direction of the smiley
import pygame
import math
pygame.init() # Initialize pygame
# Set constants
WIDTH, HEIGHT = 800, 600
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((800, 600)) # Set the screen
pygame.display.set_caption('My Pygame Window') # Set the window title
# Load the smiley face image
smiley_image = pygame.image.load("smiley.png")
smiley_rect = smiley_image.get_rect()
# Animation parameters
radius = 200
angle = 0
speed = 0.02 # Controls the speed of the animation
clock = pygame.time.Clock() # start the clock
running = True
while running:
# Check for events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
speed = 0.02
elif event.key == pygame.K_LEFT:
speed = -0.02
# Update state
### Update position
x = WIDTH // 2 + int(math.cos(angle) * radius)
y = HEIGHT // 2 + int(math.sin(angle) * radius)
smiley_rect.center = (x, y)
### Update angle for next frame
angle += speed
# Draw
screen.fill(WHITE)
screen.blit(smiley_image, smiley_rect)
pygame.display.flip() # Update the display
clock.tick(60)
pygame.quit()1.5 Creating some classes
- Let’s create a class “Player” to represent our main character: John Calvin.
- Calvin
GRAVITY = 0.75 # setting a gravity constant
# Player class
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("calvin_char.png")
self.rect = self.image.get_rect()
self.rect.center = (WIDTH // 2, HEIGHT // 2)
self.velocity = pygame.math.Vector2(0, 0) # setting a vector velocity
def update(self):
# Apply gravity
self.velocity.y += GRAVITY
self.rect.y += self.velocity.y
# Check collision with floor
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
self.velocity.y = 0
def jump(self):
self.velocity.y = -12 # Jump strength- Now, we create the player and render in the screen.
- You can use a sprite group to update and draw everything together! Just implement the function “update()” in all of them!
import pygame
# Initialize Pygame
pygame.init()
# Constants
WIDTH, HEIGHT = 800, 600
FPS = 60
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAVITY = 0.75
# Set up the game window
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Super Calvin Jump")
# Player class
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("calvin_char.png")
self.rect = self.image.get_rect()
self.rect.center = (WIDTH // 2, HEIGHT // 2)
self.velocity = pygame.math.Vector2(0, 0) # setting a vector velocity
def update(self):
# Apply gravity
self.velocity.y += GRAVITY
self.rect.y += self.velocity.y
# Check collision with floor
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
self.velocity.y = 0
def jump(self):
self.velocity.y = -12 # Jump strength
clock = pygame.time.Clock()
player = Player() # create Calvin!
all_sprites = pygame.sprite.Group(player) # add Calvin to the sprite group
# game loop
running = True
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.jump()
# Update everything
all_sprites.update()
# Render everything
screen.fill(WHITE)
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(FPS)
pygame.quit()- Let’s make it move left and right.
- You can also check for events at the very time of the update. This is another way to implement some kind of logic.
MOVE_SPEED = 5
# Player class
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("calvin_char.png")
self.rect = self.image.get_rect()
self.rect.center = (WIDTH // 2, HEIGHT // 2)
self.velocity = pygame.math.Vector2(0, 0) # setting a vector velocity
def update(self):
# Apply gravity
self.velocity.y += GRAVITY
self.rect.y += self.velocity.y
# Check collision with floor
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
self.velocity.y = 0
# Handle horizontal movement
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.velocity.x = -MOVE_SPEED
elif keys[pygame.K_RIGHT]:
self.velocity.x = MOVE_SPEED
else:
self.velocity.x = 0
self.rect.x += self.velocity.x
def jump(self):
self.velocity.y = -12 # Jump strength1.6 Collision detection
- Let’s add some blocks to our scene.
- We now need to check if Calvin is colliding with them!
class Block(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.image = pygame.Surface((width, height))
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)- We can add them to a new group of blocks.
# Create blocks
blocks = pygame.sprite.Group()
blocks.add(Block(200, 400, 100, 20))
blocks.add(Block(400, 300, 100, 20))
blocks.add(Block(600, 200, 100, 20))
# Create player
player = Player()
all_sprites = pygame.sprite.Group(player)- And now, in the update function of Player, we check for collisions. We will use the function
pygame.sprite.spritecollide.- We add the blocks group to the Player update function.
def update(self, blocks):
# update position
self.rect.x += self.velocity.x
self.rect.y += self.velocity.y
# update velocities
self.velocity.y += GRAVITY
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.velocity.x = -MOVE_SPEED
elif keys[pygame.K_RIGHT]:
self.velocity.x = MOVE_SPEED
else:
self.velocity.x = 0
# Check collision with walls
collisions = pygame.sprite.spritecollide(self, blocks, False)
for block in collisions:
clip_rect = self.rect.clip(block.rect)
if clip_rect.width > clip_rect.height: # up or down
if self.rect.bottom > block.rect.top and self.rect.bottom < block.rect.bottom:
self.rect.bottom = block.rect.top
self.velocity.y = 0
elif self.rect.top < block.rect.bottom:
self.rect.top = block.rect.bottom
self.velocity.y = 0
else: # right or left
if self.rect.right > block.rect.left and self.rect.right < block.rect.right:
self.rect.right = block.rect.left
self.velocity.x = 0
elif self.rect.left < block.rect.right:
self.rect.left = block.rect.right
self.velocity.x = 0
# Check collision with floor
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
self.velocity.y = 0- In this case, we will detect collision only in terms of rectangles. Later, you may need to implement a collision mask. See here.
1.7 Sound
- Let’s add a jump sound. Out of the main loop, load the sound:
jump_sound = pygame.mixer.Sound('jump.mp3')- Now make it play when Calvin jumps!
def jump(self):
self.velocity.y = -12 # Jump strength
jump_sound.play()1.8 Multiple scenes
- There are many ways to create multiple scenes, but a simple one is just create a function for each scene. For example:
def main_menu():
bg = pygame.image.load("supercalvin.png")
bg = pygame.transform.scale(bg, (800, 600))
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
running = False
# Render everything
screen.blit(bg, (0, 0))
pygame.display.flip()
clock.tick(FPS)
def first_level():
# background
bg = pygame.image.load("geneva.jpg")
bg = pygame.transform.scale(bg, (800, 600))
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.jump()
# Update everything
player.update(blocks)
blocks.update()
# Render everything
screen.blit(bg, (0, 0))
player_g.draw(screen)
blocks.draw(screen)
pygame.display.flip()
clock.tick(FPS)
main_menu()
first_level()
pygame.quit()