Okay, I need to write a snake game in Python using SDL. Let's start by figuring out which Python library uses SDL. I remember that PySDL2 is a wrapper around SDL2, so that's probably the right choice. I'll need to install that first.Write a snake game in python using SDL.
Next, the basic structure of a snake game: there's a snake that moves around, eating food and growing. The game ends when the snake hits the wall or itself. So I'll need to handle the game loop, user input for direction changes, collision detection, and rendering.
I should start by initializing the SDL window and renderer. Then set up the game variables: snake position, direction, food position, and the score. The snake can be represented as a list of segments, each with x and y coordinates. The direction will change based on arrow key presses.
For the game loop, I'll need to process events each frame. Check for key presses to change direction, and also check if the window is closing. Then, update the snake's position by moving the head in the current direction. Each time the snake eats the food, the length increases, and a new food is generated. But I have to make sure the new food doesn't spawn on the snake's body.
Collision detection involves checking if the head hits the walls (outside the screen boundaries) or any part of the body. If a collision occurs, the game ends.
Rendering will involve clearing the screen each frame, drawing the snake segments as rectangles, and the food as another rectangle. Also, displaying the score somewhere, maybe in the window title for simplicity.
Wait, how do I handle the timing? The snake's movement should be at a consistent speed. Maybe using a delay in the loop or tracking time to move at regular intervals. Using SDL's timer functions could help, but perhaps a simple delay in the loop would suffice for a basic implementation.
Testing each part step by step. First, get the window up. Then handle input and moving a block. Then add the food and collision detection. Finally, the growing snake and game over condition.
Possible issues: handling the direction changes properly, making sure the snake doesn't reverse direction into itself. For example, if moving right, can't suddenly go left. Need to restrict direction changes to valid ones.
Also, generating food randomly, but ensuring it's not on the snake. That might require a loop to check all snake segments against the new food position.
Putting it all together, the code structure would be something like:
- Import necessary modules from SDL2.
- Initialize window and renderer.
- Set initial variables (snake, direction, food, score).
- Game loop:
- Process events (key presses).
- Update snake position.
- Check for collisions.
- Draw everything.
- Delay to control game speed.
Let me write the code now, step by step, making sure each part is covered.
I'll help you create a Snake game using Python with the SDL library. We'll use the PySDL2
package, which provides Python bindings for SDL2. Here's the implementation:
import sys
import random
from sdl2 import *
from sdl2.ext import *
# Initialize SDL subsystems
SDL_Init(SDL_INIT_VIDEO)
# Game constants
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
GRID_SIZE = 20
SNAKE_SPEED = 7
# Directions
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)
class Game:
def __init__(self):
self.window = Window("Snake Game", (WINDOW_WIDTH, WINDOW_HEIGHT))
self.renderer = Renderer(self.window)
self.factory = SpriteFactory(sprite_type=SOFTWARE)
self.snake = [(5, 5)]
self.direction = RIGHT
self.food = self.generate_food()
self.score = 0
self.game_over = False
def generate_food(self):
while True:
food = (random.randint(0, (WINDOW_WIDTH//GRID_SIZE)-1),
random.randint(0, (WINDOW_HEIGHT//GRID_SIZE)-1))
if food not in self.snake:
return food
def handle_input(self):
event = SDL_Event()
while SDL_PollEvent(event):
if event.type == SDL_QUIT:
return False
if event.type == SDL_KEYDOWN:
if event.key.keysym.sym == SDLK_UP and self.direction != DOWN:
self.direction = UP
elif event.key.keysym.sym == SDLK_DOWN and self.direction != DOWN:
self.direction = DOWN
elif event.key.keysym.sym == SDLK_LEFT and self.direction != RIGHT:
self.direction = LEFT
elif event.key.keysym.sym == SDLK_RIGHT and self.direction != LEFT:
self.direction = RIGHT
elif event.key.keysym.sym == SDLK_ESCAPE:
return False
return True
def update(self):
if self.game_over:
return
# Move snake
head = self.snake[-1]
new_head = (head[0] + self.direction[0], head[1] + self.direction[1])
# Check collisions
if (new_head[0] < 0 or new_head[0] >= WINDOW_WIDTH//GRID_SIZE or
new_head[1] < 0 or new_head[1] >= WINDOW_HEIGHT//GRID_SIZE or
new_head in self.snake):
self.game_over = True
return
self.snake.append(new_head)
# Check food collision
if new_head == self.food:
self.score += 1
self.food = self.generate_food()
else:
self.snake.pop(0)
def render(self):
self.renderer.clear()
# Draw snake
for segment in self.snake:
x = segment[0] * GRID_SIZE
y = segment[1] * GRID_SIZE
self.factory.create_sprite((x, y, GRID_SIZE, GRID_SIZE), color=(0, 255, 0))
# Draw food
food_rect = (self.food[0] * GRID_SIZE, self.food[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)
self.factory.create_sprite(food_rect, color=(255, 0, 0))
# Update title with score
self.window.set_title(f"Snake Game - Score: {self.score}")
self.renderer.present()
def run(self):
running = True
last_frame = 0
while running:
current_time = SDL_GetTicks()
if current_time - last_frame > 1000 // SNAKE_SPEED:
last_frame = current_time
running = self.handle_input()
self.update()
self.render()
SDL_Quit()
if __name__ == "__main__":
game = Game()
game.run()
To run this game:
-
First install the required packages:
pip install PySDL2
-
Save the code in a file (e.g.,
snake_game.py
) -
Run the file using Python
How to play:
- Use arrow keys to control the snake
- Eat the red food to grow and score points
- Avoid hitting walls or yourself
- Press ESC to quit
- Score is displayed in window title
Game features:
- Grid-based movement
- Simple collision detection
- Score tracking
- Food generation avoiding snake body
- Basic game over detection
The game uses SDL2 for rendering and input handling. The snake moves at a constant speed, and the game features simple collision detection with walls and self-intersection.
For a more complete implementation, you could add:
- Game over screen
- Restart functionality
- Sound effects
- Increasing difficulty levels
- Better food spawning algorithm
- Persistent high scores
llama_perf_sampler_print: sampling time = 154.48 ms / 1785 runs ( 0.09 ms per token, 11554.67 tokens per second) llama_perf_context_print: load time = 338110.94 ms llama_perf_context_print: prompt eval time = 18095.48 ms / 20 tokens ( 904.77 ms per token, 1.11 tokens per second) llama_perf_context_print: eval time = 528966.73 ms / 1771 runs ( 298.68 ms per token, 3.35 tokens per second) llama_perf_context_print: total time = 550260.88 ms / 1791 tokens
With
-t 0.6 --min_p 0.05
we get a working snake game