Python
Как сделать Змейку на Python: простая игра на Pygame
«Змейку» на Python удобнее делать через Pygame. В игре есть окно, клеточное поле, змейка, еда, движение по таймеру, управление стрелками и проверка столкновений. Это уже не первая программа на Python, но хороший мини-проект после того, как вы разобрались с условиями, списками и циклами
Сначала установите Pygame:
python -m pip install pygame
На некоторых системах команда будет такой:
python3 -m pip install pygame
Проверить установку можно так:
python -m pygame.examples.aliens
Если открылось демонстрационное окно, Pygame работает
Что будет в нашей версии
Мы сделаем простую змейку: она движется по сетке, ест красную точку, становится длиннее и проигрывает при столкновении со стеной или самой собой. Код будет в одном файле, чтобы начинающему было проще понять общий поток игры
Создайте файл:
snake_game.py
Полный код игры
import random
import pygame
pygame.init()
CELL = 20
WIDTH = 30
HEIGHT = 20
SCREEN_WIDTH = CELL * WIDTH
SCREEN_HEIGHT = CELL * HEIGHT
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Snake на Python")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)
snake = [(5, 5), (4, 5), (3, 5)]
direction = (1, 0)
food = (15, 10)
score = 0
def random_food():
while True:
point = (
random.randint(0, WIDTH - 1),
random.randint(0, HEIGHT - 1),
)
if point not in snake:
return point
def draw_cell(color, point):
x = point[0] * CELL
y = point[1] * CELL
rect = pygame.Rect(x, y, CELL, CELL)
pygame.draw.rect(screen, color, rect)
running = True
game_over = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and not game_over:
if event.key == pygame.K_UP and direction != (0, 1):
direction = (0, -1)
elif event.key == pygame.K_DOWN and direction != (0, -1):
direction = (0, 1)
elif event.key == pygame.K_LEFT and direction != (1, 0):
direction = (-1, 0)
elif event.key == pygame.K_RIGHT and direction != (-1, 0):
direction = (1, 0)
if not game_over:
head_x, head_y = snake[0]
step_x, step_y = direction
new_head = (head_x + step_x, head_y + step_y)
hit_wall = (
new_head[0] < 0
or new_head[0] >= WIDTH
or new_head[1] < 0
or new_head[1] >= HEIGHT
)
hit_self = new_head in snake
if hit_wall or hit_self:
game_over = True
else:
snake.insert(0, new_head)
if new_head == food:
score += 1
food = random_food()
else:
snake.pop()
screen.fill((20, 24, 32))
for part in snake:
draw_cell((80, 220, 120), part)
draw_cell((240, 80, 80), food)
score_text = font.render(f"Score: {score}", True, (240, 240, 240))
screen.blit(score_text, (10, 10))
if game_over:
text = font.render("Game over", True, (255, 220, 120))
screen.blit(text, (SCREEN_WIDTH // 2 - 80, SCREEN_HEIGHT // 2 - 20))
pygame.display.flip()
clock.tick(10)
pygame.quit()
Запуск:
python snake_game.py
или:
python3 snake_game.py
Как устроено поле
Игра работает не в пикселях напрямую, а в клетках. Размер одной клетки хранится в переменной CELL
CELL = 20
WIDTH = 30
HEIGHT = 20
Это значит, что поле состоит из 30 клеток по ширине и 20 клеток по высоте. Реальный размер окна считается умножением:
SCREEN_WIDTH = CELL * WIDTH
SCREEN_HEIGHT = CELL * HEIGHT
Так проще управлять змейкой. Она не двигается на 1 пиксель, а переходит из клетки в клетку
Как хранится змейка
Змейка — это список координат:
snake = [(5, 5), (4, 5), (3, 5)]
Первый элемент списка — голова. Остальные элементы — тело. Когда змейка двигается, мы добавляем новую голову в начало списка:
snake.insert(0, new_head)
Если еда не съедена, удаляем хвост:
snake.pop()
Так длина остается прежней, а змейка как будто передвинулась вперед
Как работает управление
Pygame отправляет события клавиатуры. Мы проверяем, была ли нажата клавиша:
if event.type == pygame.KEYDOWN:
Затем смотрим, какая именно:
if event.key == pygame.K_UP:
Направление хранится как пара чисел. Например, (1, 0) означает движение вправо, (-1, 0) влево, (0, -1) вверх, (0, 1) вниз
В коде есть проверка, чтобы змейка не могла резко развернуться в противоположную сторону и сразу врезаться в себя
Как появляется еда
Функция random_food() выбирает случайную клетку:
point = (
random.randint(0, WIDTH - 1),
random.randint(0, HEIGHT - 1),
)
Потом проверяет, что эта клетка не занята змейкой:
if point not in snake:
return point
Это нужно, чтобы еда не появлялась прямо внутри тела
Как проверяются проигрыш и столкновения
Столкновение со стеной проверяется по координатам головы:
new_head[0] < 0
new_head[0] >= WIDTH
new_head[1] < 0
new_head[1] >= HEIGHT
Столкновение с собой проверяется проще:
hit_self = new_head in snake
Если случилось любое столкновение, переменная game_over становится True, и игра перестает двигать змейку
Мини-практика
Сначала измените скорость игры:
clock.tick(10)
Поставьте 5, затем 15 и посмотрите, как меняется сложность. Потом измените размеры поля WIDTH и HEIGHT, чтобы сделать игру шире или компактнее
После этого добавьте перезапуск по клавише R. Это уже маленькая архитектурная задача: нужно вынести начальные значения змейки, еды и счета в функцию reset_game()
Частые ошибки
Первая ошибка — не установить Pygame перед запуском. Если видите ModuleNotFoundError: No module named 'pygame', выполните python -m pip install pygame
Вторая ошибка — назвать файл pygame.py. Тогда Python может попытаться импортировать ваш файл вместо библиотеки Pygame
Третья ошибка — забыть pygame.display.flip(). Без обновления экрана изменения могут не отображаться
Четвертая ошибка — двигать змейку в пикселях, а столкновения проверять в клетках. Лучше сразу выбрать одну систему координат, для «Змейки» удобнее клеточная
Что почитать дальше по Python
Если нужен общий маршрут по теме, откройте рубрику Python. Для соседних задач пригодятся эти разборы:
- Как сделать игру на Python: первая консольная игра «Угадай число»
- Как сделать калькулятор на Питоне: простой код для начинающих
- Как сделать многострочный комментарий в Питоне: решетка, тройные кавычки и docstring
- Как из списка сделать строку в Python: join, map и частые ошибки