Building a Snake Game in Python with Pygame
Python’s simplicity and versatility make it an excellent choice for game development. In this tutorial, we’ll create a classic Snake game using the Pygame library. Let’s dive into the step-by-step process.
Step 1: Setting Up the Environment
Before we begin, ensure you have Pygame installed. You can install it via pip:
pip install pygame
Step 2: Initializing Pygame and the Game Window
We start by initializing Pygame and setting up the game window with the desired dimensions.
import pygame
import random
import sys
# Constants for the game
WIDTH = 800
HEIGHT = 600
SPEED = 10
BLOCK_SIZE = 20
# Define some colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
class SnakeGame:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Snake Game")
self.clock = pygame.time.Clock()
Step 3: Initializing Snake and Food
We initialize the snake and food positions. The snake is represented as a list of (x, y) tuples, and the food position is randomly generated within the game window.
class SnakeGame:
def __init__(self):
# Previous initialization code...
# Initialize the snake and food
self.snake = [(200, 200), (190, 200), (180, 200)]
self.food = (random.randint(0, WIDTH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE,
random.randint(0, HEIGHT - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE)
self.direction = 'right'
self.score = 0
Step 4: Handling User Input
We capture user input to change the snake’s direction.
class SnakeGame:
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and self.direction != 'down':
self.direction = 'up'
elif event.key == pygame.K_DOWN and self.direction != 'up':
self.direction = 'down'
elif event.key == pygame.K_LEFT and self.direction != 'right':
self.direction = 'left'
elif event.key == pygame.K_RIGHT and self.direction != 'left':
self.direction = 'right'
Step 5: Updating Snake Position and Checking for Collisions
We update the snake’s position based on its direction and check for collisions with the game boundaries and itself.
class SnakeGame:
def run(self):
while True:
# Previous code...
# Move the snake
head = self.snake[0]
if self.direction == 'right':
new_head = (head[0] + BLOCK_SIZE, head[1])
elif self.direction == 'left':
new_head = (head[0] - BLOCK_SIZE, head[1])
elif self.direction == 'up':
new_head = (head[0], head[1] - BLOCK_SIZE)
elif self.direction == 'down':
new_head = (head[0], head[1] + BLOCK_SIZE)
if new_head in self.snake or new_head[0] < 0 or new_head[0] >= WIDTH or new_head[1] < 0 or new_head[1] >= HEIGHT:
print('Game Over!')
pygame.quit()
sys.exit()
if new_head == self.food:
self.score += 1
self.food = (random.randint(0, WIDTH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE,
random.randint(0, HEIGHT - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE)
else:
self.snake.insert(0, new_head)
if len(self.snake) > self.score + 1:
self.snake.pop()
Step 6: Drawing Graphics
We draw the snake, food, and game score on the screen.
class SnakeGame:
def run(self):
while True:
# Previous code...
# Draw everything
self.screen.fill(BLACK)
for x, y in self.snake:
pygame.draw.rect(self.screen, WHITE, (x, y, BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(self.screen, RED, (*self.food, BLOCK_SIZE, BLOCK_SIZE))
font = pygame.font.Font(None, 36)
text = font.render("Score: " + str(self.score), True, WHITE)
self.screen.blit(text, (10, 10))
# Update the display
pygame.display.flip()
self.clock.tick(SPEED)
Step 7: Running the Game
Finally, we create an instance of the SnakeGame
class and run the game.
if __name__ == "__main__":
game = SnakeGame()
game.run()
Conclusion
Congratulations! You’ve successfully built a Snake game in Python using Pygame. This project demonstrates fundamental game development concepts, including handling user input, updating game state, and rendering graphics. Feel free to enhance the game further by adding features like sound effects, high scores, or additional levels. Happy coding!
Complete Code Snippet
import pygame
import random
import sys
# Define some constants
WIDTH = 800
HEIGHT = 600
SPEED = 10
BLOCK_SIZE = 20
# Define some colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
class SnakeGame:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Snake Game")
self.clock = pygame.time.Clock()
# Initialize the snake and food
self.snake = [(200, 200), (190, 200), (180, 200)]
self.food = (random.randint(0, WIDTH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE,
random.randint(0, HEIGHT - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE)
self.direction = 'right'
self.score = 0
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and self.direction != 'down':
self.direction = 'up'
elif event.key == pygame.K_DOWN and self.direction != 'up':
self.direction = 'down'
elif event.key == pygame.K_LEFT and self.direction != 'right':
self.direction = 'left'
elif event.key == pygame.K_RIGHT and self.direction != 'left':
self.direction = 'right'
# Move the snake
head = self.snake[0]
if self.direction == 'right':
new_head = (head[0] + BLOCK_SIZE, head[1])
elif self.direction == 'left':
new_head = (head[0] - BLOCK_SIZE, head[1])
elif self.direction == 'up':
new_head = (head[0], head[1] - BLOCK_SIZE)
elif self.direction == 'down':
new_head = (head[0], head[1] + BLOCK_SIZE)
if new_head in self.snake or new_head[0] < 0 or new_head[0] >= WIDTH or new_head[1] < 0 or new_head[1] >= HEIGHT:
print('Game Over!')
pygame.quit()
sys.exit()
if new_head == self.food:
self.score += 1
self.food = (random.randint(0, WIDTH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE,
random.randint(0, HEIGHT - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE)
else:
self.snake.insert(0, new_head)
if len(self.snake) > self.score + 1:
self.snake.pop()
# Draw everything
self.screen.fill(BLACK)
for x, y in self.snake:
pygame.draw.rect(self.screen, WHITE,
(x, y, BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(self.screen, RED,
(*self.food, BLOCK_SIZE, BLOCK_SIZE))
font = pygame.font.Font(None, 36)
text = font.render("Score: " + str(self.score), True, WHITE)
self.screen.blit(text, (10, 10))
# Update the display
pygame.display.flip()
self.clock.tick(SPEED)
def main(self):
self.run()
if __name__ == "__main__":
game = SnakeGame()
game.main()