рвы
ры

Рис.
Файлы с картинками поместите в папку images
import warnings
warnings.filterwarnings("ignore", category=RuntimeWarning, message=".*AVX2.*")
import pgzrun
from random import randint
CELL_SIZE = 22 # Размер сегмента змейки в пикселях
MIN_SEGMENTS = 4 # Количество сегментов змейки в начале игры
WIDTH = CELL_SIZE * 30 # Ширина окна в пикселях
HEIGHT = CELL_SIZE * 20 # Высота окна в пикселях
LEFT = TOP = CELL_SIZE // 2 # Левая и верхняя границы игрового поля
RIGHT = WIDTH - CELL_SIZE // 2 # Правая граница игрового поля
BOTTOM = HEIGHT - CELL_SIZE // 2 # Нижняя граница игрового поля
BACKGROUND_COLOR = "#9ead86" # Цвет фона
game_over = False # Признак конца игры
vx = 1 # Горизонтальная скорость движения змейки
vy = 0 # Вертикальная скорость движения змейки
Rp = Actor("raspberry") # Еда малинка(файл в папке images/raspberry.png)
snake = [Actor("segment")] # Список сегментов змейки
XY = [(WIDTH//2, HEIGHT//2)] # Список траекторий движения всех сегментов
snake[0].pos = XY[0] # Сегмент помещаем в центр окна
def bit_his_tail():
"""
Проверяет, не столкнулась ли голова с каким-либо сегментом тела,
начиная с сегмента №2, исключаем шею - сегмент №1.
"""
for n in range(2, len(snake)):
if snake[0].colliderect(snake[n]):
return True # Если было столкновение
return False
def get_vector(vx, vy):
'''
Определяет направление движения, исходя из текущего направления,
а так же, запрещает резкий разворот на 180 градусов.
'''
if vy != 0: # Eсли текущее движение по вертикали
if keyboard.left:
vx = -1
vy = 0
elif keyboard.right:
vx = 1
vy = 0
else: # Eсли текущее движение по горизонтали
if keyboard.up:
vy = -1
vx = 0
elif keyboard.down:
vy = 1
vx = 0
return (vx, vy)
def update(dt):
"""
Особая функция из pgzrun, вызывается каждый кадр.
Здесь обновляется логика игры: поедание, движение, столкновения.
dt – время, прошедшее с предыдущего кадра (не используется).
"""
global game_over, vx, vy, SEGMENTS
if game_over: # Если игра окончена
return
# ===== Поедание еды и рост=====
if snake[0].colliderect(Rp) or len(snake) == 1 or (
len(snake) < MIN_SEGMENTS and not snake[0].colliderect(snake[-1])):
Rp.pos = (randint(LEFT, RIGHT), randint(TOP, BOTTOM)) # Перемещаем еду в случайное место
snake.append(Actor("tetris")) # Добавляем новый сегмент змейки
snake[-1].pos = snake[-2].pos # Новый сегмент помещаем на последний сегмент
for n in range(CELL_SIZE): # Увеличиваем список XY на CELL_SIZE пар координат
XY.append(snake[-2].pos) # Заполняем координатами предпоследнего сегмента
# ===== Движение головы =====
vx, vy = get_vector(vx, vy) # Определить направление движения
snake[0].x += vx # Смещение головы по X
snake[0].y += vy # Смещение головы по Y
# ===== Обновление позиций сегментов тела =====
for i in range(len(XY)-1, 0, -1):
XY[i] = XY[i-1] # Сдвигаем все элементы XY вправо
XY[0] = snake[0].pos # В начало списка записываем текущие координаты головы
for n in range(1, len(snake)):
snake[n].pos = XY[n*CELL_SIZE] # Каждый сегмент получает координаты из списка XY
# ===== Проверка столкновений =====
if (snake[0].y > BOTTOM or snake[0].y < TOP or # выход за верхнюю/нижнюю границу
snake[0].x > RIGHT or snake[0].x < LEFT or # выход за левую/правую границу
bit_his_tail()): # столкновение с сегментом тела
game_over = True
def draw():
"""
Особая функция из pgzrun – отрисовка каждого кадра.
"""
screen.fill(BACKGROUND_COLOR) # Заливка фона цветом
Rp.draw() # Рисуем еду
for n in range(len(snake)-1, -1, -1):
snake[n].draw() # Рисуем сегменты змейки в обратном порядке
if game_over: # Выводим сообщение о проигрыше
screen.draw.text("GAME\nOVER", center=(WIDTH//2, HEIGHT//2),
fontsize=60)
pgzrun.go() # Эта функция из pgzrun запускает главный цикл программы
Лист.

Рис.