Гид по технологиям

Реализуем систему здоровья в Arcade (Python)

5 min read Game Dev Обновлено 04 Jan 2026
Система здоровья в Arcade (Python) — шаг за шагом
Система здоровья в Arcade (Python) — шаг за шагом

Введение

Добавление системы здоровья в аркадную игру повышает вовлечённость игрока и создаёт дополнительный слой риска и стратегии. В материале показано простое и понятное решение на Python + Arcade, пригодное для обучения и быстрого прототипирования.

Важно: код примеров сохранён как рабочий — его можно сразу запустить и адаптировать.

Что вы получите (варианты запроса)

  • Как реализовать шкалу здоровья и её визуализацию
  • Как обрабатывать урон и лечение
  • Как добавить усиления (power-ups) и разные типы врагов
  • Как сделать систему модульной и протестировать её

Начало: простая игра

Установите библиотеку Arcade:

pip install arcade

Создайте простой игровой файл. Ниже — исходный код из исходной статьи. Скопируйте его в файл с именем simple-game.py и запустите.

import arcade  
  
# Set window dimensions  
SCREEN_WIDTH = 800  
SCREEN_HEIGHT = 600  
  
# Set player movement speed  
PLAYER_MOVEMENT_SPEED = 5  
white = arcade.color.WHITE  
blue = arcade.color.BLUE  
red = arcade.color.RED  
  
class GameWindow(arcade.Window):  
    def __init__(self, width, height):  
        super().__init__(width, height)  
        arcade.set_background_color(white)  
  
        # Create player and enemy objects  
        self.player = arcade.SpriteCircle(30, blue)  
        self.enemy = arcade.SpriteCircle(30, red)  
        self.player.center_x = 100  
        self.player.center_y = 100  
        self.enemy.center_x = 400  
        self.enemy.center_y = 300  
  
    def on_draw(self):  
        arcade.start_render()  
        self.player.draw()  
        self.enemy.draw()  
  
    def update(self, delta_time):  
        pass  
  
    def on_key_press(self, key, modifiers):  
        if key == arcade.key.LEFT:  
            self.player.center_x -= PLAYER_MOVEMENT_SPEED  
        elif key == arcade.key.RIGHT:  
            self.player.center_x += PLAYER_MOVEMENT_SPEED  
        elif key == arcade.key.UP:  
            self.player.center_y += PLAYER_MOVEMENT_SPEED  
        elif key == arcade.key.DOWN:  
            self.player.center_y -= PLAYER_MOVEMENT_SPEED  
  
def main():  
    game = GameWindow(SCREEN_WIDTH, SCREEN_HEIGHT)  
    arcade.run()  
  
if __name__ == "__main__":  
    main()

После запуска вы увидите окно с двумя кругами — игроком (синий) и врагом (красный):

Экран с надписью

Простая аркадная сцена с игроком и врагом

Переменные и константы для здоровья

Добавим базовые переменные, которые будут отслеживать текущее здоровье игрока, скорость восстановления и таймер лечения. Вставьте эти поля в конструктор класса GameWindow.

class GameWindow(arcade.Window):  
    def __init__(self, width, height):  
        # ...  
        # Health-related variables and constants  
        self.player_health = 100  
  
        # Health points healed per second  
        self.heal_rate = 1  
  
        # Timer for healing  
        self.heal_timer = 0  
  
    def update(self, delta_time):  
        # ...  
        # Update healing timer  
        self.heal_timer += delta_time  
  
        # Heal the player's health every 2 seconds  
        if self.heal_timer >= 2:  
            self.player_health += self.heal_rate  
            self.heal_timer = 0  
  
        # Ensure health doesn't exceed the maximum value  
        if self.player_health > 100:  
            self.player_health = 100

Пояснение: heal_rate — сколько единиц здоровья восстанавливается каждые 2 секунды. heal_timer накапливает delta_time между кадрами.

Урон и лечение: столкновения

Чтобы отнимать здоровье при столкновении игрока и врага, используйте check_for_collision. Добавьте соответствующую логику в метод update.

class GameWindow(arcade.Window):  
    def __init__(self, width, height):  
        # ...  
  
    def update(self, delta_time):  
        # Detect collisions between player and enemy  
        if arcade.check_for_collision(self.player, self.enemy):  
            self.player_health -= 5  
  
        # ...

Совет: используйте интервалы времени или «временную невосприимчивость» (invincibility frames), чтобы здоровье не пропадало слишком быстро при длительном перекрытии спрайтов.

