Глава 19 · Проект: «Змейка»
Полный код первого прототипа
Собираем все части в единый игровой цикл — и переходим от честного прототипа к внимательному разбору того, как устроена игра на самом деле.
Соберём один игровой шаг из всех частей главы — эта функция и есть сердце игры, вызываемое снова и снова, пока игра не закончится:
igrovoj_shag.py
import time
ZADERZHKA_SEK = 0.12 # пауза между шагами
def igrovoj_shag():
if igra_okonchena:
return False
dvigat_telo()
dvigat_golovu()
proverit_edu()
proverit_stolknoveniya()
screen.update()
return not igra_okonchena
def glavnyj_cikl():
global napravlenie
napravlenie = "right"
while igrovoj_shag():
screen.update()
time.sleep(ZADERZHKA_SEK)
tablo.goto(0, 0)
tablo.write(f"Игра окончена! Счёт: {schet}", align="center", font=("Arial", 20, "bold"))
Без time.sleep() игра закончилась бы раньше, чем вы успели бы нажать клавишу
Цикл
while крутится со скоростью Python, а не со скоростью человека: от центра до стены всего 14 шагов, и без паузы они проходят примерно за две тысячных секунды — окно успело бы только моргнуть надписью «Игра окончена! Счёт: 0». time.sleep(0.12) задаёт человеческий темп: примерно восемь шагов в секунду. Здесь sleep() уместен именно потому, что цикл и так блокирующий — пока он работает, в программе всё равно ничего другого не происходит, а screen.update() в конце каждого шага успевает разобрать накопившиеся нажатия клавиш. В архитектуре на screen.ontimer() (раздел 19.13) тот же самый sleep() уже станет ошибкой — Debug Lab 4 в разделе 19.31 разбирает, почему.
Полная, уже собранная и проверенная программа первого прототипа доступна отдельным файлом:
projects/turtle/snake/snake_basic.py
Запустите игру у себя
python snake_basic.py в терминале — управление стрелками клавиатуры.Честная, но не окончательная версия
Мы построили настоящую работающую игру — с движением, едой, счётом и столкновениями. Но
while igrovoj_shag(): ... — блокирующий цикл с фиксированной задержкой: скорость нельзя менять по ходу партии, а паузу и рестарт пришлось бы вплетать прямо в тело цикла. Всё состояние при этом живёт в глобальных переменных модуля. Начиная со следующего раздела глава смотрит на игру внимательнее: что такое сетка и игровой тик по-настоящему, как устроить паузу и рестарт без второй параллельной цепочки таймеров, и как вырастить из этого прототипа архитектуру уровня SnakeApp (раздел 19.32).★★★ Задача повышенной сложности
Уровни сложности
Добавьте выбор уровня сложности перед стартом игры (input() из главы 8) — влияющий на начальную скорость через задержку между шагами.
Практика: полная игра
Модуль turtle открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально
Итоги первого прототипа
Что мы узнали в первых восьми разделах
screen.tracer(0)+ ручнойscreen.update()— стандартный приём для плавной анимации в играх на Turtle.screen.onkeypress()связывает клавиши со стрелками с функциями изменения направления; запрет разворота на 180° предотвращает мгновенное самостолкновение.- Тело змейки — список отдельных сегментов, каждый из которых следует за предыдущим; порядок обновления (сначала тело, потом голова) критически важен.
.distance()между двумя черепашками — удобный способ проверить, находятся ли они «достаточно близко» (для еды и столкновений).- Игровой цикл — функция, вызываемая снова и снова, пока не наступит условие конца игры.
- Это только первый прототип — дальше глава разбирает сетку, тик, состояние и архитектуру куда внимательнее.