Игра Змейка: зелёный фон, счёт 32, чёрная змейка, красная точка-еда.

Реализация игры «Змейка» на Python

Простое пошаговое руководство по созданию игры «Змейка» с нуля.

Делиться

ea5c9066669e25b6cd5b557982ec687f

Мои воспоминания о первом мобильном телефоне моей мамы тесно связаны с игрой, которая в нём была. Да, классическая игра в «Змейку», такая простая, но такая затягивающая. Я помню, как играла в эту игру на мамином телефоне, проигрывала, а потом пыталась снова и снова!

В этой статье мы научимся создавать простую игру «Змейка». Для генерации игры мы будем использовать модуль turtle из Python. Обратите внимание, что это руководство по Python для начинающих и пользователей среднего уровня, и предполагается, что читатель знаком с основами Python, такими как функции и циклы, импорт и доступ к модулям, а также использование условных операторов. Также требуется поверхностное понимание объектно-ориентированного программирования, особенно создания экземпляров объектов из классов. Для простоты я объясню каждую строку кода. Давайте начнём!

f2ee1e41c633cc3c4206c03f196feaee

Понимание игры

Классическая игра «Змейка» включает в себя маленькую змейку на простом фоне. На экране отображается еда. По мере того, как змейка съедает еду, она увеличивается в размерах, и счет растет. Как только змейка сталкивается с ограждением или с самой собой, игра заканчивается, и игрок проигрывает.

Для написания этой игры на Python нам необходимо учесть следующие моменты:

  1. Настройка игрового экрана – в классической игре «Змейка» фон представляет собой тусклый неоново-желто-зеленый экран.
  2. Создание тела змеи – игра начинается с маленькой черной змеи, которая постепенно увеличивается в размерах по мере поедания пищи.
  3. Управление змеей: змея может двигаться в 4 направлениях: вверх, вниз, влево и вправо, используя клавиши со стрелками на клавиатуре или соответствующие кнопки на телефоне.
  4. Создание корма – корм для змеи появляется в случайных местах на экране.
  5. Змея поедает еду – при столкновении тела змеи с созданной едой, счет увеличивается, а длина змеи возрастает, при этом случайным образом генерируется новая еда, и игра продолжается.
  6. Столкновение змеи самой с собой или с границей игрового экрана – если тело змеи сталкивается само с собой или с границей игрового экрана, игра заканчивается.

Давайте начнём программировать.

Настройка игрового экрана

Для начала создадим новый проект в нашей IDE, назовём его «Игра в змейку». Я использую PyCharm для написания кода. Затем создадим новый файл «snake game.py». Прежде всего, импортируем модуль Turtle, а именно его классы Screen и Turtle.

from turtle import Screen, Turtle

Модуль Turtle — это встроенный пакет Python, позволяющий рисовать фигуры, линии, узоры и создавать анимацию на экране с помощью кода. Модуль работает так, как если бы у черепахи была кисть на спине, и она бы двигалась в нужном направлении, создавая тем самым рисунки. Вы можете попросить черепаху двигаться вперед, повернуть налево на определенный угол, нарисовать круг и т. д. Черепаха нарисует именно это, и это простой инструмент для визуализации кода. Он помогает практиковаться в работе с переменными, циклами, функциями, координатами и базовой логикой анимации с мгновенным визуальным результатом.

Официальную документацию по Turtle можно посмотреть здесь.

Как видно из приведенной выше строки кода, мы импортировали два элемента: Screen и Turtle. Это классы, определенные в модуле. В Python класс — это шаблон, используемый для создания объектов. Turtle и Screen — это классы, которые будут использоваться для создания соответствующих объектов. Эти объекты будут иметь атрибуты (переменные) и методы (функции), определенные в их шаблоне, с возможностью настройки.

Давайте сначала создадим фон для нашей игры. Для этого мы будем использовать класс Screen и настроим его в соответствии с нашими требованиями. Для справки, ознакомьтесь с методами Screen в официальной документации здесь.

