Autor Wątek: Przesuwanie mapy a zachowanie innych elementów (interfejs)  (Przeczytany 978 razy)

Offline qba10

  • Użytkownik

# Kwiecień 10, 2011, 23:19:53
Witam
Próbuje stworzyć mechanizm przesuwania mapy zbudowanej na kafelkach.
Pomysł mam taki:
powierzchnia ekran symbolizuje okno gry;
2 powierzchnia mapy która dowolnie przesuwam za pomocą blit
3 powierzchnia stała interfejsu: jej nie ruszam;

Na razie  w kodzie nie mam powierzchni interfejsu ( to tylko plany), ale mam problem z wdrożeniem idei z powierzchnia mapy; Nic mi nie wychodzi i nie wiem jak się za to zabrać (Próbowałem zrobić powierzchnie na której układam kafelki z sprita a potem za pomca Blit Surface umiescic ja na powierzchni ekran)

Czy możecie mi coś doradzić ?

Zamieszczam obrazek jak sobie to wyobrażam i kod źródłowy klasy Core (pętla główna) i Klasy Map (budowanie kafelek)

« Ostatnia zmiana: Kwiecień 10, 2011, 23:21:41 wysłana przez qba10 »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Karol

  • Użytkownik

# Kwiecień 11, 2011, 07:44:18
O ile dobrze zrozumiałem - chcesz narysować cała mapę i potem z tej wielkiej powierzchni kopiować fragment na ekran? Bad idea.

Rysuj kafelki z przesunięciem. W miarę przesuwania mapy (z dokładnością do px) wyliczasz przesunięcie kafla oraz piksela. Załóżmy, że chcesz przesunąć mapę o 100px. Wyliczasz wtedy od którego kafla zaczynasz rysować OffsetKafla = 100 div RozmiarKafla, oraz o ile przesunąć kafle OffsetPiksel = 100 mod RozmiarKafla. Pętla rysująca powinna mieć zakres od OffsetKafla do OffsetKafla + RozmiarKafla div WymiarEkranuGry + 1. W tej pętli każdy kafel jest rysowany na pozycji (ZmiennaPetli - OffsetTile) * RozmiarKafla - OffsetPiksel. Dla obu osi niezależnie takie wyliczenia.
« Ostatnia zmiana: Kwiecień 11, 2011, 09:40:55 wysłana przez Karol »

Offline Ivian

  • Użytkownik
    • Ivian's Cave

# Kwiecień 11, 2011, 09:18:42
Jeżeli rysujesz z dokładnością pixelową a nie na floatach, to będą Ci potrzebne zmienne offsetx i offsety.

Wtedy:

offsetx % tile_width = przesunięcie pierwszego kafla na 0X etc.
a inne obiekty rendedrujesz ze sprawdzeniem : if(object.x >= offsetx - max_object_width && object.x <= offsetx + screen_width) object.render();

Odradzałbym też renderowanie każdej warstwy na oddzielną bitmape. Dużo tracisz na wydajności. Rysuj wszystko na jednej powierzchni backbuffera.

Offline Pomnico

  • Użytkownik
    • Magic-Ars

# Kwiecień 11, 2011, 10:31:55
Przyłączam się do głosu kolegów. Rysuj bezpośrednio po powierzchni ekranu - nie tracisz wtedy ani pamięci na dodatkowe bitmapy, ani czasu na blit tego na ekran.

Powinieneś zaimplementować to mniej więcej tak, żeby gdzieś mieć wirtualne okno na świat gry - informację jaki obszar świata jest aktualnie widziany przez gracza. Wtedy rysujesz tylko te kafle widoczne przez takie okno, od razu dodając odpowiedni offset, aby wylądowały w odpowiednim miejscu ekranu.

Załóżmy że świat ma 1000x1000 kafli, każdy z nich ma rozmiar 30x30 pikseli. Wówczas świat ma 30Kx30K pikseli. Teraz załóżmy, że lewy górny róg ekranu jest w pozycji 165x135 pikseli.

Najpierw obliczasz, który kafel jest widoczny w lewym górnym rogu ekranu. Robisz to dzieląc pozycję x,y przez rozmiar kafla. Dostajesz 165/30 = 5 od lewej (licząc od 0, czyli de facto 6-ty kafel od lewej) i 135/30 = 4 od góry.

Teraz rysujesz wszystkie widoczne kafle zaczynając od tego górnego lewego (xstart, ystart to obliczone wcześniej 5 i 4):
for (y = ystart; y * 30 - 135 < screen_h; y++)
    for (x = xstart; x * 30 - 165 < screen_w; x++)
    {
        int posx = x * 30 - 165;
        int posy = y * 30 - 135;
        //blitujemy kafla x,y na ekran tak, aby lewy gorny rog byl w pozycji posx, posy
    }

Offset kafla to ujemna wartość lewego górnego rogu tego fragmentu świata, który widzi gracz. W warunku pętli for sprawdzamy, czy dany fragment jeszcze zaczyna się przed dolną / prawą krawędzią ekranu.