JS Platformer – przewijający ekran gry

Ile razy zdarzyło się wam, że siadacie przed kompem aby napisać prosty, krótki kawałek kodu a tu nagle okazuje się, że spędzacie nad tym pół dnia? Ja dziś miałem taką sytuację. Implementacja elementu gry, który dziś opiszę, miała zająć tylko chwilę i być jedynie rozgrzewką, przed pisaniem innych rzeczy. Niestety zeszedł mi na to cały przeznaczony tego dnia na programowanie czas.

Co dokładnie chciałem zaimplementować? Przewijający się ekran gry, dzięki któremu w miarę jak gracz się przemieszcza, na płótnie wyświetlają się nowe obiekty.

Platformówka w JavaScript

Z założenia, etapy w mojej grze platformowej nie miały ograniczać się do rozmiarów płótna. Poziomy mają być duże i gracz powinien mieć możliwość dowolnie je eksplorować. Na płótnie pojawiałyby się tylko aktualnie widoczne obiekty. Widok ma się przesuwać wraz z postacią kontrolowaną przez gracza. Efekt ten można zobaczyć klikając tutaj.

Nie jest to specjalnie skomplikowana technika. W jednej ze swoich gier już implementowałem takie rozwiązanie. Tym razem jednak, jak to czasem bywa, wystąpiły nieprzewidziane kłopoty.

Tak jak początkowo planowałem, dość szyb udało mi się dodać efekt przewijającego ekranu gry. Zmieniłem tylko rozkład obiektów, dopasowałem ich współrzędne do nowego obszaru gry i gotowe. Niby. Wprawdzie świat przewijał się jak należy, ale pojawiły się nowe problemy. Strzałka, która jest rysowana na prostokącie reprezentującym gracza nie wskazywała na kursor myszki tak jak powinna. Do tego, przyciskanie prawego klawisza myszy nie dawało żadnych widocznych efektów (wcześniej strzelanie).

I co teraz? Nowo dodany kod był bardzo mały i byłem pewny, że z nim wszystko gra. A jednak w jakiś sposób wpłynął na dodane wcześniej funkcjonalności.

Po chwili główkowania uświadomiłem sobie, że strzały generowane prawym przyciskiem myszy, są usuwane z gry, gdy tylko wylecą poza płótno. Czyli jeżeli ich współrzędne x oraz y będą większe niż szerokość i wysokość płótna lub mniejsze od zera. Nowy strzał generowany był w pozycji gracza i otrzymywał zbliżone do jego obiektu współrzędne. Ponieważ x i y gracza określone są teraz względem świata gry a nie płótna, były on większe niż rozmiar tego elementu html już na samym początku. Wystrzelone pociski były usuwane z gry, zanim zostały narysowane.

Ten problem udało mi się szybko zlikwidować. Zmieniłem regułę usuwania pocisków. Teraz są kasowane kiedy wylecą po za widoczny obszar. Zadziałało! Znów widziałem wystrzeliwane pociski. Niestety leciały one pod nieodpowiednim kątem no i wciąż miałem problem ze strzałką.

Podejrzewałem, że problem związany jest z obliczaniem kąta strzału i kąta obrotu strzałki, ale dłuższy czas nie mogłem dojść do tego co jest przyczyną. Odpowiedź okazała się trywialna. Tym razem również kłopoty generowane były przez nowe współrzędne postaci gracza. Kąt obliczałem korzystając z dwóch punktów, jeden wskazywany przez myszkę a drugi przez lokację gracza. Jednak myszka wskazywała współrzędne względem płótna, a gracz względem świata gry.

Rozwiązaniem było sprawienie aby myszka wskazywała na punkt w aktualnie rysowanym świecie gry. Tutaj ‚fix’ wymagał trochę więcej pracy. Stworzyłem osobny moduł reprezentujący wyświetlacz (screen.js). Stan gry aktualizuje na bieżąco jego współrzędne. Dzięki temu moduł mouse może je pobierać i odpowiednio obliczyć pozycję kursora.

Zwycięstwo! Było trochę frustracji, ale radość po pokonaniu problemów bardzo duża. Ostateczny bilans zadowolenia z pracy na plus 🙂 .

W kodzie powoli robi się mały bałagan, szczególnie w funkcji aktualizującej stan gry. Póki co jednak to kontroluję i zanim zacznę robić porządki chcę pododawać wszystkie zaplanowane funkcjonalności. Istnieje szansa, że będę musiał zmienić architekturę w miarę pojawiania się nowych elementów. Dlatego za refaktoryzację zabiorę się gdy wszystko będzie już zaimplementowane.

Póki co utrzymuje pół-spontaniczny stan produkcji. Czuję, że to właśnie w nim powstaje najwięcej kreatywnych pomysłów 🙂 .

To tyle na dziś. Jeżeli masz jakieś pytania lub uwagi, zachęcam do skorzystania z opcji dodania komentarza poniżej. Innym dobrym sposobem na kontakt ze mną jest moja strona na facebooku. Do przeczytania w kolejnym wpisie.

Dodaj komentarz

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