#Настройка игрового экрана screen = Screen() screen.setup(width=600, height=600) screen.bgcolor(«green yellow») screen.title(«Snake Game») screen.tracer(0) screen.exitonclick()

Как видно из приведенного выше кода, сначала мы создали объект экрана из класса Screen. Затем мы использовали метод setup() класса Screen и установили ширину игрового экрана 600×600. Мы настроили цвет фона на «зелено-желтый» с помощью метода bgcolor(). Название цвета можно найти по этой ссылке. Я выбрал цвет, наиболее близкий к цвету в оригинальной игре. После этого мы назвали экран «Игра в змею» с помощью метода title(). Метод tracer() класса Turtle позволяет нам управлять анимацией. Передав аргумент «0», мы отключили ее. Это станет понятнее, когда мы создадим змею и еду. Наконец, мы использовали метод exitonclick(), чтобы окно закрывалось только при щелчке по нему. В противном случае окно закрывается сразу после появления и выполнения всего кода.

При выполнении приведенного выше кода будет получен следующий результат:

6611fcde99e9347a14eed3a1031193da

Создание тела змеи

После создания игрового экрана следующая задача — создать змею. Змея также будет создана с использованием класса Turtle. Мы создадим 3 объекта черепахи, которые совсем не будут похожи на черепаху. Скорее, это будут квадратные сегменты, которые, будучи сложенными вместе, будут напоминать тело змеи, как в игре. Для этого мы будем использовать цикл for для создания 3 сегментов. Каждый сегмент будет размещен в указанной позиции. Давайте напишем код:

#Создание сегментов змеи segments = [] starting_positions = [(0,0), (-20,0), (-40,0)] for position in starting_positions: new_segment = Turtle(«square») new_segment.color(«black») new_segment.penup() new_segment.shapesize(1,1) new_segment.goto(position) segments.append(new_segment) screen.update()

В приведенном выше коде мы сначала создали пустой список сегментов. Этот список будет содержать сегменты змеи. После создания сегментов змея будет состоять из 3 сегментов, и каждый раз, когда змея съедает свою пищу, количество сегментов будет увеличиваться. Мы создали кортеж starting_positions. Он будет содержать 3 позиции, заданные в виде координат x и y, и будет представлять собой позиции, где будут созданы сегменты змеи. Мы создадим первый сегмент в (0,0), второй в (-20,0) и третий сегмент в (-40,0). Используя цикл for, мы создали 3 сегмента из переменной new_segment в виде объекта черепахи квадратной формы стандартного размера 20×20. Аргументом метода shapesize () является значение 1×1, поскольку он растягивает размер курсора рисования относительно его размера по умолчанию 20×20 пикселей. Метод penup() позволяет скрыть перо и вывести только форму объекта черепахи. Метод goto() позволяет нам создать фигуру, начиная с этой позиции. Наконец, мы добавили вновь созданный сегмент в пустой список, созданный в начале этого блока кода. Таким образом, будет создано еще 2 сегмента, поскольку в кортеже starting_positions содержится на 2 позиции больше.

В итоге мы обновим наш экран так, чтобы теперь на нем отображались как настроенный экран, так и недавно созданная змейка. Вот результат:

ec8c542ffe7d51c58f38fce06e83467d

Обратите внимание, что мы создали сегменты, используя только цикл for. По мере продвижения по программе нам потребуется увеличивать количество сегментов у змеи по мере того, как она ест еду. Чтобы упростить этот процесс, давайте изменим блок кода и добавим функцию add_segments, которая будет создавать змею, а также использоваться позже для добавления сегментов к змее во время поедания еды. Это будет более эффективным подходом к программированию в текущей ситуации:

#Создание сегментов змеи segments = [] starting_positions = [(0,0), (-20,0), (-40,0)] #Добавление сегментов Function def add_segments(position): new_segment = Turtle(«square») new_segment.color(«black») new_segment.penup() new_segment.goto(position) segments.append(new_segment) for position in starting_positions: add_segments(position) screen.update()

