Upload
filip-sobalski
View
474
Download
1
Embed Size (px)
Citation preview
WstępElementy składowe
Całość
Programowanie gier 2DPodstawowe koncepcje
Filip Sobalski
30.03.2011
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Wszystko to iluzja
Cel: Jak oszukać gracza?Jak uzyskać efekt, który będzie zgodny z wyobrażeniami graczanajmniejszym nakładem obliczeń i pamięci.
Czyli...Wszystkie chwyty dozwolone – liczy się tylko efekt.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Duszki i inne potworności
Sprite
W dosłownym tłumaczeniu znaczy „duszek”. Podstawowy elementgraficzny, czyli - w skrócie - obrazek, który zmienia położenie. W nowychimplementacjach to będzie obiekt zawierający także wszystkie informacjeo postaci, potworku czy innym elemencie gry.
Sprite Engine
Odpowiada za rysowanie Sprite’ów, zwykle także za ich animację,detekcję kolizji, etc... Kiedyś implementowany sprzętowo, teraznajczęściej przez oprogramowanie.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Grafika
1 Wstęp
2 Elementy składoweGrafikaRuchDetekcja kolizji
3 Całość
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Bit blit
Bit-blitting
Blokowy (vide: scanlines) transfer danych z obrazka źródłowego dodocelowego (zwykle bufor graficzny) często z użyciem operatorarastrowego (ROP). ROP to nic innego jak operator bitowy - AND, OR,XOR.
Zwykle użyjemy do tego biblioteki korzystającej wyłącznie z CPU (np.SDL) lub zlecimy rysowanie wyspecjalizowanemu sprzętowi (np.OpenGL).
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przezroczystość
maskowanieNajpierw rysujemy 1-bitową maskę z operacją AND a potem w tymsamym miejscu rysujemy właściwy obrazek z operacją OR. Danypiksel może być przezroczysty lub nie.
colorkeyUżywane przy grafice z paletą. Wybieramy indeks palety, który mabyć przezroczysty i każdy piksel źródłowy o tej wartości jestignorowany przy blitting’u.
alpha blendingDziś to najczęściej stosowane rozwiązanie. ROP zastępujemyoperatorem matematycznym mieszającym kolory z uwzględnieniemdodatkowego kanału alpha.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przezroczystość - maskowanie
Rysunek: 1-bitowa maska
Rysunek: rezultat poszczególnych kroków maskowania
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przezroczystość - colorkey
Rysunek: sprite przygotowany do metody colorkey
Uwaga!
Stratna kompresja w przypadku sprite’ów i masek to zło!
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przezroczystość - alpha blending
Mieszamy składowe piksli w proporcjach określonych przez kanał alfa.
s - piksel źródłowyd - piksel docelowy
k ∈ {R,G ,B}dk , sk , sA ∈ [0, 1]
blended componentk = dk × (1− sA) + sk × sA
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Kolejność rysowania - warstwy
Stała ilość warstw - dla każdej warstwy osobna lista sprite’ówDowolna ilość warstw - nr warstwy przypisany do sprite’aSortujemy co klatkę. [stabilny algorytm sortowania]Każdego nowego sprite’a wstawiamy w odpowiednie miejsce. [a’lainsertion sort]
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Viewport clipping
Viewport
Zwykle zdefiniowany przez położenie bezwzględne (w układzie wsp.świata) i wymiary; określa, który fragment sceny widać na ekranie.
Rysujemy tylko te sprite’y, których aktualne obrazki nakładają się na naszviewport. Wygodnie tutaj zastosować bounding box ale o tym później.
Położenie pod którym narysujemy sprite’a to prostu różnica wektorowajego położenia i położenia viewportu. Warto jednak wyróżnić sprite’yktórych położenie będziemy definiować względem viewportu - użytecznedo wyświetlania punktacji, ilości naboi etc.
Uwaga
W każdej klatce rysujemy wszystko od nowa. Można rysować tylko toco zmieniło się od ostatniej klatki, jednak dziś nie ma sensu stosować tejtechniki.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Podwójne buforowanie
Podwójne buforowanie razem z synchronizacją pionową (v-sync)rozwiązuje problem tearing’u.
1 Narysuj w buforze off-screen scenę.
2 Zamień miejscami wartości wskaźników pokazujących na buforoff-screen i display.
3 Narysuj na ekranie bufor display w momencie kiedy monitor skończyłrysować poprzednią klatkę ale nie zaczął następnej.
W praktyce wszystkim zajmie się biblioteka. Nas interesuje buforoff-screen oraz musimy pamiętać o wywołaniu funkcji typu SwapBufferspo narysowaniu sceny.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Ruch
1 Wstęp
2 Elementy składoweGrafikaRuchDetekcja kolizji
3 Całość
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Dyskretyzacja ruchu
Jak?Dlaczego nie ma już w obudowach przycisku turbo?
Lag
Czas w sekundach mierzony od ostatniej klatki.
Skalujemy wszystko przez lag.
Caveat
Nawet jeśli nie rysujemy z podpikslową precyzją wszystko trzymamy wefloat’ach! Obcinamy wtedy kiedy potrzebujemy int’a.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Animacja
frame ← frame + animation speed × lag
Nie obcinamy części ułamkowych!
Zawijamy: (lub odbijamy w przypadku oscylacji)
i f ( f rame >= t o t a l f r a m e s )frame −= t o t a l f r a m e s ;
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Animacja - wyrównywanie klatek
Sposób nr 1Każda klatka (obrazek) animacji ma tę samą wielkość. Położenie sprite’aokreślamy względem stałego punktu obrazka (np. lewego-górnego rogu -[0, 0]).
Sposób nr 2Każda klatka animacji ma określony punkt względem którego będziemyją pozycjonować na ekranie - nazwijmy go grab point. Znajdujemy punktodniesienia na naszym animowanym obiekcie i jego pozycja w każdejklatce będzie stanowiła grab point.Sposób nr 2 jest rozszerzeniem sposobu nr 1.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Grab point
Ten punkt będzie wydawał się stać w miejscu podczas animacji.
Rysunek: przykładowe umieszczenie gp
Gdzie rysujemy lewy-górny róg sprite’a?~sprite screen pos ← ~sprite pos − ~frame gp
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przemieszczenie
Prędkość to nie problem...~sprite pos ← ~sprite pos + ~sprite velocity × lag
Co z przyśpieszeniem?~sprite velocity ← ~sprite velocity + ~sprite accelleration × lag
Przykład - grawitacja~sprite velocity ← ~sprite velocity + (0, gravity)× lag
Czy widać tutaj jakiś problem?
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przybliżenie...
Rysunek: 10 FPS
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Przybliżenie... c.d.
Rysunek: 30 FPS
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Detekcja kolizji
1 Wstęp
2 Elementy składoweGrafikaRuchDetekcja kolizji
3 Całość
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Bounding box
Szybki test BB vs. BB
Często wystarczy jako jedyna metoda detekcji kolizji
Dobra metoda dla pierwszej fazy (pruning)
Kiepsko aproksymuje kształty.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Bounding circle
Szybki test BC vs. BC i BB vs. BC
Dobrze nadaje się do aproksymacji tylko niektórych kształtów, np.pocisków
Dobra metoda dla pierwszej fazy
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Per-pixel collision test
Bardzo powolny test, nawet z bitmaską
Nienaturalny efekt
Ze skalowaniem i obrotem to koszmar
Tylko vs. per-pixel
Tylko do drugiej fazy
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Ograniczenie wielokątami wypukłymi
Relatywnie szybkie
Łatwo dowolnie przekształcić
Tylko do drugiej fazy
Jak? Separating Axis Theorem
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Ograniczenie wielokątami
Co z wklęsłymi?
1 Podziel na trójkąty (tesselacja)
2 Zachłannie łącz z powrotem w wypukłe wielokąty.
3 Dla każdego wielokąta z otrzymanego zbioru wylicz bounding box idodaj kolejną fazę...
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Co robimy kiedy nastąpi kolizja?
Przewidujemy kolizję z wyprzedzeniem ;)
Cofamy do poprzedniej pozycji - kiepski efekt przy dużej prędkości
Cofamy się małymi kroczkami wzdłuż wektora przemieszczenia ażkolizja przestanie zachodzić
Jeśli metoda detekcji pozwala to liczymy wektor „zagłębienia” iodejmujego go od pozycji. (Wielokąty FTW!)
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Potencjalne problemy
Niski framerate i/lub duża prędkość - jeden sprite przeskoczy drugi.Nie ma dobrego rozwiązania. Można ruch pomiędzy klatkamisprowadzić do postaci ciągłej.Zakleszczenie:
1 Zmiana klatki animacji na „większą” w trakcie kolizji/zaraz pocofnięciu. (Częste przy teście per-pixel.)
2 Błędy zaokrągleń.3 Dwa sprite’y poruszające się na raz.
Specjalne przypadki - np. gracz spada na płaską powierzchnię czychodzi po niej, ślizganie się, etc.
Niska wydajność.
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Wydajność, wydajność, wydajność...
Naiwne podejście - sprawdzić każdy obiekt z każdym - nieakceptowalniepowolne przy dużej liczbie obiektów.Propozycje:
Wykluczyć z testów obiekty dla których detekcja kolizji nam jest niepotrzebna.
Podzielić obiekty na klasy i wykluczyć z testów pary klas, które napewno nie będą kolidować lub włączyć jedynie te pary, którychkolizja nas interesuje.
Indeksowanie przestrzenne - np. quadtrees (octrees w 3D), siatkaobszarów.
Przy skomplikowanych testach dodać więcej faz (ale nie za dużo!).
Liczyć przekształcenia tylko w ostatniej fazie.
Zrezygnować z powyższych sposobów detekcji kolizji jeśli specyfikagry na to pozwala. ;) (KISS)
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
GrafikaRuchDetekcja kolizji
Quadtree
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Ograniczenie ilości FPS
Prosty sposób - sleep/delay w głównej pętli - nie skaluje się.
Uniwersalny sposób - sleep/delay adaptujący się do czasu wykonaniapętli
I zapewne wiele innych...
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Adaptive Frame Limiter
void A d a p t i v e F r a m e L i m i t e r : : onFrame ( ){
f l o a t d i f f = ( 1 . 0 f / m maxFps ) − m lag ;f l o a t d e l a y = d i f f + 0 . 9 f ∗ m l a s t D e l a y ;
m l a s t D e l a y = d e l a y ;
i f ( d e l a y <= 0 . 0 f ) return ;
m pSystem−>d e l a y ( ( d e l a y ∗ 1000 .0 f ) ) ;}
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Główna pętla
1 Wyczyść bufor graficzny
2 Uaktualnij stan wejścia
3 Uaktualnij timery synchroniczne
4 Wylicz nową pozycję sprite’ów + logika (+zaznacz sprite’y dousunięcia i zapisz te do dodania)
5 Sprawdź kolizje (+zaznacz sprite’y do usunięcia i zapisz te dododania)
6 Usuń zaznaczone sprite’y
7 Dodaj sprite’y w kolejce
8 Narysuj sprite’y
9 Podmień bufory (swap buffers)
10 Poczekaj chwilę aby ograniczyć FPS
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
Więcej?
1 Diagram klas
2 Jakaś demonstracja
3 Kompensujący timer synchroniczny
4 Podsystem wejścia
Filip Sobalski Programowanie gier 2D
WstępElementy składowe
Całość
...
Dziękuję za uwagę.
Filip Sobalski Programowanie gier 2D