30.04.2016

Odświeżanie animacji

Obiekt animacji typu tileSeq zawiera wskaźnik do okna (poprzez wskaźnik do aktualnej ramki actualVO), w którym ma być wyświetlany, za pomocą funkcji theWindow::redrawField. Po upływie czasu przerwy między przejściami ramek, wyświetlana i odświeżana jest kolejna ramka, poprzez funkcję składową tileSeq::draw(). Indeks tej ramki ustalany jest za pomocą sumy wartości zmiennej actualFrame w aktualnej sekwencji i zmiennej nextFrame. Jeżeli zmienna nextFrame ma wartość ujemną wtedy taka animacja będzie odtwarzana wstecz.

Jeżeli aktualna ramka osiągnie indeks graniczny, dla jej sekwencji, wtedy aktualny indeks ustawiany jest na początek w tej sekwencji (w przypadku zapętlonej animacji), lub jest wstrzymywana cała animacja (poprzez wyłączenie timera dla tego obiektu).

29.04.2016

Funkcja do sprawdzania obszaru wspólnego dwóch przestrzeni dwuwymiarowych

Funkcja do obliczania obszaru wspólnego dwóch przestrzeni dwuwymiarowych, w tym projekcie, użyta jest do sprawdzenia czy wyświetlany obiekt wizualny nie wychodzi poza okno lub widzialny obszar do odświeżenia zmian (taki obszar nie musi mieć rozmiarów całego okna). W przyszłości będzie też potrzebna do detektora kolizji.

Definicja tej funkcji znajduje się w "engine2d\resources.cpp", a jej deklaracja wygląda następująco:

bool jointField( _POS f1x, _POS f1y, _SIZE f1w, _SIZE f1h, _POS f2x, _POS f2y, _POS f2w, _POS f2h, _POS& jf1x, _POS& jf1y, _SIZE& jfw, _SIZE& jfh );

Pierwsze osiem argumentów tej funkcji to pozycja i rozmiary obydwu obszarów. Kolejne argumenty referencyjne zawierają wynikowy obszar wspólny, czyli jego pozycję (jf1x, jf1y) względem pierwszego obszaru, oraz szerokość i wysokość (jfw, jfh).
 

23.04.2016

Inicjacja timera animacji

Rozpoczęcie animacji następuje po wywołaniu funkcji składowej tileSeq::start(). Funkcja ta dodaje timer, który po upływie czasu (podanego w zmiennej interval) generuje programowe zdarzenie wychwytywane w pętli głównej (każde zdarzenie jest przetwarzane według kolejki dodania). Obsługa zdarzenia animacji jest realizowana za pomocą funkcji attendProgEvents w "events_prog.cpp", która inicjuje renderowanie ramki w określonym oknie.
Implementacja timera zależy od użytej biblioteki. W przypadku tego projektu jest to SDL_AddTimer, który umieściłem w inline'owej, zuniwersalizowanej funkcji o nazwie _ADD_TIMER. Organizację kodu w aspekcie systemu operacyjnego omówiłem już we wcześniejszej notce.

22.04.2016

Dodanie animacji do macierzy sektorów

Animacja jako obiekt typu tileSeq jest zdefiniowana w "engine2d\resources.h". Zawiera kontener z ramkami typu _SURFACE, identyfikator animacji, wektor z sekwencjami, aktualnie ustawiona sekwencja, położenie i wskaźnik do aktualnie wyświetlanej ramki.
Pojedyncza sekwencja zwiera informacje - od której do której ramki odtwarzać określoną animację. Każda animacja może być wyświetlana na wiele sposobów np. od końcowej do początkowej ramki, albo np. od ramki piątej do osiemnastej i właśnie do tego służą sekwencje.
Tworzenie obiektu animacji może przebiegać na dwa sposoby. Pierwszy, poprzez konstruktor z podaną ścieżką do pliku mozaiki, z której ma zostać utworzona animacja. Drugi sposób, poprzez użycie funkcji składowej tileSeq::prepare( tileSet* t ). Przypomnę, że obiekt typu tileSet zawiera kontener z już załadowanymi powierzchniami RGBA (typu _SURFACE). Domyślnie jest tworzona jedna sekwencja: od ramki pierwszej (z indeksem 0) do ramki ostatniej.
Dodanie takiej animacji do macierzy sektorów (w celu jej przyszłego wyświetlenia), w określonym oknie, na konkretną pozycję, odbywa się za pomocą funkcji theWindow::putSeqOnMatrix.

16.04.2016

Fizyka mapy

Obecnie, każda jednostka mapy zawiera flagi informujące:
* czy przez ten sektor można przemieścić cokolwiek (nie tylko pojazd gracza);
* czy w tym sektorze znajduje się przedmiot, który można zabrać do inwentarza;
* czy w tym sektorze znajduje się obiekt, który można przemieścić;
* czy w tym sektorze znajduje się dziura;
* czy podłoga tego sektora to ruchoma platforma wodna;
* czy obiekt znajdujący sie na podłodze może eksplodować.

Początkowe stany flag są ustawiane w funkcji theLevel::buildMap przy konstruowaniu mapy z zasobów.

15.04.2016

Przydział podłogi przy budowie mapy

Format zapisu mapy (opisany wstępnie tutaj) jest dwuwymiarowy, więc funkcja odpowiedzialna za konstruowanie mapy musi sama rozpoznać, które jej elementy są położone na podłodze (czyli musi być dodana podłoga, w niższej macierzy sektorów), a które stanowią jej poziom. Część programu odpowiedzialna za tą czynność umieszczona jest w theLevel::buildMap w "level.cpp".
Przykładowa mapa "tutorial 1" z rozmieszczonymi na niej elementami, wygląda w ten sposób:
Zamiast:

10.04.2016

Przygotowanie wizualnych elementów mapy

Niektóre obiekty na mapie nie są identyczną kopią tego co znajduje się w pliku zasobów grafiki. Dlatego trzeba je najpierw odpowiednio przygotować przed umieszczeniem ich w kontenerze kafli mapy.

Np. ruchome platformy:
mogą być skierowane w różnych kierunkach, więc trzeba utworzyć ich obrócone, o odpowiednią liczbę stopni, odpowiedniki.

W przypadku przejść kierunkowych oprócz obrotu strzałki:
trzeba też nałożyć na siebie jej obraz z samym typem przejścia, np.:


 Wszystkie te sprawy są zebrane w funkcji pomocniczej prepareMainTiles w "resources_constructor.cpp".