Глава 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 разбирает, почему.
Реальное окно: собранная игра — счёт 30, змейка из трёх сегментов, яблоко на поле
Реальное окно первого прототипа: всё вместе — движение, еда, счёт.

Полная, уже собранная и проверенная программа первого прототипа доступна отдельным файлом:

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() между двумя черепашками — удобный способ проверить, находятся ли они «достаточно близко» (для еды и столкновений).
  • Игровой цикл — функция, вызываемая снова и снова, пока не наступит условие конца игры.
  • Это только первый прототип — дальше глава разбирает сетку, тик, состояние и архитектуру куда внимательнее.