O czym tym razem będzie? Ano o kolejnych przemyśleniach dotyczących światów 2D. GIGANTYCZNYCH ŚWIATÓW 2D.Tak ogromnych jak tylko pamięć komputera pozwoli i wola chęci oprogramowania pojedynczego poziomu do takiej gry. Artykuł ma też i drugi ukryty cel: DELPHI TO POTĘGA. Jeśli ktoś mówi Ci że C lub CPP zasługuje na uwagę to ma rację, ale jak przy tym krytykuje inne języki to jego zdanie jest nie wiele warte. Każdy język pozwala bardzo dużo wycisnąć z kompa… w jednym robi się to łatwiej, w drugim trudniej. Zasady są te same, stąd też treści zawarte w tym cyklu na pewno będą przydatne dla każdego, kto chce napisać grę 2D.

Jako że pomysł jest dość cenny zastrzegam sobie prawa autorskie i bez zgody autora nie pozwalam zamieszczać artykułu na innych serwisach niż www.unit1.pl

Tu chcę podkreślić ze omawiany model będzie 3 warstwowy. Gdzie każda warstwa może być zbudowana z kafli 25×25 lub 2000×2000 sztuk a nawet więcej. Wymiary kafli od 32×32 pikseli do 256×256. Jak kto woli. Mój leciwy komp- Duron 800, 512 MB RAM-u radzi sobie z 3 warstwami 2500×2500 dla kafli 64×48 pikseli wyśmienicie, FPS ponad 120, czas budowy losowego świata około 10 sekund. Im większy wymiar kafla w pikselach tym FPS będzie lepszy, który i tak jest bardzo dobry bo od 100 FPS wzwyż.

Temat planuję omówić w 3 częściach

1. opis modelu pojedynczej kości (kafla) warstwy świata 2D
2. przykład giganta mapy świata prostokątnego
3. przykład giganta mapy świata izometrycznego

Może też być omówiony gigant modelu świat opisanego prze zemnie w „Górach i dolinach świata 2d”. Nie obiecuję bo coraz bardziej nie lubię komputerów, wolę łódki strugać

Czas zacząć…

MODEL POJEDYNCZEJ KOŚCI WARSTWY ŚWIATA 2D

Poniżej rysunek przedstawia dwie kości świata 2D. Pojedyncza kość ma wymiar 64 x 48 pikseli. Proszę zwrócić uwagę, że drewniana (ma to być kasztelania:) budowla jest większa niż wymiar kafla.

Strzałki z klawiatury umożliwiają ruch warstw

Jakie zdania są stawiane na kość takiego świata:

a) musi umieć się poruszać
b) musi istnieć możliwość przyjęcia obrazu większego niż przyjęty rozmiar kafla
c) nie może być rysowana gdy nie zawiera obrazu
d) musi reagować na zmianę kolorów i kanału przezroczystości (Alpha)
e) może być animowana
f) może istnieć test kolizji
g) … i różne inne pomysły

Spełnienie wszystkich zadań najłatwiej jest zrealizować tworząc klasę bazową pojedynczej kości warstwy. W kodzie programu jest ona zapisana w warstwa_cz1.pas

Serce bohatera artykułu zostało podane. Teraz pokrótce omówię realizację zadań wymienionych w podpunktach a, b…

Ad a) musi umieć się poruszać

Proszę teraz odpalić program i wcisnąć klawisze strzałek. Zauważymy, ze warstwa wcale nie porusza się po całym ekranie ale jest uwięziona. Ruch kości jest ograniczony. Kość może przesunąć się w lewo, prawo o odcinek nie większy niż jej szerokość, a w górę lub w dół o odcinek nie większy niż jej wysokość. Po czym wraca na swoje miejsce. Konkretnie do zmiennych

wartość przesuwu pamiętana jest w

Procedury reagujące na ruch to:

Wywołane w

Nie opisuję tego bo to zbyt proste. Jedynie nadmienię, ze

To zmienne globalne decydujące o przesuwaniu świata zgodnie z życzeniem gracza

Tu chce podkreślić znaczenie programowania obiektowego. NIE MA SENSU PRZEKAZYWANIA WARTOŚCI SkokX, SkokY do każdej kości z osobna w jakiś tam pętlach. Jest to ogromy błąd który spowalnia silnik gry. To załatwia główna metoda ojca (nie biologicznego) naszych kości

OmegaSprite1 jest ojcem dla TSimpleAnimSprite, czyli naszej kości

TKostkaMapy=class(TSimpleAnimSprite)

Ad b) musi istnieć możliwość przyjęcia obrazu większego niż przyjęty rozmiar kafla

Bardzo ważna cecha. Spełnienie tego warunku pozwala osadzać w świcie budynki w całości. Jedynie należy rozwiązać problem justowania takiego obrazu. Rozwiązanie jakie ja przyjąłem jest bardzo proste i idealnie pasuje do drzew. Dla kasztelani należało by je zmodyfikować- co nie jest trudne. Idee justowania przedstawia poniższy rysunek poglądowy

jak widać w kaflu 64×48 pikseli należy umieścić obraz o innym rozmiarze, tu 120×86 pikseli. Justowanie dotyczy warstw 1,2 i tak dalej. W kodzie programu zrobiłem to w momencie załadowania obrazka lub jego zmiany w kaflu warstwy pierwszej. Czyli wykonujemy to tymi liniami

Wyliczone wartości są przechowywane w zmiennych klasy kafla to jest w

Left
Top

A wykorzystuje się je w procedurze rysowania

Podejście bardzo proste.

Ad b) nie może być rysowana gdy nie zawiera obrazu
c) musi reagować na zmianę kolorów i kanału przezroczystości (Alpha)

To można omówić razem. Kość nie będzie rysowana gdy indeks obrazu wynosi –1 (minus jeden). Zmian kolorów Red, Green, Blue pozwoli nam uzyskać na przykład efekt nocy w poziomie gry. A wszystko to robimy tak

Ad e) może być animowana

To zostawiam własnej inwencji twórczej. Należy przerobić odpowiednie przykłady dołączone do komponentu OMEGI. Można zastosować te rozwiązania bo nasza kość jest oparta na klasie TSimpleAnimSprite

TKostkaMapy=class(TSimpleAnimSprite)

Ad f) może istnieć test kolizji

Tu należy zadać sobie pytanie:

Czy warto wykrywać kolizję z drzewem lub budynkiem metodą testu pikseli?

Moim zdaniem nie. Metoda ta przy dużej ilości drzew da się nam we znaki. Spowolni grę. Dalej: poza niewidoczną części świata gry nie jest wykonywana. Jej użycie będzie bez sensu dla „automatów”. Jak ktoś czytał moje arty o „Wędrówkach w świecie 2D” to może pamięta, ze wprowadziłem tam tablicę siatki drogi. Test kolizji będzie tylko wykonywany przez obiekty ruchome i polega na sprawdzeniu : jest /brak. Stąd też kolizje należy wykonywać w klasach obiektów żywych. W warstwach nie…Ale to jest moje zdanie i nie każdy musi je podzielać.

Na tym kończę część pierwszą. Kiedy powstaną kolejne tego nie wiem. Co prawda odpowiednie przykłady programów dla modelu świata 2D prostokątnego i izometrycznego są gotowe. Brakuje tylko tekstu…

Pozdrawiam oksal

Zbylitowska Góra 3.01.2007

Autor: Oksal

Załączniki