Mapa kafelkowa: większe kafle

Witam Was w prezentacji/poradniku/opisie przykładowe klasy, która będzie obsługiwała wyświetlanie mapy kafelkowej, w której obiekty mogą być reprezentowane jako 1 obrazek, ale jednocześnie zajmują więcej niż 1 kafel. Będę tutaj korzystał z pseudo kodu, chociaż niewykluczone, że pojawi się jakiś kod w SFML’u (ale tylko wtedy jeżeli będziecie chcieli).

Przedstawienie problemu

Tak jak wiemy w mapie kafelkowej, mapa składa się z pojedynczych kafelków i przykładowy plik tekstowy z jego reprezentacją może wyglądać w ten sposób:

A po jego wyświetleniu możemy otrzymać coś takiego:

 

I tutaj nie mamy problemów z implementacją tego bo każda cyfra w naszym pliku tekstowym oznacza że w tym miejscu znajduje się dokładnie 1 kafelek o takich samych rozmiarach. Jednak co jeżeli posiadamy kafelek, który zajmuje miejsce np. 2 kafelków? Wtedy możemy go oczywiście podzielić na mniejsze 2 kafle, czyli traktować to jako dwa niezależne pola i w zasadzie mamy po kłopocie, jednakże musimy dodać kolejne pole do naszego kodu, czyli odpowiednik dla jednej i drugiej połowy obiektu.

Obiekt składający się z 2 kafli

Problem pojawia się przy obiektach, które składały by się z większej ilości kafli, średnio wygodnie takie kafle się ustawia  bo trzeba dopasować je odpowiednio w edytorze map.

Ja poniżej przedstawię propozycję rozwiązania, które pozwoli nam na wczytanie obiektów większych niż rozmiar 1 kafla jako 1 większy obiekt bez konieczności dzielenia go na kafelki, a także bez zbędnego dzielenia go w kodzie na np lozko_gora i lozko_dol.

 

Rozwiązanie problemu

Oczywiście to w jaki sposób ja przedstawię Wam rozwiązanie tego problemu jest rozwiązaniem jednym z wielu, ja jedynie chcę Wam pokazać inne spojrzenie na ten problem.

Na początku musimy uzgodnić jakie informacje chcemy przechować w każdym kaflu. Na pewno potrzebujemy informacji o tym jakiego jest typu.

Przydałaby nam się też w nim informacja czy może nasz kafel nie jest po prostu kontynuacją innego kafla i należy go pominąć pry ustawianiu na nim tekstur.

Możemy oczywiście także dodać tutaj informacje o tym czy dany kafel jest ścianą, pułapką, etc. Czyli możemy tutaj dodać wszelkie przydatne informacje o nim potrzebne do naszej gry.

Przedstawienie zapisu wartości dla zwykłego kafla oraz obiektu o wielkości 2 kafli, które ma kolidować z graczem

Teraz czas na wczytanie poziomu z pliku oraz ustawieniu odpowiednich wartości dla każdego kafla. Oczywiście można to zrobić w specjalnie napisanej do tego klasie, ale my napiszemy to w zwykłej funkcji main().

W kodzie powyżej wczytujemy w standardowy sposób poziom kafelkowy, który może wyglądać chociażby tak:

Wizualizacja mapy zapisanej powyżej

Kolejnym dość ważnym krokiem jest ustawienie odpowiednio wartości dla każdego rodzaju kafla, flaga multitile oznacza czy ten kafel należy pominąć przy wczytywaniu tekstur tak abyśmy nie ustawili 2 razy tej samej tekstury przez co moglibyśmy otrzymać taki efekt jak na screenie poniżej, gdzie nastąpiłoby ustawienie sprite’a łóżka 2 razy, które zostałoby także zasłonięte przez kolejny kafel przy rysowaniu.

Dwukrotne wczytanie tekstury łóżka

Ostatnim krokiem jest ustawienie odpowiednich sprite’ów i wyświetlenie ich na odpowiednich pozycjach, tutaj jedyne co musimy zrobić to sprawdzić czy dany kafel ma wartość multile oznaczoną na true, jeżeli tak to pomijamy go i nie ustawiamy na nim żadnej tekstury. Resztę, czyli jego pozycję itd. ustawiamy w odpowiedni sposób dla swojej biblioteki (poradnik dla SFML).

 

Podsumowanie

Jak widzimy w dość łatwy sposób możemy napisać taką klasę, wymaga ona jedynie zrozumienia w jaki sposób są rysowane kolejne obiekty (w jakiej kolejności).

Dajcie znać co sądzicie o poradnikach pisanych przy użyciu pseudo kodu. W razie niejasności, problemów, pytań piszcie w komentarzach piszcie.

Zobacz kod na GitHub


  • terminatorek

    Lepiej jak piszesz normalnym kode 😀

    • Kod w tym stylu ułatwia mi wiele, bo nie muszę się trzymać np. SFML’a, ale nawet jeśli to ten kod łatwy byłby w implementacji w SFML’u. W artykułach tego typu raczej chodzi o przekazanie idei niż o pozostawienie gotowego kodu, tak trzeba jednak pomyśleć dlaczego kod jest w takiej postaci 😉