-
Notifications
You must be signed in to change notification settings - Fork 3
Battle
W konstruktorze klasy Battle
tworzymy wszystkie obiekty potrzebne do walki
- obiekty graczy
Player
- korzystamy zPlayerFactory
- koordynator walki -
Coordinator
- obiekt odpowiedzialny za wyliczanie wyniku walki -
Outcome
- recorder -
ProcessRecorder
przechowujący dane o każdej turze
Na początku każdej iteracji głównej pętli wykonujemy metodę next_turn
w Coordinatorze. Coordinator ma pełną wiedzę o kolejności wykonywania ruchów przez graczy poprzez TurnsQueue
. Pozyskujemy w tej kolejki gracza za pomocą metody turn()
. TurnsQueue
zaprojektowany jest w taki sposób, że pobrany gracz automatycznie trafia na koniec kolejki.
Od gracza potrzebujemy karty, która ma się wykonać. Nie potrzbujemy całego obiektu karty, wystarczą nam same jej efekty, więc pytając gracza o kartę metodą use_card
chcemy dostać odpowiedź w postaci listy efektów. Nazwa tej metody może wydawać się dziwna, ale kryje się za nią większa logika która zasługuje na miano użycia karty. To co zwraca jest trochę nieintuicyjne, dlatego zadbaliśmy o zapisania typu returnu.
Pobieranie karty z Decku odbywa się w dokładnie ten sam sposób co pobieranie gracza z kolejki tur - pobrana karta z tej kolejki automatycznie trafia na koniec. Na zwróconej karcie wykonujemy
use
, która realizuje zadania:
- Aktualizacja buffów - Efekty posiadają swoje buffy; trwają one okreśioną liczbę tur i muszą być aktualizowane przed każdym użyciem kart, sprawdzamy czy buff nie jest już nieaktualny. Aktywne buffy aktualizują się metodą
tick
- 'tyka' wewnętrznymi timerami, które mówią np o czasie aktywności buffa. Buffy same w sobie nic nie robią, są jedynie później wykorzystywane przy obliczaniu wartości wykonanych efektów. - Zwrot listy efektów tej karty.
Dla każdego efektu wykonujemy metodę
activate(current_player, opponent, turnsQueue)
W środku metody wybierany jest cel - efekty mogą działać zarówno na przeciwnika, jak i na gracza, a następnie metoda abstrakcyjna on_activation(target, turns_queue)
(Więcej w sekcji Podmoduł Efektów )
Po wykonaniu efektów, stany obu graczy mogły ulec zmianie. Przekazujemy te dwa obiekty w ProcessRecordera w metodzie record_turn(attacker, defender)
.
Dla każdego wykonanego ruchu tworzony jest obiekt State
, który tłumaczy obiekty obu graczy na dwa uproszczone modele - klasa SimplifiedPlayer
. Metoda ta zna jedynie ID gracza, ID jego kart w kolejności w jakiej są w Decku i jego statystyki. Statystyki są kopiowane żeby zmiana statystyk w jednym obiekcie nie skuktowała zmianą wszystkich stanów.
Efekty kart zaprojektowane są z myślą o łatwym rozwoju modularnym aplikacji - programista może łatwo stworzyć nowe efekty korzystając z zastosowanego wzorca Strategy tworząc klasę dziedziczącą z Effect
. Podmoduł znajduje się w folderze effects
.
Klasa ta realizuje metody odpowiedzialne za aktualizacje efektów, wybieranie celu, zarządzanie buffami tak, abyśmy przy tworzeniu klas dziedziczących nie musieli się przejmować tą logiką. Punktem wejścia jest metoda activate
, którą wykonuje Battle
przy aktywowaniu efektów. Activate wybiera cel i wykonuje abstrakcyjną metodę on_activation
.
Serce każdego efektu. To jest jedyna metoda abstrakcyjna jaką musimy zaimplementować tworząc własny efekt. Jako parametry ta metoda udostępnia nam widok na cel efektu, czyli instancję BattlePlayer
i dostęp do kolejki ruchów w Coordinator
. Widoczność na playera umożliwia nam działanie na graczu (modyfikacja statystyk, talii, buffy, itp). Dodatkowo mamy pełen dostęp do kolejki ruchów. Nie jest to najlepsze rozwiązanie patrząc na low coupling, ale dzięki niemu uzyskaliśmy lepszą spójność.
W klasie Effect
mamy dostęp do atrybutów power, range i buffs. Służą one efektom, które korzystają z jakiś stałych wartości do wykonywania swoich akcji (leczenie, zadawanie obrażeń, tarcza). Inne efekty mogą w ogóle nie potrzebować tych wartości (np. zmiana kolejności talii). Atrybut power oznacza moc efektu, a range oznacza losowość efektu. buffs dodatkowo mogą aplikować mnożnik i stałą wartość do ostatecznej wartości efektu. Tą wartość możemy obliczać w dowolny sposób, ale przygotowaliśmy pewną klasę pomocniczą, która zrobi to za nas - Calculator
- zrealizowana jako singleton. Jeżeli chcemy obliczyć faktyczną moc efektu po uwzględnieniu power, range i buffs, możemy pobrać instancje kalkulatora Calculator.get_instance()
i wykonać metodę calculate_effect_power(power, range, buffs)
aby otrzymać ostateczną wartość efektu.
WMI Adventure
Dokumentacja
- System punktów
- API
- Backend
-
Frontend
- Struktura plików
- Komponenty:
-
Komponent CardsCreator
- Atoms:
- Organisms:
-
Komponent CardsCreator