Как сделать игру «Змейка» на Python
Помните аркадную игру «Змейка», в которую когда-то играли на неубиваемой нокии? Оказывается, что написать классическую «змейку» сможет каждый новичок. О том, как сделать змейку на Python и накормить ее яблоками, расскажет Настя Мартынова — веб-писатель REG.RU.
Змейка (Snake) — это игра, созданная Танели Арманто в 1997 году специально для телефона Nokia. Змейка стала переломным моментом в развитии мобильного гейминга и завоевала сердца миллионов людей. Несмотря на свою примитивность, даже спустя 25 лет эта игра остается популярной.
Хоть Танели Арманто и считается создателем змейки, идея игры ему не принадлежит. Первый вариант змейки появился аж в 1976 году и назывался Blockade. После были созданы десятки клонов этой игры с разными названиями. Арманто при создании игры вдохновился одним из таких клонов, который был установлен на его Apple Macintosh. А мы вдохновились Танели Арманто и решили рассказать, как сделать игру змейка самостоятельно! С этим справятся даже те, кто только недавно начал изучать программирование.
Для создания змейки можно использовать разные языки программирования. Мы будем использовать… питон 🐍! Язык программирования Python универсален: он подходит как для решения повседневных задач, так и для создания простых игр.
Змейку на Python можно написать несколькими способами. Первый — при помощи библиотеки Python PyGame, которую используют для создания игр. Второй — с помощью встроенной библиотеки Turtle. В статье мы опишем второй способ.
Помимо Turtle, мы будем использовать два других модуля:
- Time — для добавления задержки в выполнении программы.
- Random — для генерации случайного числа/цвета/формы.
Какие инструменты нам понадобятся:
- редактор исходного кода на ваш выбор. Можно воспользоваться редактором VSCode или средой разработки PyCharm;
- установленный Python 3.
Как работает игра «Змейка»
Игрок управляет змейкой при помощи кнопок направления — вверх, вниз, влево, вправо. Ползая, змейка должна собирать еду, за которую начисляются очки. Цель игры — набрать как можно больше очков. Игра заканчивается, если змейка врезается в стену или в себя.
Для написания игры мы проделаем следующие шаги:
- импортируем модули в программу,
- создадим экран игры с помощью модуля Turtle,
- зададим кнопки направления движения змеи,
- реализуем игровой процесс.
Прежде всего создайте файл snakegame.py в вашем редакторе кода. А затем приступайте к созданию змейки по нашей инструкции. 👇
Импортируем модули
В этой части кода мы импортируем 3 модуля — turtle, time и random. Помимо этого, мы зададим значения по умолчанию:
- начальный счет — score,
- наибольший счет — high score,
- время задержки — delay.
Добавим в Python строки кода:
1 2 3 4 5 6 7 |
import turtle import time import random score = 0 high_score = 0 delay = 0.1 |
Создаем экран игры
Теперь создадим экран игры — укажем размер экрана, цвет фона и название программы. В функции wind.tracer установим значение задержки обновления экрана.
1 2 3 4 5 6 7 8 |
# Creating a window screen wind = turtle.Screen() wind.title("Snake Maze") wind.bgcolor("green") # the width and height can be put as user's choice wind.setup(width=600, height=600) wind.tracer(0) |
После создадим змею. Метод penup() тут нужен для того, чтоб змейка не рисовала линию при движении, а goto(x,y) задает координаты, которые перемещают змею в абсолютное положение.
1 2 3 4 5 6 7 |
# head of the snake head = turtle.Turtle() head.shape("square") head.color("white") head.penup() head.goto(0, 0) head.direction = "Stop" |
Также добавим еду и счетчик, который будет отображать текущий и рекордный счет.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# food in the game food = turtle.Turtle() colors = random.choice(['red', 'green', 'black']) shapes = random.choice(['square', 'triangle', 'circle']) food.speed(0) food.shape(shapes) food.color(colors) food.penup() food.goto(0, 100) pen = turtle.Turtle() pen.speed(0) pen.shape("square") pen.color("white") pen.penup() pen.hideturtle() pen.goto(0, 250) pen.write("Score : 0 High Score : 0", align="center", font=("Arial", 24, "bold")) |
Если запустить программу сейчас, то окно будет выглядеть так:
Задаем кнопки направления движения змеи
Тут мы зададим клавиши направления, при нажатии на которые змейка будет двигаться. В нашем случае кнопки будут следующими: «W» — вверх, «A» — влево, «S» — вниз, «D» — вправо.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# assigning key directions def group(): if head.direction != "dowind": head.direction = "up" def godowind(): if head.direction != "up": head.direction = "dowind" def goleft(): if head.direction != "right": head.direction = "left" def goright(): if head.direction != "left": head.direction = "right" def move(): if head.direction == "up": y = head.ycor() head.sety(y+20) if head.direction == "dowind": y = head.ycor() head.sety(y-20) if head.direction == "left": x = head.xcor() head.setx(x-20) if head.direction == "right": x = head.xcor() head.setx(x+20) wind.listen() wind.onkeypress(group, "w") wind.onkeypress(godowind, "s") wind.onkeypress(goleft, "a") wind.onkeypress(goright, "d") |
Реализуем игровой процесс
Теперь нам нужно реализовать геймплей. Он включает в себя следующие пункты:
- Длина змейки увеличивается каждый раз, когда она собирает еду. При этом хвост и голова змейки должны отличаться по цвету.
- Счет увеличивается каждый раз, когда змея подбирает еду. Наибольший результат записывается.
- Должна быть добавлена проверка на столкновение головы змейки с телом или стеной.
- Цвет и форма еды должны меняться при каждом перезапуске игры.
- Игра начинается заново, если змея столкнулась с собой или стеной.
- В случае столкновения счетчик обнуляется, наибольший результат сохраняется до перезапуска.
Добавим оставшуюся часть нашего Python-кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
segments = [] # Main Gameplay while True: wind.update() if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290: time.sleep(1) head.goto(0, 0) head.direction = "Stop" colors = random.choice(['red', 'blue', 'green']) shapes = random.choice(['square', 'circle']) for segment in segments: segment.goto(1000, 1000) segments.clear() score = 0 delay = 0.1 pen.clear() pen.write("Score : {} High Score : {} ".format( score, high_score), align="center", font=("Arial", 24, "bold")) if head.distance(food) < 20: x = random.randint(-270, 270) y = random.randint(-270, 270) food.goto(x, y) # Adding segment new_segment = turtle.Turtle() new_segment.speed(0) new_segment.shape("square") new_segment.color("orange") # tail colour new_segment.penup() segments.append(new_segment) delay -= 0.001 score += 10 if score > high_score: high_score = score pen.clear() pen.write("Score : {} High Score : {} ".format( score, high_score), align="center", font=("Arial", 24, "bold")) # Checking for head collisions with body segments for index in range(len(segments)-1, 0, -1): x = segments[index-1].xcor() y = segments[index-1].ycor() segments[index].goto(x, y) if len(segments) > 0: x = head.xcor() y = head.ycor() segments[0].goto(x, y) move() for segment in segments: if segment.distance(head) < 20: time.sleep(1) head.goto(0, 0) head.direction = "stop" colors = random.choice(['red', 'blue', 'green']) shapes = random.choice(['square', 'circle']) for segment in segments: segment.goto(1000, 1000) segment.clear() score = 0 delay = 0.1 pen.clear() pen.write("Score : {} High Score : {} ".format( score, high_score), align="center", font=("Arial", 24, "bold")) time.sleep(delay) wind.mainloop() |
Важно добавить функцию wind.mainloop() в конце, иначе окно будет закрываться сразу после запуска.
В этом фрагменте кода мы устанавливаем случайную позицию для еды на экране. Каждый раз, когда змея собирает пищу, ее тело увеличивается. Тело по цвету отличается от головы, в нашем случае оно будет оранжевым.
После того как змея соберет еду, еда появится в случайном месте в пределах 270 координат. Каждый раз, когда змея подбирает еду, счет игрока увеличивается на 10. Когда змея сталкивается с хвостом или стеной, счет игрока обнуляется, на экране сохраняется наибольший счет.
Теперь наша змейка на Python готова.
⌘⌘⌘
Надеемся, вам было весело создавать игру и программировать на Python вместе с нами.
А какой рекорд в змейке поставили вы? Поделитесь в комментариях!