Witam wszystkich czytających ten artykuł, w którym chciałbym podzielić się pewnym pomysłem, jaki można zastosować do gry 2D w przypadku jeśli chcemy podzielić się monitorem :). Spodziewany efekt końcowy widoczny jest na poniższym zrzucie działającego przykładu.

Oczywiście omawiane rozwiązanie jest przedstawione w DELPHI plus OMEGA. Grafika do przykładu została pobrana z www.strefatg.be Komponenty, jakie będą potrzebne są widoczne na poniższym rysunku

Za podział ekranu na dwie części odpowiedzialne są te zaznaczone – czyli OmegaSurface.

Ale po kolei.

1. Ustawiamy parametry podziału ekranu.

Przyjmujemy rozdzielczość na 800×600 (ustawiamy to w Object Inspector komponentu OmegaScreen), stąd każdy z graczy będzie mieć do dyspozycji ekran o wymiarach 400×600 pikseli. Załatwimy to w tej procedurze:

Tu chciałbym zwrócić uwagę, że linię podziału uzyskamy w możliwie prosty sposób – współrzędną prawego ekranu ustawimy nie na 400 ale na 401. Czyli: OmegaSurface2.x:=401; O jej kolorze zadecydują parametry czyszczenia głównego (całego) ekranu : OmegaScreen1.ClearScreen(0,0,0,0), którą wywołujemy w „zegarze” aplikacji.

2. Algorytm rysowania pojedynczego ekranu można wykonać według kroków:

Czyść ekran
Ustaw świat dla gracza
Rysuj świat

Rysowanie na obu ekranach odbywa się w tej procedurze (pełna postać w kodzie przykładu):

Dlaczego OmegaSprite1.Draw? a to tylko dla tego, że nasz świat oparty jest na kostkach (20×20) klasy TSprite. Jeśli to rozwiązanie zastosujemy to nie musimy w pętli rysować naszego świata (załatwi to za nas procedura Draw komponentu OmegaSprite) i mamy bazę wyjściową do testowania kolizji (której w tym przykładzie nie uwzględniam). Oczywiście możemy zastosować komponent OmegaMap na podobnych zasadach lub możemy obsłużyć rysowanie świata w pętli korzystając z OmegaImageList…Te problemy są na inny temat.
Ważnym elementem w naszych rozważaniach jest ta procedura: UstawSwiatWedlugGracza(). Jak ona działa?

3. Działanie procedury: UstawSwiatWedlugGracza()

Zadaniem tej procedury jest odpowiedni przesuwać świat w ekranach obu graczy w uwzględnieniem zmiany pozycji gracza pierwszego względem gracza drugiego. Inaczej mówiąc typowe zastosowanie transformacji Galileusza- znajdź współrzędne poruszającego się układu w innym poruszającym się układzie…

Ciało wspomnianej procedury:

Na uwagę zasługują te linie:

Gdzie zmienna Gracz.EkranX to stała wartość względnego przesunięcia obu ekranów. Wynosi ona 400 pikseli wzdłuż osi X. Na osi Y – to 0. Jest ona ustalana w momencie tworzenia graczy. Dla gracza lewego podajemy zero a dla gracza prawego 400 (patrz do procedury tworzenia gracza w kodzie programu). Zmienne Gracz.xMapy i Gracz.yMapy przechowują informację o ile pikseli przesuną się każdy z graczy w swoim świecie. Ponadto należy zwrócić uwagę na to, że gracz w swoim ekranie wyświetlany jest na środku, to świat jest przesuwany względem „duszka” gracza.
Jako, że ta sama procedura została zastosowana dla dwóch graczy użyłem najprostszego pomysłu ich rozróżnienia- po nazwie własnej (GraczA, GraczB).
Omawiana procedura jest wywołana dwa razy, podczas odświeżania ekranu lewego a następnie ekranu prawego.

I to by było na tyle o tworzeniu dwóch ekranów. Pozostałe elementy kodu programu to procedury tworzenia losowej mapy świata, duszków graczy i klawiszologia . Omawiany przykład nie uwzględnia zmiany współrzędnej „Z” duszka, kolizji, pilnowania dopuszczalnej granicy ruchu itp. Problemy te są przedstawione w przykładach dołączonych do komponentu Omegi.

Na zakończenie mogę jeszcze wspomnieć, że ten pomysł można zastosować do rysowania mapy świata gry. Tylko należy utworzyć jeden pomocniczy mały ekran o wymiarach przeskalowanego świata (gra była by rysowana w OmegaScreen1 zaś mapka w OmegaSurface). Choć myślę że nie jest to jedyne rozwiązanie…Ale od czego są pomysły :). No i oczywiście jak się pomyśli to można znacznie przyśpieszyć rysowanie światów i to ogromnych światów. Może kiedyś zdradzę swój pmysł…

Pozdrawiam oksal

Autor: oksal

Załączniki