, ,

Jak stworzyć system zdrowia gracza w Godot 4?

·

System zdrowia gracza to jedna z najważniejszych mechanik w większości gier. Nawet bardzo prosta gra platformowa, RPG, gra akcji albo survival potrzebuje informacji o tym, ile obrażeń może przyjąć postać, kiedy powinna umrzeć i w jaki sposób można ją uleczyć.

W Godot 4 najlepiej nie wrzucać całej logiki zdrowia bezpośrednio do głównego skryptu gracza. Znacznie lepszym rozwiązaniem jest stworzenie osobnego komponentu, na przykład HealthComponent. Dzięki temu ten sam system można później wykorzystać nie tylko u gracza, ale także u przeciwników, bossów, skrzyń, drzwi, beczek wybuchowych albo innych obiektów zniszczalnych.

Przykładowa struktura sceny

Najprostsza struktura gracza może wyglądać tak:

Player (CharacterBody2D)
├── Sprite2D
├── CollisionShape2D
└── HealthComponent (Node)

Node Player odpowiada za ruch, wejście gracza i ogólne zachowanie postaci. Node HealthComponent odpowiada wyłącznie za zdrowie. Taki podział pozwala łatwiej rozwijać projekt, ponieważ każda część gry ma swoje konkretne zadanie.

Skrypt HealthComponent.gd

Utwórz nowy skrypt o nazwie HealthComponent.gd i przypisz go do node’a HealthComponent.

extends Node

signal health_changed(current_health: int, max_health: int)
signal died

@export var max_health: int = 100

var current_health: int = 0
var is_dead: bool = false

func _ready() -> void:
    current_health = max_health
    health_changed.emit(current_health, max_health)

func take_damage(amount: int) -> void:
    if is_dead:
        return

    if amount <= 0:
        return

    current_health -= amount
    current_health = clamp(current_health, 0, max_health)

    health_changed.emit(current_health, max_health)

    if current_health <= 0:
        die()

func heal(amount: int) -> void:
    if is_dead:
        return

    if amount <= 0:
        return

    current_health += amount
    current_health = clamp(current_health, 0, max_health)

    health_changed.emit(current_health, max_health)

func die() -> void:
    if is_dead:
        return

    is_dead = true
    died.emit()

Co robi ten skrypt?

Zmienna max_health określa maksymalną liczbę punktów życia. Dzięki oznaczeniu @export można zmieniać tę wartość bezpośrednio w edytorze Godot, bez edytowania kodu.

Zmienna current_health przechowuje aktualną liczbę punktów życia. Przy starcie gry jest ustawiana na wartość max_health, czyli gracz zaczyna z pełnym zdrowiem.

Funkcja take_damage() odejmuje zdrowie. Jeżeli zdrowie spadnie do zera, wywoływana jest funkcja die(). Funkcja heal() działa odwrotnie — dodaje zdrowie, ale nie pozwala przekroczyć maksymalnej wartości.

Dlaczego używamy sygnałów?

Sygnały health_changed i died pozwalają innym elementom gry reagować na zmianę zdrowia bez sztywnego łączenia skryptów. Na przykład pasek życia może słuchać sygnału health_changed, a główny skrypt gracza może słuchać sygnału died.

Dzięki temu komponent zdrowia nie musi wiedzieć, czy aktualizuje pasek życia, wyświetla ekran końca gry, odtwarza animację śmierci czy usuwa przeciwnika ze sceny. On tylko informuje: „zdrowie się zmieniło” albo „postać umarła”.

Podłączenie systemu zdrowia do gracza

W skrypcie gracza można odwołać się do komponentu zdrowia w taki sposób:

extends CharacterBody2D

@onready var health_component: Node = $HealthComponent

func _ready() -> void:
    health_component.died.connect(_on_player_died)

func _on_player_died() -> void:
    print("Gracz zginął")
    queue_free()

func damage_player() -> void:
    health_component.take_damage(10)

Jak testować system zdrowia?

Najprostszy test można zrobić przez przypisanie obrażeń do klawisza. Najpierw w ustawieniach projektu dodaj akcję, na przykład test_damage. Następnie w skrypcie gracza dodaj:

func _process(_delta: float) -> void:
    if Input.is_action_just_pressed("test_damage"):
        health_component.take_damage(10)

Po uruchomieniu gry każde naciśnięcie przypisanego klawisza odejmie graczowi 10 punktów zdrowia.

Jak rozbudować system zdrowia?

  • nieśmiertelność przez kilka sekund po otrzymaniu obrażeń,
  • różne typy obrażeń, na przykład ogień, trucizna albo lód,
  • regenerację zdrowia,
  • pancerz zmniejszający obrażenia,
  • animację otrzymania ciosu,
  • efekty dźwiękowe,
  • automatyczne odrodzenie gracza.

Podsumowanie

System zdrowia warto przygotować jako osobny komponent. Jest to proste, czytelne i bardzo wygodne rozwiązanie. Dzięki niemu można łatwo dodawać zdrowie do różnych obiektów w grze, bez kopiowania tej samej logiki do wielu skryptów.

Poprzedni poradnik: