Глава 3 · Добавляем правила

Столкновения и результат

12 минут · 38:00–50:00 в часовом практикуме

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

Рабочий файл

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

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

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

state
Переменная с выбранными нами строками playing, won или lost.
abs() и and
abs берёт величину разницы без знака. and требует выполнения обоих условий.
Ранний return
Завершает текущий вызов функции до остальных вычислений.

Подзадача 1 · Добавь состояние и подпись

Под координатами задай state. После создания окна и загрузки текстур создай надпись message.

Python
state = "playing"message = arcade.Text("", 640, 710, (255, 226, 136), 30,                      anchor_x="center", font_name="Arial")

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

  1. Строки playing, won и lost — наши значения состояния, не команды языка.
  2. Text создаёт надпись. Аргументы задают текст, позицию, цвет RGB и размер шрифта. anchor_x центрирует по x.

Подзадача 2 · Опиши проверку близости

Перед draw добавь функцию, которая подходит и для звезды, и для метеора.

Python
def touches(ax, ay, bx, by):    return abs(ax - bx) < 60 and abs(ay - by) < 60

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

  1. Сравниваем разницу по двум осям. Если обе меньше 60 пикселей, считаем объекты соприкоснувшимися.
  2. Это простая прямоугольная область вокруг центров, не контур PNG.

Подзадача 3 · Выбери исход и останови правила

В update добавь global state. Сразу после global поставь ранний выход, а после движения и патруля — проверки исхода.

Python
if state != "playing":    return# После движения и патруля:if touches(x, y, meteor_x, meteor_y):    state = "lost"elif touches(x, y, star_x, star_y):    state = "won"

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

  1. После победы или проигрыша update сразу завершится. draw продолжит показывать кадр.
  2. Опасность проверяем первой: цепочка if/elif выбирает один исход.

Подзадача 4 · Покажи результат

В конце draw выбери текст и нарисуй подготовленную надпись.

Python
message.text = ""if state == "won":    message.text = "Звезда найдена!"elif state == "lost":    message.text = "Столкновение."message.draw()

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

  1. Меняем свойство text у уже созданной надписи; draw() показывает её на текущем кадре.
  2. Для проверки двух исходов перезапусти файл. В следующем блоке добавим новую попытку клавишей R.
Рабочий результат задачи 5: столкновения и результат.
Рабочий результат задачи 5: столкновения и результат. Нажми на кадр, чтобы увеличить.

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

  1. Проверь победу и проигрыш отдельно. Измени порог близости и оцени, как меняется сложность.

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

  • Касание метеора даёт проигрыш, звезды — победу; после исхода герой и метеор стоят.

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

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

Скачать game.py задачи 5 ↓
Посмотреть весь файл
Python
import arcadeWIDTH = 1280HEIGHT = 800x = 210y = 235SPEED = 270keys = set()star_x, star_y = 1070, 540meteor_x, meteor_y = 720, 385meteor_speed = 200state = "playing"window = arcade.Window(WIDTH, HEIGHT, "Звезда и Метеор")background = arcade.load_texture("assets/background.png")hero = arcade.load_texture("assets/astronaut.png")star = arcade.load_texture("assets/star.png")meteor = arcade.load_texture("assets/meteor.png")message = arcade.Text("", 640, 710, (255, 226, 136), 30,                      anchor_x="center", font_name="Arial")def draw_image(texture, x, y, size):    arcade.draw_texture_rect(texture, arcade.XYWH(x, y, size, size))def touches(ax, ay, bx, by):    return abs(ax - bx) < 60 and abs(ay - by) < 60def draw():    window.clear()    arcade.draw_texture_rect(background, arcade.LBWH(0, 0, WIDTH, HEIGHT))    draw_image(hero, x, y, 132)    draw_image(star, star_x, star_y, 90)    draw_image(meteor, meteor_x, meteor_y, 132)    message.text = ""    if state == "won":        message.text = "Звезда найдена!"    elif state == "lost":        message.text = "Столкновение."    message.draw()def key_pressed(key, modifiers):    keys.add(key)def key_released(key, modifiers):    keys.discard(key)def update(delta_time):    global x, y    global meteor_x, meteor_speed    global state    if state != "playing":        return    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))    meteor_x += meteor_speed * delta_time    if meteor_x > 1110:        meteor_x = 1110        meteor_speed = -200    elif meteor_x < 340:        meteor_x = 340        meteor_speed = 200    if touches(x, y, meteor_x, meteor_y):        state = "lost"    elif touches(x, y, star_x, star_y):        state = "won"window.on_draw = drawwindow.on_key_press = key_pressedwindow.on_key_release = key_releasedwindow.on_update = updatewindow.on_deactivate = keys.cleararcade.run()
Преподавателю: объяснение блока и запись видео

Начните так: «Графическая сцена превращается в игру, когда появляются цель, опасность и конечный результат.»

Спросите: Почему return стоит в update, а не в draw?

Ответ: Нужно остановить изменение мира, сохранив рисование результата.

Если не получается: Если исход меняется повторно, ранний return стоит ниже проверок. Если надпись не видна, проверьте message.draw() и порядок рисования.

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