В приведенном выше блоке кода мы сделали то же самое, что и раньше, а именно, создали тело змеи, за исключением того, что использовали для этого функцию Python. Мы определили функцию add_segments, цель которой — просто добавлять сегменты к телу змеи, и список сегментов. Более того, теперь здесь пригодится метод tracer() модуля screen. Если вы закомментируете строку screen.tracer(), которую мы добавили в начале, вы увидите анимацию создания тела змеи по одному сегменту за раз (а нам это не нужно в нашей игре!). Это лучше визуализируется, если сначала импортировать модуль time и использовать функцию sleep(). Анимация будет более наглядной.

import time #Остальную часть кода оставьте без изменений for position in starting_positions: add_segments(position) time.sleep(1) screen.update()

Движение змеи

Следующая задача — запрограммировать движение змеи. Для начала давайте просто заставим змею двигаться вперед. Сначала мы создадим переменную game_is_on, которая будет иметь значение True, пока игра запущена, и будет переключаться на False, как только мы проиграем или игра закончится. Эта переменная будет использоваться в цикле while. Пока игра запущена, змея будет продолжать двигаться, и мы сможем менять ее направление только с помощью клавиш со стрелками. Это будет та часть нашей программы, которая будет поддерживать игру в активном состоянии.

Теперь начинается сложная часть. Чтобы змея двигалась вперед, нам нужно переместить все ее сегменты. Чтобы заставить все тело змеи двигаться вперед, нужно, чтобы каждый сегмент, кроме первого, перемещался на место предыдущего. Это означает, что в начале, когда змея имеет длину всего 3 сегмента, сегмент 3 переместится на место сегмента 2, сегмент 2 — на место сегмента 1, а сегмент 1 будет двигаться вперед, используя метод `forward()` черепашки. Это можно запрограммировать в цикле `for`, задав ему начальное значение последнего элемента списка, который является элементом на 2-й позиции (элементы списка начинаются с 0, то есть 0, 1, 2) при создании змеи (имеющей 3 сегмента), или же вычислить как длину сегментов минус 1. Цикл `for` завершится на позиции 0, и, поскольку движение происходит в обратном направлении, мы зададим шаг -1. Весь этот сценарий закодирован следующим образом:

game_is_on = True while game_is_on: screen.update() time.sleep(0.1) for seg_num in range(len(segments)-1, 0, -1): new_x = segments[seg_num — 1].xcor() new_y = segments[seg_num — 1].ycor() segments[seg_num].goto(new_x, new_y) segments[0].forward(20)

Обратите внимание, что мы добавили метод `update()` для экрана, а также определили скорость змейки с помощью функции `sleep()` модуля `time`. Если задать аргумент `0.1`, сегменты змейки будут двигаться вперед с задержкой в 0,1 секунды, и эту скорость можно регулировать. Если задать аргумент `1`, задержка составит 1 секунду, и скорость змейки будет низкой. Вы можете поэкспериментировать со скоростью змейки, изменяя значения, передаваемые функции `sleep()`.

Внутри цикла for подробно описывается, как сегменты будут перемещаться в положение предыдущих сегментов, используя их координаты. В конце первый сегмент нашей змеи перемещается вперед на 20, используя метод forward() черепашки. Запуск нашего кода выведет на экран движущуюся змею:

6fcc42598b904bb2905287e1d5233acb

Как контролировать змею

Теперь, когда мы рассмотрели, как заставить змею двигаться, следующим шагом будет управление её движениями вверх/вниз/влево/вправо. Для этого мы будем использовать обработчики событий экрана. Мы напишем программу так, чтобы при нажатии клавиш вверх, вниз, влево и вправо змея двигалась соответствующим образом, меняя положение головы.

