Creating a Simple Snake Game in Python with Pygame
Introduction
In this tutorial, we will build a classic Snake game using Python and the Pygame library. The game involves controlling a snake to eat food and grow longer, while avoiding collisions with itself and the boundaries of the game screen.
Prerequisites
Before getting started, ensure you have Python installed on your computer along with the Pygame library. You can install Pygame using pip:
pip install pygame
Step-by-Step Guide
Setting up the Environment
Begin by importing the necessary modules and initializing Pygame:
import pygame
import sys
import random
pygame.init()
# Constants
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400
GRID_SIZE = 20
GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# Create the screen
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')
# Clock to control the game speed
clock = pygame.time.Clock()
Defining the Snake and Food Classes
Define the Snake and Food classes along with helper functions for game logic:
class Snake:
def __init__(self):
self.body = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]
self.direction = (1, 0) # Initial direction: right
def move(self, food):
# Move the snake based on its current direction
head_x, head_y = self.body[0]
dx, dy = self.direction
new_head = ((head_x + dx) % GRID_WIDTH, (head_y + dy) % GRID_HEIGHT)
# Check for collisions with itself or boundaries
if new_head in self.body[1:] or new_head[0] < 0 or new_head[0] >= GRID_WIDTH or new_head[1] < 0 or new_head[1] >= GRID_HEIGHT:
return False
# Insert new head position and check for food collision
self.body.insert(0, new_head)
if new_head == food.position:
food.spawn() # Respawn food at a new position
else:
self.body.pop() # Remove the tail segment if no food eaten
return True
def draw(self):
# Draw the snake on the screen
for segment in self.body:
pygame.draw.rect(screen, GREEN, (segment[0] * GRID_SIZE, segment[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE))
def change_direction(self, direction):
# Change the snake's direction, ensuring it doesn't reverse
if (direction[0] * -1, direction[1] * -1) != self.direction:
self.direction = direction
class Food:
def __init__(self):
# Initialize food at a random position within the grid
self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
def spawn(self):
# Respawn food at a new random position within the grid
self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
def draw(self):
# Draw the food on the screen
pygame.draw.rect(screen, RED, (self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE))
Game Loop and Event Handling
Implement the main game loop and handle events such as key presses for changing the snake's direction:
def main():
snake = Snake()
food = Food()
running = True
while running:
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:
snake.change_direction((0, -1)) # Move snake up
elif event.key == pygame.K_DOWN:
snake.change_direction((0, 1)) # Move snake down
elif event.key == pygame.K_LEFT:
snake.change_direction((-1, 0)) # Move snake left
elif event.key == pygame.K_RIGHT:
snake.change_direction((1, 0)) # Move snake right
screen.fill(WHITE) # Clear the screen with white
draw_grid() # Draw grid lines
snake_move_result = snake.move(food) # Move snake and handle collisions
if not snake_move_result:
running = False # End game if snake collides
snake.draw() # Draw the snake on the screen
food.draw() # Draw the food on the screen
pygame.display.flip() # Update the display
clock.tick(10) # Control the game speed
pygame.quit() # Quit Pygame
sys.exit() # Exit the program
if __name__ == '__main__':
main()
Explanation
Initialization: Set up the Pygame environment, define constants, and create the game screen.
Snake and Food Classes: Define the Snake and Food classes with methods for movement, drawing, and collision handling.
Game Loop: Implement the main loop where user input is processed, the game state is updated (snake movement and food spawning), and the screen is refreshed.
Event Handling: Manage events such as key presses to change the snake's direction.
Drawing: Use Pygame's drawing functions to visually represent the snake and food on the screen.
Conclusion
You’ve now successfully created a simple Snake game in Python using Pygame! This tutorial covered essential aspects such as game initialization, class design for game objects, event handling, and drawing on the screen. Feel free to expand this game by adding features like score tracking, increasing difficulty levels, or implementing more complex game mechanics. Enjoy coding and exploring the world of game development with Python!
Subscribe to my newsletter
Read articles from Adriel Vinuya directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Adriel Vinuya
Adriel Vinuya
I specialize in technical writing with a focus on Python programming and game development using Pygame. My work primarily involves creating clear and concise guides, tutorials, and documentation that help beginners and enthusiasts alike learn and explore Python's capabilities in game development. With a passion for coding and a knack for explaining complex concepts in a straightforward manner, I enjoy empowering others to dive into the exciting world of game development using Python and Pygame.