GCM – Wrzesień: Gra w TypeScript. Gra nabiera kształtów

Już wiem, jak wyglądać będzie moja TypeScriptowa gra. Stworzę bardzo prostą wersję klasycznej łamigłówki sokoban. Aby ukończyć grę gracz musi przesunąć skrzynie na wyznaczone pola. Musi robić to umiejętnie, bo inaczej się zablokuje.

W mojej implementacji mam już obiekt gracza, ściany o które się obija, oraz skrzynki, które może przesuwać. Czyli gra już prawie gotowa 🙂

JavaScript Noob 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 klikając w ten link.

W kodzie pojawiło się trochę zmian, jednak wbrew pozorom nie ma ich aż tak dużo. Doszło kilka nowych klas oraz parę zmian wewnątrz tych, które już istniały. Pierwszą nowością jest interfejs map, na podstawie którego tworzę następnie klasę Map. Oto ich kod:

Jak łatwo się domyślić jest to obiekt reprezentujący mapę poziomu. Posiada on dwa pola. Pierwsze, size, to rozmiar jednego kafelka mapy. Drugie pole mapData, przechowuje tablicę tablic, w których znajdują się wartości liczbowe. Wartości obu pól przekazywane są podczas tworzenia obiektu do parametrów konstruktora.

Do tego, klasa Map posiada metodę draw, która wyrysowuje te elementy mapdata, które nie są równe zero.

Kolejne dwie nowe klasy to Box oraz GameText. Na pdostawie pierwszej z nich tworzone będą obiekty przedstawiające skrzynki, druga służy do dodawania do gry wszelkiego rodzaju tekstów. Tak wyglądają w kodzie:

Obie klasy te są bardzo proste. Obie implementują interfejs actor, więc można je traktować dokładnie tak samo jak inne obiekty tego typu.

Największe zmiany zaszły zdecydowanie wewnątrz klasy State, która rozrosła się dość mocno. Nie będę wklejał całego jej kodu, ponieważ jest dość spora. Można go podejrzeć w pliku, który podlinkowałem wyżej.

Teraz konstruktor State przyjmuje jeden dodatkowy parametr opcjonalny typu Map. Jeżeli istnieje on w stanie, w metodzie draw, zostanie wyrysowany. Do tego stan posiada dwie nowe metody checkCollision oraz checkOverlap. Dokładne ich działanie opisałem już wcześniej w osobnych postach. W skrócie, pierwsza służy do blokowania ruchu obiektów w wypadku kolizji a druga tylko wykrywa kolizje.

I teraz nadchodzi lwia część zmian, czyli metoda upadte, a właściwie ta jej część która wykonuje się, jeżeli w stanie istnieje mapa oraz tablica aktorów nie jest pusta:

Spełniony pierwszy warunek oznacza, że stan w którym aktualnie znajduje się program to główny stan gry. W takim wypadku muszę sprawdzić kolizję. Najpierw przechodzę podwójną pętla przez każdy element tablicy tablic mapData, czyli mapy poziomu gry. Jeżeli dany element to jedynka, czyli ściana, sprawdzam kolizję z obiektem gracza. Do sprawdzenia kolizji potrzebuję dwóch obiektów o określonych parametrach, dlatego tworze na szybko pomocniczy obiekt mający reprezentować fragment ściany. To rozwiązanie jest trochę badziewne i dałoby się zrobić to lepiej, szczególnie przy pomocy TypeScriptu. Póki co jednak zostaje w taki sposób. Następnie sprawdzam czy aktorów jest więcej niż jeden. Jeżeli tak to dla pozostałych (będą to skrzynki) też sprawdzam kolizje ze ścianami. Jeżeli kolizja wystąpi, pole movable skrzynki ustawiam na false.

Na koniec sprawdzam kolizje pomiędzy graczem a skrzynkami (warunek – aktorów jest więcej niż jeden). Obracam kolejność argumentów wewnątrz checkCollision w zależności od tego, czy skrzynka jest movable czy nie. Od tego zależy czy gracz będzie popychał skrzynkę czy będzie ona go blokowała. W rezultacie, gracz może popychać skrzynkę dopóki ta nie „wejdzie” w ścianę. Wtedy będzie go blokowała.

Na koniec dla każdej skrzynki która nie styka się z graczem wartość pola movable ustawiam na true. Dzięki temu skrzynki zatrzymają się gdy gracz wsunie je na ścianę, ale będzie mógł je dalej pchać wzdłuż ściany.

I tak naprawdę to wszystko. Reszta programu to zmiany kosmetyczne. Pierwszy stan zawiera w sobie tylko obiekt tekstu a wcisniecie spacji zawsze ustawia stan gry. W głównym stanie znajduje się mapa oraz jeden obiekt skrzynki do popychania. Przyciśnięcie spacji resetuje ten stan.

Kolejne kroki to dodanie większej ilości skrzynek, zaprojektowanie kolizji pomiędzy nimi oraz wbudowanie systemu liczenia punktów. Do tego postaram się zrobić mały porządek w kodzie, jednak brak doświadczenia w pisaniu aplikacji TypeScriptowych daje się we znaki i robi mi się mały bałagan. No ale cóż, tak się człowiek uczy 🙂 .

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 *