Пример: храните last_hit_timer и не наносите урон, пока он меньше порога.

Смерть игрока и завершение игры

Когда здоровье достигает нуля или ниже, считаете игрока погибшим и завершаете игру. Добавьте проверку в update.

class GameWindow(arcade.Window):  
    def __init__(self, width, height):  
        # ...  
  
    def update(self, delta_time):  
        # ...  
  
        # Check if player health is zero or below  
        if self.player_health <= 0:  
            # End the game  
            arcade.close_window()  
  
        # ...

Важно: вместо немедленного закрытия окна вы можете переключаться на экран «Game Over», предлагать рестарт или сохранять статистику игрока.

Визуализация: бар здоровья

Добавим визуальный бар здоровья — простой и эффективный индикатор состояния игрока. Вставьте код в метод on_draw.

class GameWindow(arcade.Window):  
    def __init__(self, width, height):  
        # ...  
  
    def on_draw(self):  
        arcade.start_render()  
        self.player.draw()  
        self.enemy.draw()  
        gray = arcade.color.LIGHT_GRAY  
        green = arcade.color.GREEN  
  
        # Draw health bar  
        arcade.draw_rectangle_filled(SCREEN_WIDTH // 2, 20,    
                                     SCREEN_WIDTH, 20, gray)  
  
        health_width = self.player_health / 100 * SCREEN_WIDTH  
  
        arcade.draw_rectangle_filled(health_width // 2, 20,    
                                     health_width, 20, green)

Результат визуализации (пример):

Игра с игроком, врагом и полосой здоровья

Совет по UX: размещайте бар в месте, где он не заслоняет игровое поле, и используйте подсказки (цвета, мерцание) при критическом здоровье.

Дополнительные функции

Ниже — идеи и примеры кода для расширения системы.

Числовой индикатор здоровья

Чтобы показать точное значение, отрисуйте текст рядом с баром.

# Inside the on_draw() method  
black = arcade.color.BLACK  
text = f"Health: {self.player_health}"  
arcade.draw_text(text, 10, 10, black, 14)

Локализованный вариант (русский UI):

# Русский текст для интерфейса  
black = arcade.color.BLACK  
text = f"Здоровье: {self.player_health}"  
arcade.draw_text(text, 10, 10, black, 14)

Усиления здоровья (power-ups)

Добавьте объекты-усиления, которые увеличивают здоровье при столкновении:

# Inside the update() method  
if arcade.check_for_collision(self.player, self.power_up):  
    self.player_health += 20  
  
    # Remove the power-up from the game  
    self.power_up.kill()

Разные типы врагов

Различные враги наносят разный урон — это простая механика для усложнения уровней:

# Inside the update() method  
if arcade.check_for_collision(self.player, self.enemy):  
    if self.enemy.type == "weak":  
        self.player_health -= 5  
    elif self.enemy.type == "strong":  
        self.player_health -= 20

Архитектура: как сделать систему модульной

Рекомендуется вынести систему здоровья в отдельный класс или компонент. Это упростит тестирование и повторное использование.

Пример класса HealthComponent (микро-реализация):

class HealthComponent:
    def __init__(self, max_health=100, heal_rate=1, heal_interval=2.0):
        self.max_health = max_health
        self.current = max_health
        self.heal_rate = heal_rate
        self.heal_interval = heal_interval
        self._timer = 0.0
        self._invulnerable_timer = 0.0

    def update(self, delta):
        self._timer += delta
        if self._timer >= self.heal_interval:
            self.current = min(self.max_health, self.current + self.heal_rate)
            self._timer = 0.0
        if self._invulnerable_timer > 0:
            self._invulnerable_timer -= delta

    def take_damage(self, amount, invulnerable_time=0.5):
        if self._invulnerable_timer > 0:
            return False
        self.current = max(0, self.current - amount)
        self._invulnerable_timer = invulnerable_time
        return True

    def heal(self, amount):
        self.current = min(self.max_health, self.current + amount)

    def is_dead(self):
        return self.current <= 0

Интеграция: создавайте экземпляр HealthComponent в GameWindow и делегируйте обновления/урон/лечение ему.

Тестирование и критерии приёмки

Критерии приёмки

  • Игрок начинает с заданного максимума здоровья.
  • При столкновении с «слабым» врагом здоровье уменьшается на 5, со «сильным» — на 20.
  • Полоса здоровья отображает текущий процент корректно.
  • При достижении 0 здоровье игра переходит в экран Game Over или окно закрывается.
  • Лечение происходит автоматически по таймеру и не превышает максимум.

Примеры тест-кейсов

  1. Unit-test HealthComponent.take_damage(): наносим урон 10 — ожидаем уменьшение на 10.
  2. Unit-test invulnerability: два удара подряд с малого интервала — второй удар игнорируется.
  3. UI-test: при current = 50 ширина полосы равна SCREEN_WIDTH * 0.5.
  4. Integration: подбирать частоту кадров (delta_time) и симулировать 5 секунд — проверять накопление лечения.

Рекомендации и лучшие практики

Важно:

  • Делайте систему модульной — отделяйте логику от представления (визуализации).
  • Валидируйте входные значения: не позволяйте current выйти за диапазон [0, max_health].
  • Добавьте тесты для граничных случаев: 0, max, переполнение, отрицательные значения.
  • Предусмотрите события: on_death, on_heal, on_damage — это упростит интеграцию со звуком и анимацией.

Примечание: аудио и визуальные сигналы важны — предупредите игрока о критическом состоянии.

Альтернативные подходы и модели

  • «Щит + HP»: разделите здоровье на щит (восстанавливаемый) и жизненные очки (не восстанавливаются автоматически).
  • «Система ранений»: вместо числового HP используйте уровни состояния (здоров, ранен, критичен), влияющие на управление.
  • «Сердечки»: классический визуальный подход с дискретными единицами (например, 5 сердечек вместо 100 очков).

Когда этот подход не подходит

  • Для игр, где каждая ошибка должна быть фатальной (roguelike с перманентной смертью), нужно проектировать систему иначе.
  • В многопользовательных играх важно синхронизировать состояние здоровья через сервер и учитывать лагающие обновления.

Безопасность и сохранение состояния

  • При сохранении состояния сохраните не только текущее здоровье, но и таймеры (heal_timer, invulnerable_timer), чтобы при загрузке поведение оставалось предсказуемым.
  • В сетевых играх авторитет сервера должен подтверждать урон во избежание читерства.

Быстрый чек-лист для релиза

  • Модуль здоровья покрыт unit-тестами
  • Нулевая и максимальная границы проверены
  • События on_death/on_heal реализованы
  • UI-чувствительность (цвет, мерцание) протестирована на разных разрешениях
  • Сохранение и загрузка здоровья корректно работают

Decision flow (упрощённая логика)

flowchart TD
  A[Игрок инициализирован] --> B{Столкновение с врагом?}
  B -- Да --> C[Попытка нанести урон]
  C --> D{Инвulnerable?}
  D -- Нет --> E[Уменьшить здоровье]
  D -- Да --> F[Игнорировать урон]
  B -- Нет --> G{Проходит время для лечения?}
  G -- Да --> H[Восстановить здоровье]
  G -- Нет --> I[Обычный апдейт]
  E --> J{Здоровье <= 0?}
  J -- Да --> K[Game Over]
  J -- Нет --> I

Заключение

Добавление системы здоровья — относительно простая, но мощная механика для аркадной игры. Главное — сделать её понятной игроку, модульной в коде и протестированной на граничных сценариях. Вы можете начать с базовой реализации, а затем расширять систему: добавлять усиления, разные классы врагов, щиты и эффектные визуальные подсказки.

Краткое резюме:

  • Выясните требования: дискретное или непрерывное здоровье.
  • Выделяйте логику в отдельные компоненты.
  • Тестируйте и защищайте от некорректных значений.
  • Думайте про UX: цвет, текст и звук делают систему понятной.

Важно: начните с простого прототипа, затем итеративно улучшайте механику и UX.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Запретить изменение фона рабочего стола в Windows
Windows

Запретить изменение фона рабочего стола в Windows

Установка Anaconda на Ubuntu — руководство
Data Science

Установка Anaconda на Ubuntu — руководство

Ошибка 0x80d03801 в Microsoft Store — устранение
Windows

Ошибка 0x80d03801 в Microsoft Store — устранение

Таймер сна в Deezer — как включить и настроить
Руководство

Таймер сна в Deezer — как включить и настроить

Защита устаревших устройств без обновлений
Кибербезопасность

Защита устаревших устройств без обновлений

Беспроводная печать: настройка и устранение неполадок
Технологии

Беспроводная печать: настройка и устранение неполадок