Contents
Welcome to this tutorial where we’ll be building a simple “Zombie Shooter” game using Pygame! This game involves a player controlling a shooter at the bottom of the screen, shooting bullets upwards to eliminate incoming zombies. The goal is to survive as long as possible while accumulating points by shooting zombies.
By the end of this tutorial, you’ll have a fully working arcade-style shooter game. Let’s get started! —
What We’ll Build
In this game:
- Use Left/Right arrow keys to move
- Press Spacebar to shoot
- Avoid letting zombies reach the bottom
- Earn points by shooting zombies
- Beat your top score, saved in a local file
Here is a preview:
Game Breakdown (Step-by-Step)
1. Game Initialization
We start by:
- Initializing Pygame
- Creating the main window
- Defining colors
- Loading assets (player + zombie images)
This sets the stage for everything else.
2. Player Setup
- The player sprite sits at the bottom of the screen
- It moves left and right
- Movement is handled using the arrow keys
We store the player’s position using player_x, player_y.
3. Bullet Mechanics
Bullets:
- Spawn at the player’s current location
- Move upward each frame
- Disappear when leaving the screen
We store bullets as a list of [x, y] positions.
4. Zombie Mechanics
Zombies:
- Spawn at random x-positions at the top
- Move downward at a constant speed
- Trigger game over if they reach the bottom
We store zombies just like bullets—lists of [x, y].
5. Collision Detection
We compare bullet and zombie positions:
- If a bullet hits a zombie:
- Remove both
- Increase score
- Update top score if necessary
6. Game Over & Restart
If a zombie passes the bottom:
- Game shows “Game Over!”
- Displays the final score
- Player can restart by pressing R
The reset_game() function clears bullets, zombies, score, and positions.
Summary
Player Setup: This is where we load the player’s image and place it at the bottom center of the screen. The player moves left and right using the arrow keys, and we track the player’s position using player_x and player_y.
Bullet Mechanics: When the player presses space, bullets are created at the player’s current position. Each bullet moves upwards at a constant speed. We remove bullets when they go off-screen.
Zombie Mechanics: Zombies spawn at random positions at the top of the screen and slowly move downwards. If a zombie reaches the bottom, the game ends, and the player loses.
Collision and Scoring: Whenever a bullet hits a zombie, the zombie and bullet are removed from the game, and the score increases by 1. We also keep track of the top score in a file and display it on the screen.
Game Over and Restart: If the game is over, the player can press “R” to restart the game, resetting everything to its initial state.
Source code
import pygame
import random
## Initialize pygame
pygame.init()
## Screen dimensions
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Zombie Shooter")
## Colors
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
## Load assets
player_img = pygame.image.load("static/icon.png")
zombie_img = pygame.image.load("static/zombie.png")
## Resize images
player_size = 50
player_img = pygame.transform.scale(player_img, (player_size, player_size))
zombie_img = pygame.transform.scale(zombie_img, (player_size, player_size))
## Player setup
player_x = WIDTH // 2
player_y = HEIGHT - 70
player_speed = 5
## Bullet setup
bullets = []
bullet_speed = 7
## Zombie setup
zombies = []
zombie_speed = 2
spawn_rate = 25 # Lower is faster
## Font setup
font = pygame.font.Font(None, 36)
## Load top score from file
def load_top_score():
try:
with open("top_score.txt", "r") as file:
return int(file.read().strip())
except (FileNotFoundError, ValueError):
return 0
def save_top_score(score):
with open("top_score.txt", "w") as file:
file.write(str(score))
top_score = load_top_score()
## Game loop
running = True
game_over = False
clock = pygame.time.Clock()
score = 0
def reset_game():
global player_x, player_y, bullets, zombies, score, game_over
player_x = WIDTH // 2
player_y = HEIGHT - 70
bullets = []
zombies = []
score = 0
game_over = False
while running:
screen.fill(BLACK)
if not game_over:
## Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullets.append([player_x + player_size // 2, player_y])
## Player movement
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player_x > 0:
player_x -= player_speed
if keys[pygame.K_RIGHT] and player_x < WIDTH - player_size:
player_x += player_speed
## Bullet movement
for bullet in bullets[:]:
bullet[1] -= bullet_speed
if bullet[1] < 0:
bullets.remove(bullet)
## Spawn zombies
if random.randint(1, spawn_rate) == 1:
zombies.append([random.randint(0, WIDTH - player_size), 0])
## Zombie movement
for zombie in zombies[:]:
zombie[1] += zombie_speed
if zombie[1] > HEIGHT:
game_over = True # Game over if a zombie reaches bottom
## Collision detection
for bullet in bullets[:]:
for zombie in zombies[:]:
if zombie[0] < bullet[0] < zombie[0] + player_size and \
zombie[1] < bullet[1] < zombie[1] + player_size:
zombies.remove(zombie)
bullets.remove(bullet)
score += 1
## Draw elements
screen.blit(player_img, (player_x, player_y))
for bullet in bullets:
pygame.draw.rect(screen, RED, (bullet[0], bullet[1], 5, 10))
for zombie in zombies:
screen.blit(zombie_img, (zombie[0], zombie[1]))
## Update and display score
if score > top_score:
top_score = score
save_top_score(top_score)
top_score_text = font.render(f"Top Score: {top_score}", True, RED)
screen.blit(top_score_text, (WIDTH - 200, 10))
score_text = font.render(f"Score: {score}", True, GREEN)
screen.blit(score_text, (WIDTH - 200, 40))
else:
## Game over screen
game_over_text = font.render("Game Over! Your score: " + str(score), True, WHITE)
screen.blit(game_over_text, (WIDTH // 2 - 150, HEIGHT // 2 - 50))
restart_text = font.render("Press R to Restart", True, WHITE)
screen.blit(restart_text, (WIDTH // 2 - 100, HEIGHT // 2 + 10))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
reset_game()
pygame.display.flip()
clock.tick(30)
pygame.quit()
Website: https://www.pyshine.com Author: PyShine