Глава 2 · Оживляем объекты

Плавное управление

13 минут · 15:00–28:00 в часовом практикуме

Результат задачи: Двигать героя стрелками, останавливать при отпускании и ограничить поле.

Рабочий файл

Открой game.py в распакованном проекте. Продолжаем файл предыдущей задачи. Python и Arcade уже должны быть установлены. После изменения сохрани и запусти Run → Run Module / F5. Старое игровое окно закрой.

Скачать учебную папку со всеми картинками ↓

Что используем в этом блоке

keys = set()
Множество нажатых клавиш без повторов: add добавляет, discard убирает, in проверяет наличие.
delta_time
Время между обновлениями в секундах. Скорость × время даёт пройденный путь.
global
Разрешает функции присваивать новые значения переменным уровня файла.

Подзадача 1 · Запомни нажатия и отпускания

Под настройками создай SPEED = 270 и keys = set(). После draw добавь два обработчика.

Python
def key_pressed(key, modifiers):    keys.add(key)def key_released(key, modifiers):    keys.discard(key)

Как работает блок

  1. Arcade передаёт key — код клавиши; modifiers содержит Shift, Ctrl и подобные признаки, здесь они не нужны.
  2. При удержании клавиша остаётся в keys, при отпускании удаляется. Множество не создаёт дубликатов.

Подзадача 2 · Обновляй координаты

Добавь update перед строками подключения. Скорость измеряется в пикселях в секунду.

Python
def update(delta_time):    global x, y    if arcade.key.RIGHT in keys:        x += SPEED * delta_time    if arcade.key.LEFT in keys:        x -= SPEED * delta_time    if arcade.key.UP in keys:        y += SPEED * delta_time    if arcade.key.DOWN in keys:        y -= SPEED * delta_time

Как работает блок

  1. += прибавляет к текущему значению, -= вычитает. По x двигаемся вправо/влево, по y вверх/вниз.
  2. Независимые if позволяют держать два направления. В этой базовой версии диагональ быстрее прямого движения.
  3. keys.add меняет существующее множество; global нужен для присваиваний x и y.

Подзадача 3 · Ограничь поле

В конце update, после движения, добавь ограничения для центра героя.

Python
x = max(96, min(1184, x))y = max(171, min(589, y))

Как работает блок

  1. min ограничивает сверху, max снизу. Внутри update эти строки имеют отступ четыре пробела.

Подзадача 4 · Подключи события

Перед arcade.run() добавь подключения. on_draw уже подключён в первом уроке.

Python
window.on_key_press = key_pressedwindow.on_key_release = key_releasedwindow.on_update = updatewindow.on_deactivate = keys.clear

Как работает блок

  1. Обработчик ввода меняет набор клавиш, update рассчитывает координаты, draw показывает результат.
  2. При уходе в другое окно keys.clear сбрасывает клавиши, чтобы персонаж не продолжал движение сам.
Рабочий результат задачи 3: плавное управление.
Рабочий результат задачи 3: плавное управление. Нажми на кадр, чтобы увеличить.

Самостоятельная модификация

  1. Подбери другую SPEED и проверь четыре края. Дополнительно добавь D для движения вправо через условие or.

Критерий готовности

  • Удержание даёт плавное движение; отпускание останавливает; выйти за поле нельзя.

Полный game.py после задачи 3

Сверь расположение блоков или скачай файл в корень распакованного проекта рядом с assets. Это полная рабочая версия на данном этапе.

Скачать game.py задачи 3 ↓
Посмотреть весь файл
Python
import arcadeWIDTH = 1280HEIGHT = 800x = 210y = 235SPEED = 270keys = set()window = arcade.Window(WIDTH, HEIGHT, "Звезда и Метеор")background = arcade.load_texture("assets/background.png")hero = arcade.load_texture("assets/astronaut.png")def draw_image(texture, x, y, size):    arcade.draw_texture_rect(texture, arcade.XYWH(x, y, size, size))def draw():    window.clear()    arcade.draw_texture_rect(background, arcade.LBWH(0, 0, WIDTH, HEIGHT))    draw_image(hero, x, y, 132)def key_pressed(key, modifiers):    keys.add(key)def key_released(key, modifiers):    keys.discard(key)def update(delta_time):    global x, y    if arcade.key.RIGHT in keys:        x += SPEED * delta_time    if arcade.key.LEFT in keys:        x -= SPEED * delta_time    if arcade.key.UP in keys:        y += SPEED * delta_time    if arcade.key.DOWN in keys:        y -= SPEED * delta_time    x = max(96, min(1184, x))    y = max(171, min(589, y))window.on_draw = drawwindow.on_key_press = key_pressedwindow.on_key_release = key_releasedwindow.on_update = updatewindow.on_deactivate = keys.cleararcade.run()
Преподавателю: объяснение блока и запись видео

Начните так: «Разделяем ввод, движение и рисование. Клавиша задаёт желание игрока, обновление меняет координаты, кадр показывает новое место.»

Спросите: Почему движение умножается на delta_time, а не просто на один шаг за кадр?

Ответ: Так скорость привязана к секундам, а не к количеству обновлений на конкретном компьютере.

Если не получается: Нет остановки — проверьте key_released и его подключение. UnboundLocalError — проверьте global. Не ставьте while True вокруг arcade.run().

Открыть сценарий блока →