Gra 2D, część 11: Edytor poziomów cz. 1
15.03.2011 - Marcin Milewski
Nowe funkcje w klasie LevelGłównym zadaniem edytora jest modyfikowanie poziomu. Zatem będziemy musieli dopisać kilka metod, które do tej pory nie były potrzebne. Pierwszą z nich jest zapisywanie pól planszy do pliku. Zadanie z kategorii tych łatwiejszych: iterujemy po dwuwymiarowej tablicy i zapisujemy wartość każdego pola do pliku. Każdy wiersz poziomu kończymy znakiem nowej linii -- z punktu widzenia gry nie jest to konieczne, bo białe znaki i tak są pomijane przy wczytywaniu. Pozwala to jednak przeglądać poziom w dowolnym edytorze tekstu, a kosztuje nas naprawdę niewiele dodatkowej pracy. Zauważmy, że przedstawiona poniżej implementacja formatuje wyjście tak, aby każde pole zajmowało 5 znaków. Wymaga to dołączenia nagłówka iomanip w pliku StdAfx.h
Siostrzaną funkcją, zapisującą dane dotyczące poziomu, jest SaveEntitiesToFile. Zapisuje ona informacje o jednostkach, bonusach, położeniu gracza, itp. Jej implementacja również jest prosta:
Do tej pory tylko odczytywaliśmy dane z pliku, więc nie potrzebowaliśmy funkcji, które w jakiś sposób manipulowałyby instancją klasy Level. Najważniejszą funkcjonalnością edytora poziomów jest możliwość zmiany wybranego pola na inne. Realizują to poniższe wiersze kodu:
Kolejne dwie metody będą manipulowały szerokością poziomu. Pierwsza obsłuży sytuację, kiedy użytkownik zechce dodać nowe pola za ostatnim klockiem po prawej stronie. Należy wtedy zwiększyć szerokość poziomu, jeżeli jest zbyt mała. Aby zwiększyć szerokość poziomu zwiększamy rozmiar każdego wiersza. Metoda EnsureWidth nie może zmniejszyć szerokości poziomu (zapewnia rozmiar równy co najmniej przekazanemu argumentowi). Na razie nie chcemy obsługiwać innej wysokości poziomu niż standardowa, czyli 20 klocków.
Do zmniejszania szerokości poziomu wykorzystamy drugą ze wspomnianych metod manipulacji poziomem -- ShrinkWidth. Jej zadaniem jest przycięcie rozmiaru poziomu do wskazanego przez użytkownika. Specjalną wartością parametru jest 0 -- poziom powinien zostać przycięty automatycznie, czyli do najdalszego pola. Dlaczego nie bierzemy pod uwagę encji? Dlatego, że wydaje się to niepotrzebne -- czym kierowałby się projektant poziomu umieszczając np. bonus poza ostatnim polem? Gracz prawdopodobnie i tak nie mógłby z niego skorzystać (przypomnijmy, że aby przejść poziom należy wejść w pole typu FT::EndOfLevel), o estetyce takiego poziomu nie wspominając. Oto kod metody ShrinkWidth:
Ostatnim usprawnieniem klasy Level będzie możliwość utworzenia nowej instancji na postawie już istniejącej, ale podając własną listę jednostek oraz encję gracza. Implementacja jest prosta, gdyż polega na przepisaniu wartości większości pól z przekazanej instancji klasy Level. Pozostałe pola wypełniamy wartością argumentów. Należy zadbać o sortowanie encji w poziomie. Oto odpowiedni kawałek kodu:
Nagłówki nowych metod należy dodać do pliku Level.h. Jego uaktualnioną zawartość można zobaczyć w kodzie końcowym dołączonym do tego artykułu. |
Copyright © 2008-2010 Wrocławski Portal Informatyczny
design: rafalpolito.com