Ещё одна особенность, которую нам нужно добавить, позаимствованная из оригинальной игры «Змейка», заключается в том, что когда змейка движется влево, она не может сразу повернуть направо, а когда она движется вверх, она не может сразу повернуть вниз. Короче говоря, змейка не может повернуть на 180 градусов относительно своего текущего положения. Давайте добавим эту функцию в наш код. Убедитесь, что вы добавили эти строки кода перед циклом while, который мы запрограммировали ранее.

#Управление змеей screen.listen() def turn_up(): if segments[0].heading() != 270: segments[0].setheading(90) def turn_down(): if segments[0].heading() != 90: segments[0].setheading(270) def turn_left(): if segments[0].heading() != 0: segments[0].setheading(180) def turn_right(): if segments[0].heading() != 180: segments[0].setheading(0) screen.onkey(turn_up, «Up») screen.onkey(turn_down, «Down») screen.onkey(turn_left, «Left») screen.onkey(turn_right, «Right»)

Как видно выше, сначала мы использовали метод `listen()` экрана, который позволяет отслеживать нажатия клавиш. Затем мы определили функции, которые будут вызываться позже в методе `onkey()` экрана, который вызывает функцию в зависимости от нажатой клавиши клавиатуры. Мы определили 4 функции, каждая из которых поворачивает в направлении, отличном от полностью противоположного, используя метод `setheading()` черепахи. Этот метод устанавливает положение головы черепахи, которое представляет собой первый сегмент или `segment[0]`, в 0, 90, 180 или 270, то есть вправо, вверх, влево или вниз. Условные операторы `if` в каждой функции гарантируют, что змея не повернет в противоположном направлении, как это видно в оригинальной игре.

Запуск всего кода с добавлением этого блока кода позволит нам переместить нашу змейку:

e822ef6131e7a387b080eb48e513d8e4

Создание продуктов питания

После того, как змея создана и запрограммирована на движение с помощью клавиш со стрелками, следующая задача — создать еду, которую змея будет есть и растить. Эта еда также будет создана в виде объекта черепахи круглой формы, красного цвета. Мы установим размер формы равным 0,5, чтобы еда занимала 10×10 пикселей на экране. Мы также установили скорость (speed()) на «fastest», чтобы анимация была быстрой и не было задержек в создании еды. Здесь мы импортируем модуль random из Python для создания еды в случайных позициях на игровом экране. Мы установили границы еды в диапазоне от -275 до 275 по осям x и y. Это сделано для того, чтобы змее было легче есть еду, не сталкиваясь с внешними границами экрана.

Кроме того, всякий раз, когда змея съедает свою пищу, необходимо генерировать новую пищу. Для этого мы определим функцию refresh() и сгенерируем новые случайные координаты, куда переместится объект черепахи, называемый food. Посмотрите код ниже:

#Создание еды import random food = Turtle() food.color(«red») food.shape(«circle») food.penup() food.shapesize(stretch_len=0.5, stretch_wid=0.5) food.speed(«fastest») random_x = random.randint(-275, 275) random_y = random.randint(-275, 275) food.goto(random_x, random_y) def refresh(): random_x = random.randint(-275, 275) random_y = random.randint(-275, 275) food.goto(random_x, random_y)

a0df90c1952d11872d5e06cbb19e23c4

Обнаружение столкновения с едой

После создания еды нам необходимо разработать механизм, с помощью которого змея её съест. Это означает, что всякий раз, когда змея касается еды, еда исчезает, а змея увеличивается на один сегмент. Мы запрограммируем этот сценарий таким образом, что всякий раз, когда змея и еда находятся в непосредственной близости друг от друга, так что расстояние между ними меньше 15, это означает, что змея съела еду. Мы воспользуемся методом distance() модуля turtle, который вычисляет расстояние между черепахой и определенной точкой или другим объектом черепахи. Если это расстояние меньше 15 (методом проб и ошибок), это будет означать, что змея коснулась или съела свою еду, и еда должна переместиться в новое место для продолжения игры. Следовательно, теперь мы вызовем функцию refresh(), которую мы определили ранее, чтобы переместить объект еды в новое место. Съедание еды должно увеличить размер змеи на один сегмент. Для этого мы определим функцию extend() вне цикла while и вызовем её внутри условного оператора if, когда змея съест еду.

