fizyka wzory prawa zadania teoria, chemia teoria zadania wzory, modelarstwo szkutnicze
tworzenie gier wędrowanie w świecie gry 2d część3 2d2_3.jpg

Pobierz kod Wędrowanie w świecie 2D- część 3

 
WĘDROWANIE W ŚWIECIE 2D (część 3)


Odsłona trzecia
 
tworzenie gier wędrowanie w świecie gry 2d część3 2d3_1.jpg
 
W świecie 2D pojawił się ruch ZIELONYCH i zakazał chodzenia po leśnym runie. Zbudowano drogi... Nasz bohater może tylko chodzić po tych drogach. Zostaje nam go nauczyć tej sztuki

Tak, więc stanęliśmy na kolejnym i ostatnim problemie, jaki zapowiedziałem w części pierwszej. Oczywiście nie zamyka to problemu wędrowania w świecie 2D, ale zamyka podstawowy problem tego cyklu artykułów- zmianę koloru duszka bohatera stojącego za przeszkodą.

Wprowadzamy sieć dróg

W naszym świecie drogi będziemy pamiętać w odpowiedniej tablicy. Tablicy warstwy 0 (zerowej)- podstawowej. W części drugiej jest to ta tablica mapaWarstwa0:array[0..19,0..19], zapisana jako stała w swiatUnit2.pas i wypełniona samymi zerami. Wartość zero odpowiadała indeksowi obrazu-klatki trawy, która jest przechowywany w OmgeaImageList1. W omawianych przykładach posłużyłem się prostym podejściem. W przyjętym modelu założyłem, że:
a) klatka gruntu ma wymiar 64x32
b) drogi będą nakładane w warstwie 0 (zero)
c) obraz całego gruntu (trawa, drogi) jest zawarty w jednym pliku graficznym załadowanym do OmegaImageList- stąd też klatki dróg muszą być tego samego wymiaru co klatka gruntu (64x32)

W praktyce realizacja podpunktu c przedstawiona jest na poniższym zrzucie ekranu.
tworzenie gier wędrowanie w świecie gry 2d część3 2d3_2.jpg
Ważne, aby we właściwościach TileWidth i TileHeight podać wymiary klatki. Pozwoli to wycinać interesujące nas klatki z obrazu gruntu. Zliczanie klatek przebiega wierszami od lewej do prawej.
W kodzie programu robimy to w momencie tworzenia warstwy



//wartswa gruntu
.. Warstwa0[w,k]:=TKostka.Create(OmegaSprite1,OmegaImageList1.ImageList.Items[0],MapaWarstwa0[w,k]);
..
Tu podam odpowiednie indeksy klatek, które są zapisane w tablicy MapaWarstwa0.
//******ODPOWIEDNIKI INDEKSOW***********
0- TRAWA
1- SKRZYZOWANIE DROG
2- DROGA W POZIOMIE
3- DROGA W PIONIE
4- DROGA ZAKRET W LEWO GORNY
5- DROGA ZAKRET W PRAWO GORNY
6- DROGA ZAKRET W LEWO DOLNY
7- DROGA ZAKRET W PRAWO DOLNY
//*********************



W części drugiej wprowadziliśmy dodatkową tablicę do przechowywania występowania pni drzew. W tej części można z tej tablicy zrezygnować(zakładamy, że nasz duszek chodzi tylko po określonych kostkach siatki mapy). Ja jednak zostawię wspomnianą tablicę. Można pokusić się, aby wprowadzić do lasu polany (ciemniejszą lub jaśniejszą trawę), na które będzie mógł bohater spokojnie wejść. Taka tablica, może również przechowywać informacje o podstawie budynku, jaki stoi w świecie 2D (chodzenie za budynkiem). Zastosowanie może być różne.

Aby nauczyć naszego bohatera chodzenia po drogach wystarczy teraz odczytać wartość indeksu przechowywanej klatki w polu, w jakim znajduje się gracz. Załatwimy to tak



procedure TGracz.MoznaIsc;
begin
//Sterowanie Graczem
stareX:=x;
stareY:=y;
if oisUp in Form1.OmegaInput1.keyboard.states then//idz do gory
SkokY:=SkokY+1;
if oisDown in Form1.OmegaInput1.keyboard.states then//idz w dół
SkokY:=SkokY-1;
if oisRight in Form1.OmegaInput1.keyboard.states then//idz w prawo
SkokX:=SkokX-1;
if oisLeft in Form1.OmegaInput1.keyboard.states then//idz w lewo
SkokX:=SkokX+1;

x:=x-SkokX;
y:=y-SkokY;
JakaKostka;
//sprwdz czy mona byc w nowej pozycji jak nie to zeruj skok
if(Drogi[wd,kd]>-1)or(MapaWarstwa0[w,k]=0)//mozna ten warunek tak zorganizowac aby dac wszystko do
//tablicy Drogi, dla części trzeciej właściwe by było: if MapaWarstwa0[w,k]=0
then begin
SkokX:=0;//
SkokY:=0;//
end;
//ustwa gracza w starej pozycji
x:=stareX;
y:=stareY;
end;




W tym miejscu chciałbym powiedzieć jak sprawdzam czy można iść. Zapamiętuję stare położenie gracza. Zwiększam skok przesuwu mapy, ale jej nie przesuwam. Przesuwam gracza (bez ruchu obrazu gracza) o zadaną wartość(ze znakiem minus w stosunku do skoku mapy świata), sprawdzam czy może być w nowym miejscu. Jeśli tak, to nie zeruję skoku mapy, w przeciwnym wypadku zeruję. Uwaga! zawsze ustawiam gracza na poprzedniej pozycji. Ponieważ przesuwamy światem a nie duszkiem. Duszek bohatera zawsze jest w tych samych współrzędnych liczonych względem górnego lewego rogu monitora.

Tyle nowości w części trzeciej.

Pisząc treść części pierwszej obiecałem wspomnieć o sugestiach związanych z przyspieszeniem działania kodu gry jeżeli sprawdzamy test kolizji używając procedury onCollision. Ta procedura znacznie spowalnia działanie kodu gry jeśli mamy kilkanaście lub więcej obiektów z tak ustawionym testem kolizji. Aby przyspieszyć działanie takiego rozwiązania można ustawiać lub zwalniać test kolizji dla ograniczonego obszaru. Na przykład problem strzelania. Duża liczba pocisków, dla których sprawdzamy kolizję z określonym typem obiektów, które przebywają w klatce obecności pocisku. Najwygodniej taką zmianę umieścić w procedurze Move konkretnej klasy obiektu. Poniżej przedstawiam najprostsze rozwiązanie, które w omawianych przykładach jest "wycięte" z kodu (ujęte w nawiasach klamrowych). Rozwiązanie to ustawia test kolizji dla drzewa, które znajduje się w tej samej kolumnie, co gracz i w wierszu o różnicy 0,1,2 względem wiersza przebywania gracza.



procedure TRoslina.Move(const MoveCount:single);
begin
inherited Move(MoveCount);
//przykład prostej metody usuwania testu kolizji
{if (k=TGracz(Gracz).k)
and
(w-TGracz(Gracz).w<=2)
then
DoCollision:=true else
DoCollision:=false;}
end;



Podsumowując

Przedstawione pomysły mogą być wyjściem do tworzenia czegoś w rodzaju obszarów terenu. Otóż FPS wzrasta jeśli operujemy dużymi klatkami gruntu siatki mapy (powiedzmy 128x64 lub 256x128). Mamy mniej do wyświetlenia "kostek". Taką kostkę można sobie podzielić na mniejsze obszary (załóżmy 32x32), dla których to będziemy losować na przykład występowanie drzew. Inaczej mówiąc w jednej kostce 128x64 możemy posadzić drzew: (128 div 32)*(64 div 32)=4*2=8 drzew. Czyli uzyskujemy gęsty las. Wprowadzając odpowiedni współczynnik zalesienia możemy regulować gęstość obiektów żyjących na jednej kostce gruntu (w omawianych przykładach losowałem jedno drzewo na środku kostki gruntu). To rozwiązanie może posłużyć i do budynków jak i dróg czy też śladów, jakie pozostawił po sobie przejeżdżający pojazd (powiedzmy ślady takie to TSprite żyjący 3- 5 minut). Zastosowań może być wiele. Na pewno nasz kod będzie dużo szybszy niż byśmy podzielili świat na kostki 32x32. Stracimy dużo pamięci na grunt i wymusimy więcej operacji graficzny
ch. Oczywiście nie są to jedyne pomysły na przyspieszenie wykonywania kodu gry. Nie chcę tu niczego sugerować. Najlepszą metodą jest stworzenie wstępnego modelu naszego świata i sprawdzanie gdzie można przyspieszyć nasz kod. Tworzenie jak najmniejszej liczby pętli, stosowanie wskaźników itp. Kod omawiany w tych częściach tego nie zawiera, nie jest to, bowiem główny cel tego tematu.

Koniec części trzeciej

Alkomat- wirtualny test

Alkomat- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
Olinowanie stałe- kalkulator średnic

Olinowanie stałe- darmowa aplikacja na Androida

Pobierz ze sklepu Google Play
przepis na gogfry

Przepis na gofry

zobacz
przepis na bitą śmietanę

Przepis na bitą śmietanę

zobacz