Implementowanie kamery / rzutni do gry 2D

21

Jaki jest najbardziej praktyczny sposób na wdrożenie kamery / rzutni w grze 2D?

Czytałem, że powinienem przechowywać pozycję świata obiektów zamiast pozycji względem ekranu?

Obecna sytuacja:

Zaimplementowałem prostą grę 2D, w której ładuję obiekty i poziomy z plików XML. Obecnie plik XML poziomu wygląda następująco:

<map>
   <tile obj="ground" x="0" y="555" />
   <tile obj="ground" x="16" y="555" />
   <tile obj="ground" x="32" y="555" />
   ...
</map>

Wszystkie obiekty mają „pozycję” wektora 2d, przechowującą ich bieżące położenie na ekranie.

Co chcę, żeby to było:

Ilustracja rzutni / gameworld

Na obrazie:

  • Aparat ma rozdzielczość 800 x 600 lub 640 x 480
  • Bloki i duszki mają wymiary 16 x 16 pikseli.
  • Świat rozmiar może się różnić
  • Współrzędne prawdopodobnie powinny być znormalizowane względem świata, a nie ekranu?
  • Pozycja rzutni względem x, y gracza i przesuwa się, gdy gracz osiągnie martwą strefę kamery (podobnie jak w tym filmie ).

Pytam pseudo przykłady / artykuły, ale jeśli chcesz wiedzieć, czego używam do programowania: SDL i C / C ++.

bluekirai
źródło
1
Dodaj swój trzeci link w komentarzach tutaj i mogę dodać go do twojego pytania.
MichaelHouse
Oto, co miałem na myśli z martwą strefą kamery: youtube.com/watch?v=89TRXUm8jMI
bluekirai
Witaj @Arthur Wulf White, chcesz opracować? Dzięki.
bluekirai,
Wspomniana kamera jest specyficzną wersją ogólnej kamery 2D, która służy tylko do przesunięcia widoku (bez obracania i powiększania). Zachowanie polegające na śledzeniu można wdrożyć, sprawdzając odległość między postacią gracza a kamerą, przesuwając kamerę, jeśli odległość jest zbyt duża.
wolfdawn

Odpowiedzi:

20

Musisz ustawić każdy obiekt względem świata zamiast ekranu. Twój aparat powinien mieć także swoje światowe współrzędne, aby można go było narysować we względnej pozycji na świecie. Może być również wygodne, aby kamera podążała za obiektem, więc gdziekolwiek on jest, kamera po prostu używa jego współrzędnych. Zazwyczaj współrzędne kamery ustawiają ją od lewego górnego rogu. Oznacza to, że kamera miałaby światową pozycję około (0,24) na zdjęciu .

Jeśli chodzi o rysowanie obiektów, które kamera może „zobaczyć”, należy narysować wszystkie obiekty względem współrzędnych świata kamery. Aby obliczyć pozycję ekranu obiektu względem kamery, po prostu wykonaj:

int screenX, screenY; //screen position of the object being drawn

screenX = object.x-camera.x;
screenY = object.y-camera.y;

Oczywiście niektóre obiekty nie są w rzeczywistości widoczne dla kamery, więc możesz zaimplementować system ograniczania widoku.

Dan Watkins
źródło
2

Wszystko to najlepiej zrobić w GPU przy użyciu macierzy World i View, a nie modyfikując miejsce rysowania obiektów na CPU.

W ten sposób możesz dowolnie zmieniać kamerę (nawet przybliżać i oddalać!), A ona po prostu magicznie zadziała. Nadal możesz wyświetlać wygładzanie, aby zaoszczędzić czas na losowaniu. I żaden kod do rysowania świata nie będzie musiał się zmieniać po prawidłowym skonfigurowaniu macierzy widoku i świata.

W SDL prawdopodobnie możesz po prostu wbudować wywołania OpenGL, takie jak glOrthoi glTranslate.

Zobacz ten wątek .

Mklingen
źródło
Czy ktoś może wyjaśnić opinię negatywną? To ma sens.
Hello World,
1
Nie oddałem głosu, ale myślę, że to dlatego, że to nawet nie odpowiada na pytanie. Pytanie dotyczy tego, jak coś obliczyć, a nie to, czy jest to bardziej wydajne czy łatwiejsze na GPU niż na procesorze. OP nawet powiedział, że szuka pseudo przykładów. Nie ma wątpliwości, że użycie kombinacji matryc kamery / świata / modelu byłoby bardziej wydajne, więc mklingen ma co najmniej rację.
Dan Watkins
Ta odpowiedź wcale nie jest zła! Jest bardziej specyficzny dla rozwoju OpenGL / DX, ale jest właściwym podejściem, ponieważ możesz po prostu obliczyć matrycę translacji na podstawie rdzeni kamery i przesuwać obiekty przez matrycę kamery, bez zmiany ich rzeczywistych pozycji.
nenchev