#Расширение змеи def extend(): add_segments(segments[-1].position())

Как видно, функция extend() добавит новый сегмент к последнему сегменту тела змеи. Теперь перейдём к основному циклу игры:

game_is_on = True while game_is_on: … #Сохраняем исходный код … #Обнаружение столкновения с едой if segments[0].distance(food) < 15: refresh() extend()

0fcb740e9e81f1298757718ab9cad8f6

Табло и обновление результатов

Далее нам нужно создать табло, которое будет отображать счет. Для этого мы будем писать код вне цикла while. Мы создадим это табло и счет в виде двух объектов Turtle, используя метод write() класса Turtle, который позволяет отображать текст на экране. Сначала мы инициализируем переменную score значением 0. По мере того, как змея ест свою еду, переменная score будет увеличиваться на 1 каждый раз. Затем мы создадим два экземпляра Turtle: scoreboard и my_score. Объект scoreboard будет отображать на экране текст «Счет =», а объект my_score будет отображать переменную score, которая будет изменяться по мере того, как змея ест свою еду. Как видно из приведенного ниже кода, оба этих объекта Turtle были настроены для отображения текста на экране в соответствии с потребностями.

#Создание табло и счета score = 0 scoreboard = Turtle() scoreboard.color(«black») scoreboard.penup() scoreboard.hideturtle() scoreboard.goto(0,250) scoreboard.write(«Score = «, True, align=»center», font=(«Arial», 12, «normal»)) my_score = Turtle() my_score.color(«black») my_score.penup() my_score.hideturtle()

После того, как мы создали вышеуказанное, мы перейдем к добавлению возможности изменения ядра внутри цикла while игры, внутри условного оператора if, когда змея сталкивается с едой. Проверьте приведенный ниже код и обновите соответствующие строки кода:

game_is_on = True while game_is_on: … #Сохраняем исходный код … #Обнаружение столкновения с едой if segments[0].distance(food) < 20: refresh() extend() score = score + 1 my_score.goto(40, 250) my_score.clear() my_score.write(score, True, align="center", font=("Arial", 12, "normal"))

После запуска программы с указанными выше дополнениями на экране отображается следующее:

8987de453c3137b62d6503f0e86eb55c

Завершение игры

Когда игра заканчивается, нам нужно сообщить пользователю об этом, а не просто закрыть экран. Для этого мы определим функцию и будем вызывать её всякий раз, когда игра заканчивается: либо при столкновении со стеной, либо при столкновении с хвостом. Для этого мы также будем использовать объект черепахи. Это функция, и она будет вызываться, когда переменная game_is_on станет равной False.

#Всплывающее окно «Игра окончена» def game_over(): game_over = Turtle() game_over.color(«black») game_over.penup() game_over.hideturtle() game_over.write(«Игра окончена», True, align=»center», font=(«Arial», 40, «normal»))

Обнаружение столкновения со стеной

Ещё одно условие непрерывности игры — убедиться, что змея не столкнётся с ограничивающей стеной экрана. Чтобы это запрограммировать, и зная, что экран игры имеет размер 600×600, мы будем считать ограничивающую стену квадратом с углами в следующих точках: (290, 290), (290, -290), (-290, -290) и (-290, 290). Блок обнаружения стены будет находиться внутри игрового цикла в отдельном условном операторе if следующим образом:

game_is_on = True while game_is_on: … #Сохраняем исходный код … # Обнаружение столкновения со стеной if segments[0].xcor() > 290 or segments[0].xcor() < -290 or segments[0].ycor() > 290 or segments[0].ycor() < -290: game_is_on = False game_over()

В приведенных выше строках кода мы получили доступ к координатам x и y первого сегмента змеи и проверили, находится ли он внутри или за пределами ограничивающей стены.

