Плавное управление
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 добавь два обработчика.
def key_pressed(key, modifiers): keys.add(key)def key_released(key, modifiers): keys.discard(key)Как работает блок
- Arcade передаёт key — код клавиши; modifiers содержит Shift, Ctrl и подобные признаки, здесь они не нужны.
- При удержании клавиша остаётся в keys, при отпускании удаляется. Множество не создаёт дубликатов.
Подзадача 2 · Обновляй координаты
Добавь update перед строками подключения. Скорость измеряется в пикселях в секунду.
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 двигаемся вправо/влево, по y вверх/вниз.
- Независимые if позволяют держать два направления. В этой базовой версии диагональ быстрее прямого движения.
- keys.add меняет существующее множество; global нужен для присваиваний x и y.
Подзадача 3 · Ограничь поле
В конце update, после движения, добавь ограничения для центра героя.
x = max(96, min(1184, x))y = max(171, min(589, y))Как работает блок
- min ограничивает сверху, max снизу. Внутри update эти строки имеют отступ четыре пробела.
Подзадача 4 · Подключи события
Перед arcade.run() добавь подключения. on_draw уже подключён в первом уроке.
window.on_key_press = key_pressedwindow.on_key_release = key_releasedwindow.on_update = updatewindow.on_deactivate = keys.clearКак работает блок
- Обработчик ввода меняет набор клавиш, update рассчитывает координаты, draw показывает результат.
- При уходе в другое окно keys.clear сбрасывает клавиши, чтобы персонаж не продолжал движение сам.

Самостоятельная модификация
- Подбери другую SPEED и проверь четыре края. Дополнительно добавь D для движения вправо через условие or.
Критерий готовности
- Удержание даёт плавное движение; отпускание останавливает; выйти за поле нельзя.
Полный game.py после задачи 3
Сверь расположение блоков или скачай файл в корень распакованного проекта рядом с assets. Это полная рабочая версия на данном этапе.
Скачать game.py задачи 3 ↓Посмотреть весь файл
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().
Открыть сценарий блока →