Pobierz kod Giganty Świata 2D - część 2
GIGANTY ŚWIATA 2D część 2
MODEL ŚWIATA PROSTOKĄTNEGO- KAFLE MAPY GRY 2D
Witam zainteresowanych tematem tworzenia gigantycznych światów 2D. Poniżej gigantyczny las w gigantycznym świecie- tylko fragment. Cały obszar to 2500x2500 kostek (kafli). Na tyle pozwolił mi mój komp
Strach się w nim zgubić, nie mówię o oprogramowaniu takiego poziomu gry...ale dla chcącego nic trudnego. W omawianym przykładzie drzewa są losowo sadzone w mapie warstwy pierwszej. Żeby nie było, że giganty to ściema utworzyłem prymitywny edytor, przy pomocy którego można sobie porysować po warstwie zerowej a potem odpalić program i dojść- przesunąć świat do wybranego punktu. Przesuwanie świata odbywa się "strzalkami"
Jak utworzyć GIGANTYCZNY ŚWIAT 2D?
Nie jest to trudne. Przypuśćmy chcemy mieć poziom gry w świecie 2500x2500 kafli dla każdej warstwy. Przyjmujemy, że warstw będzie trzy. Dla jednej warstwy da nam to
2500 razy 2500 = 6 250 000 kafli ,
dla trzech warstw będzie trzy razy tyle - 18 750 000 sztuk
Żadna gra 2D napisana w sposób standardowy nie pozwoli nam zagrać w takim świecie, ba będzie się dusić już dla świata 250 x 250.
Otóż standardowe tworzenie światów 2D polega na tym, że:
a) tworzy się tyle kafli ile jest w całym świecie
b) do każdego kafla przypisuje się grafikę
c) wyświetlane są tylko kafle widoczne
d) inne założenia o których nie wiem
Co należy zrobić?
Posłużę się takim porównaniem:
Siedzimy w czołgu, kończy nam się ostatnia skrzynka piwa (ja po skrzynkę amunicji bym nie pojechał- uraz dwa lata służby w drużynie łączności 1 komp. amunicyjnej, 5-tego samodzielnego batalionu zaopatrzenia przy 5 dywizji pancernej, dobrze ze była to drużyna łączności, łączność z piwem trwała bez większych zakłóceń) świat jaki widźmy jest ograniczony do PARU OBRAZÓW, drogę do piwa mamy w głowie- czyli MAPĘ. Nasza głowa pamięta obrazy jakie są przypisane do ścieżki dojścia do piwa...
Co z tego porównania wynika?
Jeżeli ekran komputera potraktujemy jako wizjer peryskopu a mapę wraz z informacjami o obrazach przelejemy z "głowy" do tablicy to możemy zbudować nowy model świata 2D- model GIGANTA
a) tworzymy tyle kafli ile mieści się w "wizjerze"
b) w mapie pamiętamy informacje o obrazach (konkretnie ich indeksy, pozostałe dane niesie ze sobą obraz, który jest załadowany w OmegaImageList)
c) tworzymy "nowy" sposób przesuwania świata oparty na czymś w rodzaju taśmociągu
I to jest z grubsza opisany cały pomysł. Teraz po kolei rozwinę podpunkty a, b i c
Ad a) tworzymy tyle kafli ile mieści się w "wizjerze"
Powiedzmy, że dla naszej gry ustalamy rozdzielczość 800x600 i podstawowy wymiar kości kafla na 64x48 pikseli. Z prostego rachunku wynika, że zmieści się nam
- w poziomie: 800 div 64 = 12 kafli
- w pionie : 600 div 48 = 12 kafli
Uzyskane wartości należy zwiększyć o 3 co da nam układ 15x 15. Czyli 225 kafli na warstwę. Jeżeli planujemy umieścić coś w rodzaju panelu gry na przykład u dołu ekranu. Powiedzmy o wysokości 96 pikseli pozwoli nam zmniejszyć ilość kafli w wierszach z 15 na 13. A więc w jednej warstwie będzie 15x13 = 195 kafli. Dla trzech warstw będzie to tylko 195 x 3 = 585 lub 225 x 3 = 675 (a to dużo mniej niż 6 250 000). I to nie zależnie czy świat będzie o rozmiarze 100 na 100 czy 2500 na 2500 . W moim modelu ważne jest aby nie budować światów mniejszych od granicznej ilości wyliczonej z przyjętej rozdzielczości i rozmiaru kafla.
Można zadać pytanie : Dlaczego zwiększamy rozmiar o 3?
Zwiększamy tylko ze względu na niepożądany efekt widoczności przerzucania obrazów w skrajnych kolumnach i wierszach. Skrajne kolumny i wiersze ustawiamy poza granicami ekranu monitora.
W artykułach o "Wędrówkach w świecie 2D" opisałem ze głębię kości (współrzędna Z) dobieram na podstawie numeru wiersza w którym dana kość się znajduje. Tu również to zastosowałem (patrz kod programu). W e wspomnianych artykułach opisałem powód takiego postepowania.
Ad b) w mapie pamiętamy informacje o obrazach (konkretnie ich indeksy, pozostałe dane niesie ze sobą obraz, który jest załadowany w OmegaImageList
Dla każdej warstwy tworzymy mapę świata. Czyli informację o indeksach użytych obrazów. I bardzo ważne jeżeli w danej komórce mapy świat nie istnieje obraz wstawiamy -1 (minus jeden). Co ten zabieg nam daje? Otóż nie będziemy rysować kafla który w danej chwili ma wartość indeksu obrazu ustawioną na minus jeden. Procedura DRAW kości warstwy nie będzie wykonana- zyskamy na prędkości gry.
procedure TKostkaMapy.Draw;
var
Rect:TRect;
begin
if fSiatka then begin
Image.Renderer.OmegaScreen.DrawRectangle(Round(x+1),Round(y+1),Round(x+DAneMApy.W1Kosc-1),Round(y+DAneMApy.H1Kosc-1),
false,1,125,125,125);
exit;
end;
//nie rysuj jesli indeks wskazuje na -1
if (ImageIndex=-1)then exit;
Image.Draw(Round(x+left),Round(y+top),0,0.5,0.5,1,1,Red,Green,Blue,Alpha,ImageIndex,0);
end;
Najczęściej takie pustostany występują w warstwie obiektów i gadżetów.
Ad c) tworzymy "nowy" sposób przesuwania świata oparty na czymś w rodzaju taśmociągu
Ten kto śledził ruch kości w programie dołączonym do części pierwszej, zauważył ze kość- kafel wykonuje ruch w ograniczonym obszarze. Jeżeli dojdzie do ustalonego punktu (patrz część pierwsza) to wraca na miejsce startu. Jest to bardzo ważna cecha mojego modelu- mogę powiedzieć rewolucyjna :-) Taki "kaczy" ruch wymaga zapamiętania współrzędnych punktu "uwięzienia" kafla. W kodzie programu pamiętają to zmienne x0, y0 każdej kości warstwy.
Indeks:=RogX+RogY*DaneMApy.XCount;//Pole mapy swiata
x0:=a*DaneMapy.W1Kosc +RogSwiata.x;//przesun o poczatkowe polozenie rogu swiata
y0:=b*DaneMapy.H1Kosc +RogSwiata.y;//przesun o poczatkowe polozenie rogu swiata
dx:=0;
dy:=0;
Ale wracam do opisu ...
Gdy pojedynczy kafel dojdzie do granicznego miejsca ma i musi (w woju było MAMUSI:) zostawić obraz i wrócić do współrzędnych startu x0, y0. Fakt zostawienia obrazu wiąże się z przekazaniem go sąsiadowi czy to lewemu, prawemu, górnemu lub dolnemu. To zależy w jakim kierunku przesuwamy świat. Przekazanie polega na przerzuceniu indeksu i kilku innych parametrów związanych na przykłada z kolorem (RGB) lub animacją. Zmiana ta wykonywana jest w
tej procedurze należącej do klasy bazowej utworzonych kafli
procedure TKostkaMapy.ZmianaKlatki;
begin
//jak w granicach świata to ustal indeks komórki w mapie świata
if (RogX>-1)and(RogY>-1)and
(RogX
else begin
ImageIndex:=-1;
exit;//wsykocz bo jetses poz swiatem
end;
//załaduj nowy obraz i nową klatkę tego obrzau, odczytaną z mapy świata
Image:=DaneMapy.OmegaImageList.ImageList.Items[Pmapa(Lista.Items[idWskMApy])^[indeks].idObrazka];
ImageIndex := PMapa(Lista.Items[idWskMApy])^[indeks].idKlatka;
//uswta nowe wartości Red, Green, Blue, Alpha jakie niesie w sobie nowa komórka mapy świata
RGBA;
end;
UWAGA:
Mapy warstw to tablice dynamiczne do których odwołuję się poprzez wskaźnik (patrz kod programu)
I to by było na tyle co do GIGANTÓW 2D w układzie prostokątnym . W następnej części opiszę GIGANTY IZOMETRYCZNE