Обнаружение столкновения с хвостом

Наконец, завершим программу еще одним условием игры: если голова змеи сталкивается сама с собой, то есть первый сегмент сталкивается с любым другим сегментом, игра заканчивается. Для кодирования этого сценария мы будем использовать цикл for:

game_is_on = True while game_is_on: … #Сохраняем исходный код … # Обнаружение столкновения хвостов for segment in segments[1:]: if segments[0].distance(segment) < 10: game_is_on = False game_over()

Когда игра заканчивается, нам нужно сообщить пользователю о завершении игры, а не просто закрыть экран. Для этого мы вызовем функцию game_over, которую определили ранее.

5e4e5e9f2f014c00618da3957083e145

Заключение

В этом уроке мы успешно реализовали игру «Змейка» на Python. Мы использовали наши базовые знания Python, такие как определение и вызов функций, использование списков и кортежей, циклов for и while, а также условных операторов. Мы также применили наши базовые знания объектно-ориентированного программирования для создания объектов из классов модуля. Если у вас возникнут какие-либо вопросы по поводу какого-либо фрагмента кода или предложения по улучшению и повышению эффективности кода, не стесняйтесь оставлять комментарии и делиться своими идеями. А пока — кодируйте, играйте и бросайте вызов своим друзьям в разработанной вами игре «Змейка»!

Источник: towardsdatascience.com

✅ Найденные теги: Python, Змейка, Игра, новости, Реализация

ОСТАВЬТЕ СВОЙ КОММЕНТАРИЙ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Фото сгенерированных лиц: исследование показывает, что люди не могут отличить настоящие лица от сгенерированных
Нейросети построили капитализм за трое суток: 100 агентов Claude заперли…
Скетч: цифровой осьминог и виртуальный мир внутри компьютера с человечком.
Сцена с жестами пальцами, где один жест символизирует "VPN", а другой "KHP".
‼️Paramount купила Warner Bros. Discovery — сумма сделки составила безумные…
Скриншот репозитория GitHub "Claude Scientific Skills" AI для научных исследований.
Структура эффективного запроса Claude с элементами задачи, контекста и референса.
Эскиз и готовая веб-страница платформы для AI-дизайна в современном темном режиме.
ideipro logotyp
Image Not Found
Звёздное небо с галактиками и туманностями, космос, Вселенная, астрофотография.

Система оповещения обсерватории Рубина отправила 800 000 сигналов в первую ночь наблюдений.

Астрономы будут получать оповещения о небесных явлениях в течение нескольких минут после их обнаружения. Теренс О'Брайен, редактор раздела «Выходные». Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной…

Мар 2, 2026
Женщина с длинными тёмными волосами в синем свете, нейтральный фон.

Расследование в отношении 61-фунтовой машины, которая «пожирает» пластик и выплевывает кирпичи.

Обзор компактного пресса для мягкого пластика Clear Drop — и что будет дальше. Шон Холлистер, старший редактор Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной странице вашего…

Мар 2, 2026
Черный углеродное волокно с текстурой плетения, отражающий свет.

Материал будущего: как работает «бессмертный» композит

Учёные из Университета штата Северная Каролина представили композит нового поколения, способный самостоятельно восстанавливаться после серьёзных повреждений.  Речь идёт о модифицированном армированном волокном полимере (FRP), который не просто сохраняет прочность при малом весе, но и способен «залечивать» внутренние…

Мар 2, 2026
Круглый экран с изображением замка и горы, рядом электронная плата.

Круглый дисплей Waveshare для креативных проектов

Круглый 7-дюймовый сенсорный дисплей от Waveshare создан для разработчиков и дизайнеров, которым нужен нестандартный экран.  Это IPS-панель с разрешением 1 080×1 080 пикселей, поддержкой 10-точечного ёмкостного сенсора, оптической склейкой и защитным закалённым стеклом, выполненная в круглом форм-факторе.…

Мар 2, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых