Ruch dla gier jest tym czym powietrze dla ludzi. Choć ludzie nie muszą o powietrzu wiedzieć nic by funkcjonować, Ty jako programista o ruchu w grach musisz wiedzieć wszystko. Ruch w grach ma niejedno oblicze. W poprzednim rozdziale przedstawiłem ruch w ujęciu w którym wiedzieliśmy dokładnie dokąd chcemy aby obiekt się nam przemieścił. W tym rozdziale zapoznamy się z inną filozofią, tj. wiemy w którym kierunku chcemy iść, ale nie wiemy jak długo.
Ruch w danym kierunku
Przypomnijmy sobie naszą strukturę z poprzedniego rozdziału:
struct RObiekt
{
double x;
double y;
double fPredkosc;
};
Do tej pory przemieszczaliśmy co klatkę obiekt z maksymalną prędkością
fPredkosc w osi X oraz w osi Y. Oznacza to, że jeżeli będziemy teraz chcieli co klatkę poruszać się w określonym kierunku to prędkość poruszania się w danej osi nie może być większa niż ta wartość. Taka informacja niesie za sobą pewne konsekwencje:
Gdy rozpoczynasz kodowanie gry to zazwyczaj nie wiesz w którym miejscu będziesz modyfikował położenie obiektów. W trakcie realizacji projektu często okazuje się, że mamy potrzebę modyfikowania położenia obiektów w różnych miejscach - raz będzie to mechanizm realizujący sztuczną inteligencję komputera, innym razem będzie to konieczność obsłużenia kolizji. Kontrolowanie każdorazowe poprawnej prędkości przemieszczenia obiektu nie powinno być więc realizowane w każdym miejscu gdzie będziemy mieli potrzebę zmiany pozycji. Mechanizm zapewniający poprawność przemieszczenia obiektów powinien być w jednym miejscu - wspólny dla całej logiki gry. Właściwym miejscem na realizację tego przedsięwzięcia jest oczywiście nasz obiekt, czyli struktura
RObiekt. Aby mechanizm przemieszczania spełnił nasze wymagania będzie wymagana jego mała przebudowa w następujący sposób:
struct RObiekt
{
double x;
double y;
double fPredkosc;
double ruchX;
double ruchY;
};
Dodane dwa nowe pola struktury będą odpowiadały za tzw. potrzebę przemieszczenia obiektu w danym kierunku. Można te wartości interpretować jako prędkość z którą chcielibyśmy przemieścić nasz obiekt w danym kierunku. Wartość tych zmiennych możemy aktualizować do oporu w trakcie jednej klatki - ważne jest, aby później zaktualizować pozycję obiektu tylko jeden raz na klatkę. Implementację metody przemieszczającej obiekt warto zaszyć wewnątrz struktury
RObiekt.
Implementacja przemieszczania obiektów
Napiszmy teraz metody, które spełnią nasze oczekiwania dotyczące przemieszczania obiektu. Obiekt nie może się poruszać szybciej niż wartość pola struktury
fPredkosc. Ponadto mamy mieć możliwość wielokrotnej zmiany decyzji w którym kierunku obiekt powinien się poruszyć. Metody, które realizują powyższe założenia mogą wyglądać tak:
void RObiekt::aktualizujPolozenie()
{
if( ruchX > fPRedkosc )
ruchX = fPredkosc;
if( ruchX <- fPredkosc )
ruchX = - fPredkosc;
if( ruchY > fPRedkosc )
ruchY = fPredkosc;
if( ruchY <- fPredkosc )
ruchY = - fPredkosc;
x += ruchX;
y += ruchY;
ruchX = 0;
ruchY = 0;
}
void RObiekt::przesun( int deltaX, int deltaY )
{
ruchX = deltaX;
ruchY = deltaY;
}
Po dodaniu powyższych metod do naszego kodu należy jeszcze zadbać o to by je wywoływać w odpowiednim miejscu. Przed rysowaniem wszystkich obiektów na scenie dodamy następujący kod:
for( VObiektyT::const_iterator i = vObiekty.begin(); i != vObiekty.end(); ++i )
i->aktualizujPolozenie();
Kod ten zapewni nam oczywiście przemieszczanie wszystkich obiektów na scenie. Zauważ, że w tym miejscu nie zajmujemy się już problemem 'gdzie obiekt ma się przemieścić', ponieważ każdy obiekt sam 'wie' gdzie ma się przesunąć.
Wprawianie wybranych obiektów w ruch
Kwestia, która pozostała nam jeszcze do omówienia to ustalanie kierunku w którym ma się obiekt przemieszczać. Sprawa jest banalna bowiem wystarczy wywołać napisaną wcześniej metodę
przesun w dowolnym miejscu kodu dla wybranego obiektu. Tak więc przesunięcie obiektu może wyglądać tak:
vObiekty[ 0 ].przesun( 0.5, 1.5 );
Pamiętaj, że w metodzie
przesun określasz prędkość z jaką ma się obiekt poruszać, a nie położenie do którego ma obiekt dojść.
Zadanie domowe
Zastosuj nowo omówioną wiedzę poprzez napisanie programu w którym będziesz przemieszczał wybrany przez Ciebie obiekt za pomocą strzałek na klawiaturze. Jeżeli nie wiesz jak sprawdzać stan wciśniętych klawiszy w bibliotece SFML, zapoznaj się z rozdziałem
Bezpośredni dostęp do klawiatury, myszy i joysticka.