GCM – Październik: Necropolis – Phaser + TypeScript. Kontrolowanie czasu.

Czas na aktualizację mojej październikowego projektu. Tym razem bohater gry otrzymał dużą moc, która pozwoli mu uniknąć wielu tarapatów. Dzięki magicznemu amuletowi jest on w stanie spowolnić czas. Wystarczy, że gracz naciśnie spacje 🙂 Ponowne naciśnięcie spacji spowoduje, że czas wróci do normalnego biegu.

Dzięki możliwości kontrolowania czasu, gracz otrzyma możliwość unikania przeciwników i bezpiecznego przejścia pomiędzy pułapkami. Oczywiście korzystanie z mocy będzie w przyszłości ograniczone, ale póki co skupiłem się na dodanie podstaw mechanizmu.

tworzenie gier typescript

Aktualną wersję gry przetestować można klikając w obrazek powyżej. Na moim githubie znajduje się repozytorium zawierające jak najaktualniejszy stan gry. Wersja przedstawiona w poście nie będzie dostępna w źródle strony. To czego używa przeglądarka to przetranspilowany na JS kod. Wersję TypeScriptową zobaczyć można ściągając tę paczkę.

Kod gry zaczyna się powoli rozrastać, więc nie wiem czy uda mi się opisać wszystkie zmiany. Postaram się nie opuścić ważnych elementów, ale w razie czego repo na githubie stoi otworem 🙂 Jeśli pojawią się jakieś pytania, dajcie znać w komentarzach, chętnie odpowiem.

Najważniejszym nowym elementem, który pojawił się w grze jest oczywiście kontroler czasu. Umieściłem go w osobnej klasie, której definicja znajduje się w pliku . Oto jego treść:

Jak widać, nic wielkiego. Klasa ma dwa pola, pierwsze to timeModifier, które przechowuje liczbę mającą wpływ na szybkość poruszania się obiektów. Drugie pole timeSlowed przechowuje wartość boolowską. Jest to flaga, pokazująca czy czas jest aktualnie spowolniony czy nie.

Oprócz konstruktora, który przypisuje wartości do wymienionych wyżej pól, klasa TimeController posiada również dwie metod slowTime oraz speedUpTime. Jak sugerują nazwy, służą one do manipulowania czasem gry czyli wartościami pól timeModifier oraz timeSlowed.

Klasa sama w sobie nie robi zbyt wiele. Dopiero w połączeniu z innymi obiektami widoczny jest pełny efekt. Nie będę wklejał kodu, ale metody slowTime oraz speedUpTime wywoływane są w głównym stanie gry, przez wciśnięcie spacji. Kontroler wywołuje odpowiednią metodę w zależności od tego w jakim stanie jest czas.

Kolejne dwie nowe klasy to Bullets oraz Monster. Obie są ze sobą powiązane. Pierwsza to phaserowa grupa, która zawiera pociski ciskane przez potwora, czyli instancję drugiej klasy.

Zacznę od klasy Bullets, którą umieściłem w pliku bullets.ts:

Mamy tu fajny przykład tego jak stworzyć phaserową grupę w TS. Jak widać ma ona swój własny typ: Phaser.Group, który wykorzystuje aby rozszerzyć klasę Bullets. Większość kodu powinna wyglądać znajomo, wiele razy tworzyłem już kod obiektu odpowiadającego za różnego rodzaju pociski.

Warto zwrócić uwagę na to, że w konstruktorze, klasa otrzymuje referencję do obiektu typu TimeContoller. Z niego sterowana będzie prędkość lecących kul.

Widać to najlepiej wewnątrz metod spawn (która wywoływana będzie z obiektu potwora) oraz update (która wywoływana będzie co klatkę gry dla każdej znajdującej żywej instancji). Prędkość poruszania się na osi X mnożona jest przez timeModifier, czyli 1 lub 5 w zależności od tego czy czas jest aktualnie spowolniony czy nie.

Kolejna klasa w której widać działanie tej mechaniki to Monster. Znajduje się ona wewnątrz pliku monster.ts:

Tutaj sprawa wygląda bardzo podobnie. Pomimo, że klasa ta jest bardziej rozbudowana, większość jej elementów powinno być już dość dobrze znane. W konstruktorze oprócz oczywistych danych, obiekt otrzymuje referencje do obiektu typu Bullets oraz TimeController.

Mimo wszystko mechanizmy obiektu potwora są dość proste. Porusza się on bez ustanku po osi X. Jeśli trafi na ścianę (kolizje akurat są wykrywane w główny stanie gry) Wywoływana jest metoda turnAround, która robi to czego można by się spodziewać po nazwie 🙂 . Do tego co dwie sekundy potwór ma szanse na wyplucie z siebie pocisku. Wywoływana jest wtedy metoda spawn obiektu bullets.

Wpływ kontrolera czasu na potwora widać w metodzie update. Tak samo jak w przypadku pocisków i tutaj prędkość poruszania się zależy od aktualnej wartości pola timeModifier w obikecie TimeController. Jeżeli czas jest spowolniony potwór porusza się wolniej. Gdy tylko czas wróci do swojego naturalnego biegu, potwór znów przemieszcza się z oryginalną prędkością a to dzięki temu, że jego szybkość aktualizowana jest na bieżąco w metodzie update.

Ostatni nowy obiekt w grze to SpikeTrap czyli śmiercionośna pułapka z kolcami wysuwającymi się z podłogi. Klasa opisana jest w pliku spikeTrap.ts, oto jego treść:

Działanie tego prostego obiektu bazuje praktycznie całkowicie na kontrolerze czasu. Klasa rozszerza Phaserowy Sprite, więc w konstruktorze przekazuję wszystkie potrzebne dane plus referencję do TimeController‚a i wartość dla pola triggerTime. To ostatnie to liczba klatek co którą zmienia się stan pułapki z aktywnej na nie aktywną i w drugą stronę.

Zmiana stanu wynika z działania jedynej metody klasy: activate. Póki co zmiana stanu pułapki powoduje jedynie zmianę grafiki wyświetlanej w grze. W przyszłości oczywiście aktywna pułapka będzie wyrządzać krzywdę graczowi. Po nieaktywnej może on przejść.

Metoda activatewywoływana jest za pomocą phaserowego timer co liczbę klatek zależną od triggerTime. Jednak i na to wpływa ma kontroler czasu. Jeżeli czas jest zwolniony, liczba ta jet większa. Niektóre pułapki będą aktywować się tak często, że bez spowolnienia czasu gracz nie będzie mógł po nich przejść.

Tak samo jak pułapki, pociski oraz potwory nie wpływają jeszcze w żaden sposób na gracza. Kolizje zostaną dodane w kolejnej aktualizacji.

I to wszystko na dziś. Jeżeli chcesz być na bieżąco z postami na blogu zachęcam do polubienia mojej strony na facebooku. Zawsze zamieszczam tam informacje o wszystkich nowościach. Jest to też dobre miejsce na kontakt ze mną. Na wszystkie pytania zawsze odpowiem :). Do przeczytania.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *