Jednym z największych wyzwań w projektowaniu RPG jest zarządzanie tym, kiedy i jak dzieją się akcje. Czy gracz może cofnąć ruch? Czy system walki turowej musi czekać na koniec animacji, zanim wykona kolejny krok? Tutaj na scenę wchodzi Wzorzec Command.
Czym jest wzorzec Command?
W tradycyjnym podejściu, gdy klikasz przycisk „Atak”, wywołujesz funkcję PerformAttack(). Wzorzec Command mówi: „Nie wywołuj funkcji od razu. Zamknij ją w obiekcie”. Dzięki temu akcja staje się „paczką danych”, którą możesz zapisać, przesłać dalej, odłożyć w czasie lub… cofnąć.
Dlaczego Twoje RPG tego potrzebuje?
-
Systemy Turowe: Możesz stworzyć kolejkę akcji (Queue), gdzie jednostki dodają swoje ruchy, a system wykonuje je jeden po drugim.
-
System Undo (Cofnij): Jeśli gracz w turze przesunął postać na złe pole, wzorzec Command pozwala na banalnie łatwe cofnięcie tej decyzji.
-
Replay System: Skoro każda akcja jest obiektem, możesz je zapisać i odtworzyć całą walkę krok po kroku.
Implementacja w C# i Unity
Zamiast bezpośrednich wywołań, tworzymy bazowy interfejs dla każdej komendy:
C#
public interface ICommand
{
void Execute();
void Undo(); // Opcjonalne, ale bardzo przydatne!
}
Teraz każda akcja, np. użycie mikstury, staje się osobną klasą:
C#
public class UsePotionCommand : ICommand
{
private PlayerStats _player;
private int _healAmount;
public UsePotionCommand(PlayerStats player, int amount)
{
_player = player;
_healAmount = amount;
}
public void Execute()
{
_player.Health += _healAmount;
Debug.Log("Mikstura użyta!");
}
public void Undo()
{
_player.Health -= _healAmount;
}
}
Zarządzanie historią akcji
Wystarczy prosta lista lub stos (Stack), aby trzymać historię wszystkich ruchów w turze:
C#
Stack<ICommand> commandHistory = new Stack<ICommand>();
void PerformAction(ICommand command)
{
command.Execute();
commandHistory.Push(command);
}
void UndoLastAction()
{
if(commandHistory.Count > 0)
{
ICommand lastCommand = commandHistory.Pop();
lastCommand.Undo();
}
}
Podsumowanie
Wzorzec Command oddziela moment wydania polecenia od jego wykonania. W złożonych mechanikach RPG, gdzie musimy synchronizować animacje, efekty cząsteczkowe i zmiany w statystykach, jest to fundament solidnej architektury.
Stosując ten wzorzec, Twoje systemy stają się bardziej modułowe i odporne na błędy, a Ty masz pełną kontrolę nad przepływem rozgrywki.
