Piszemy grę -
podstawy
Jest wiele metod pisania gier. Pisząc prostą grę
nie trzeba się bawić w obiekty i enginy ale jeżeli naszym celem jest
bardziej złożony projekt musimy przybrać inny styl. Właśnie engin
jest czymś co ułatwia prace i zapobiega różnym wpadkom. Engine jest to
właściwie system, na którym opiera się działanie gry. Dzielimy go na
mechanizm spritów(lub logiczny jak to wolni), mechanizm mapy i inne mniej
istotne rzeczy. W tym artykule znajdziecie informacje jak się zabrać do
pisania enginu. W tekście występują fragmenty kodu w języku
Pascal(Delphi). Jeżeli w trakcie czytania stwierdzisz, że nie czaisz o
co chodzi to radzę przerwać i zaczerpnąć trochę informacji na temat
Object Pascala.
Projekt
Pierwszą rzeczą jaką trzeba zrobić jest uzmysłowienie
sobie co chcemy tak naprawdę napisać. Trzeba przybrać założenia odnośnie
mapy i postaci w grze. Co i jakie ma mieć możliwości. Załóżmy, że
chcemy napisać jakąś prostą platformówkę. Pierwsza sprawa to mapa.
Mape można opisać przy pomocy dwuwymiarowej tablicy(np. array of array
of byte;). Na razie nie posuwamy się dalej ponieważ trzeba ustalić
kwestie postaci. Trzeba zaplanować odpowiednie klasy np.:
TSprite=class
x,y:integer; // położenie na ekranie
alive:boolean; // czy żyje
// Kod procedur na razie sobie darujemy
end;
Przydał by się jeszcze jakiś system zarządzania
tymi spritami(wykrywanie kolizji, sprawdzanie czy żyją, rysowanie itp.).
Ta kwestia będzie opisana w dalszej części artykułu, ponieważ ciężko
ją pokrótce wytłumaczyć.
Każdy mechanizm powinien a nawet musi znajdować się w osobnym
unicie(module) np. mapa.pas, sprites.pas itp. Warto wspomnieć, że jest
coś takiego jak komunikacja pomiędzy mechanizmami. Najmądrzejszym rozwiązaniem
jest ustalenie jakiejś hierarchii... sprajty > mapa. Oznacza to, że
mechanizm sprajtów może pobierać i zapisywać dane z mechanizmu mapy.
Mapa ma jedynie kontrolę nad sobą.
Mapa
Implementacje proponuję zacząć od mapy. Mapa
powinna być klasą(kłania się Object Pascal). Najprostsza deklaracja może
wyglądać tak:
TMapa=Class
Pola:array [1..5,1..50] of byte; // 0- pustka 1- sciana
procedure draw(canvas:TCanvas);
end;
Pominąłem wiele rzeczy(np. odczyt z pliku),
ponieważ nie są one na razie istotne. Dzięki tablicy pola każdy sprajt
będzie wiedział czy może wejść na dane pole. Jako urozmaicenie(właściwe
niezbędnik) można dodać trzeci wymiar tej tablicy.
W jednej przestrzeni będą zapisane informacje o polach a w drugiej
informacje np. o reprezentujących je rysunkach( np. nr bitmapki).
Sprajty
Bazując na tym co już jest napisane można wziąć
się za mechanizm sprajtów. Implementacje zaczynamy od deklaracji klas
reprezentujących dany rodzaj postaci. Wygląda to tak, że najpierw
deklarujemy jakąś klasę podstawową(np. TSprite) a później jej
pochodne(np. TPlayer(TSprite) i TEnemy(TSprite)). Każda z tych klas ma
mieć jedną istotną metodę. Jej działanie polega na wywołaniu
procedur takich jak np. rysowanie, AI itd.(wszystkie procki tzw. cyklowe).
Ja ją nazywam finalizująca daną klasę. Może wyjaśnię to w inny sposób.
Załóżmy, że podczas każdego cyklu(jakiejś pętli lub timera)
napiszemy:
Sprajt.sprawdz_klawisze(klawisze);
Sprajt.move;
Sprajt.rysuj(canvas);
Procedure finalizująca wywoła te wszystkie
procedury. Teraz można się zabrać za mechanizm spritów. Zazwyczaj jest
on po prostu klasą. Uproszczona deklaracja będzie wyglądała tak:
TPostac=record
name:string;
case rodzaj: (rEnemy,rPlayer) of
rEnemy:enemy:TEnemy;
rPlayer:player:TPlayer;
end;
TSpriteEngine=class
sprajty:array of TPostac;
procedure sprites; // finalizuje wszystkie postacie z tablicy
procedure add;
procedure delete;
procedure search;
end;
Tak to mniej więcej wygląda. Nie przytaczam kodu
procedure, gdyż zajęło by to zbyt wiele miejsca
Komunikacja
Jak to jest z tą wspomnianą komunikacją? Przede wszystkim chodzi tu oto
aby sprajty widziały się na mapie. Np. Jeżeli dana postać jest
kontrolowana przez gracza to wpisuje to tablicy z mapa np. -1 i wszyscy
przeciwnicy wiedzą kogo mają atakować oraz gdzie on się znajduje. Jest
to bardzo proste rozwiązanie i bardzo polecam jego używanie.
Podsumowanie
Różnie bywa z ludźmi, którzy piszą gry.
Niektórzy porzucają projekty, gdyż brak im wytrwałości(np. trafili na
jakiś problem). Większość problemu bierze się z braku koncepcji. Na
początku zawsze pisze się łatwo, dopiero później zaczynają się
schody. Mam nadzieje, że to nad czym się męczyłem przez 1,5h pomoże w
rozwiązaniu problemów. Jeżeli macie jakieś uwagi lub pytania to walcie
śmiało na moją skrzynkę.
GREG
warsztat@poczta.fm
http://www.warsztat.px.pl |