Загрузка данных
import random
import pygame
import sys
# Инициализация Pygame
pygame.init()
# Константы
FPS = 10
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 600
CELL_SIZE = 10
# Цвета (RGB)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARK_GREEN = (0, 150, 0)
class Snake():
def __init__(self, snake_color):
# Важные переменные - позиция головы змеи и его тела
self.snake_head_pos = [100, 50] # [x, y]
# начальное тело змеи состоит из трех сегментов
# голова змеи - первый элемент, хвост - последний
self.snake_body = [[100, 50], [90, 50], [80, 50]]
self.snake_color = snake_color
# направления движения змеи, изначально зададимся вправо
self.direction = "RIGHT"
# куда будет меняться направление движения змеи при нажатии соответствующих клавиш
self.change_to = self.direction
def validate_direction_and_change(self):
"""Изменим направление движения змеи только в том случае,
если оно не прямо противоположно текущему"""
if self.change_to == "RIGHT" and not self.direction == "LEFT":
self.direction = self.change_to
elif self.change_to == "LEFT" and not self.direction == "RIGHT":
self.direction = self.change_to
elif self.change_to == "UP" and not self.direction == "DOWN":
self.direction = self.change_to
elif self.change_to == "DOWN" and not self.direction == "UP":
self.direction = self.change_to
def change_head_position(self):
"""Изменим положение головы змеи"""
if self.direction == "RIGHT":
self.snake_head_pos[0] += CELL_SIZE
elif self.direction == "LEFT":
self.snake_head_pos[0] -= CELL_SIZE
elif self.direction == "UP":
self.snake_head_pos[1] -= CELL_SIZE # Исправлено: было [0] -= 10
elif self.direction == "DOWN":
self.snake_head_pos[1] += CELL_SIZE
def snake_body_mechanism(self, score, food_pos, screen_width, screen_height):
# Вставляем новую голову (копируем, чтобы не было ссылки)
self.snake_body.insert(0, list(self.snake_head_pos))
# если съели еду
if (self.snake_head_pos[0] == food_pos[0] and
self.snake_head_pos[1] == food_pos[1]):
# задаем новое положение еды случайным образом
food_pos = [random.randint(0, (screen_width - CELL_SIZE) // CELL_SIZE) * CELL_SIZE,
random.randint(0, (screen_height - CELL_SIZE) // CELL_SIZE) * CELL_SIZE]
score += 1
else:
# если не нашли еду, то убираем последний сегмент
self.snake_body.pop()
return score, food_pos
def draw_snake(self, play_surface, surface_color):
"""Отображаем все сегменты змеи"""
for segment in self.snake_body:
pygame.draw.rect(play_surface, self.snake_color,
(segment[0], segment[1], CELL_SIZE, CELL_SIZE))
# Добавляем небольшую обводку для красоты
pygame.draw.rect(play_surface, surface_color,
(segment[0], segment[1], CELL_SIZE, CELL_SIZE), 1)
def check_collision(self, screen_width, screen_height):
# Столкновение со стенами
if (self.snake_head_pos[0] < 0 or
self.snake_head_pos[0] >= screen_width or
self.snake_head_pos[1] < 0 or
self.snake_head_pos[1] >= screen_height):
return True
# Столкновение с самим собой (проверяем, не врезалась ли голова в тело)
for segment in self.snake_body[1:]:
if self.snake_head_pos[0] == segment[0] and self.snake_head_pos[1] == segment[1]:
return True
return False
def reset(self):
"""Сброс змеи до начального состояния"""
self.snake_head_pos = [100, 50]
self.snake_body = [[100, 50], [90, 50], [80, 50]]
self.direction = "RIGHT"
self.change_to = self.direction
def show_game_over(screen, score):
"""Отображение экрана Game Over"""
font = pygame.font.Font(None, 72)
font_small = pygame.font.Font(None, 36)
game_over_text = font.render("GAME OVER", True, RED)
score_text = font_small.render(f"Счёт: {score}", True, WHITE)
restart_text = font_small.render("Нажмите SPACE чтобы сыграть снова или ESC для выхода", True, WHITE)
screen.fill(BLACK)
screen.blit(game_over_text, (WINDOW_WIDTH // 2 - game_over_text.get_width() // 2,
WINDOW_HEIGHT // 2 - 100))
screen.blit(score_text, (WINDOW_WIDTH // 2 - score_text.get_width() // 2,
WINDOW_HEIGHT // 2 - 20))
screen.blit(restart_text, (WINDOW_WIDTH // 2 - restart_text.get_width() // 2,
WINDOW_HEIGHT // 2 + 40))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
return True # Перезапуск
if event.key == pygame.K_ESCAPE:
return False # Выход
def main():
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Змейка")
clock = pygame.time.Clock()
# Основной игровой цикл (с возможностью перезапуска)
running = True
while running:
# Инициализация игры
snake = Snake(DARK_GREEN)
# Позиция еды
food_pos = [random.randint(0, (WINDOW_WIDTH - CELL_SIZE) // CELL_SIZE) * CELL_SIZE,
random.randint(0, (WINDOW_HEIGHT - CELL_SIZE) // CELL_SIZE) * CELL_SIZE]
score = 0
game_loop = True
while game_loop:
# Обработка событий
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT or event.key == ord('d'):
snake.change_to = "RIGHT"
elif event.key == pygame.K_LEFT or event.key == ord('a'):
snake.change_to = "LEFT"
elif event.key == pygame.K_UP or event.key == ord('w'):
snake.change_to = "UP"
elif event.key == pygame.K_DOWN or event.key == ord('s'):
snake.change_to = "DOWN"
elif event.key == pygame.K_ESCAPE:
game_loop = False
running = False
# Проверка и применение направления
snake.validate_direction_and_change()
snake.change_head_position()
# Проверка столкновений
if snake.check_collision(WINDOW_WIDTH, WINDOW_HEIGHT):
game_loop = False
continue
# Обновление тела змеи и проверка поедания еды
score, food_pos = snake.snake_body_mechanism(score, food_pos, WINDOW_WIDTH, WINDOW_HEIGHT)
# Отрисовка
screen.fill(BLACK)
# Рисуем еду (красный квадрат)
pygame.draw.rect(screen, RED,
(food_pos[0], food_pos[1], CELL_SIZE, CELL_SIZE))
# Рисуем змею
snake.draw_snake(screen, WHITE)
# Отображение счёта
font = pygame.font.Font(None, 36)
score_text = font.render(f"Счёт: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
pygame.display.update()
clock.tick(FPS)
# Если игра закончена, показываем экран Game Over
if not running:
break
# Показываем Game Over и спрашиваем о перезапуске
if not show_game_over(screen, score):
running = False
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()