• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[SFML 2] Optymalizacja ładowania mapy kafelkowej

0 głosów
251 wizyt
pytanie zadane 8 listopada 2015 w C i C++ przez GameProgrammer Obywatel (1,150 p.)
Mam mapę kafelkową, wiele z tworzonych obiektów różni się jedynie położeniem na mapie. Obecnie mam ładowanych około 1000 obiektów samego tła. Muszę to zoptymalizować, więc wpadłem na pomysł że przy wczytywaniu obiektów z pliku, po prostu będę wpisywał wszystkie pozycję na których ma się wyświetlić sprite, i wczyta je do sf::vector2f w jakimś kontenerze. Ale jak wygląda sprawa z kolizją:

if(entity.getGlobalBounds().intersects(sprite.getGlobalBounds()))

funkcja pobiera pozycję kafla przy uwzględnianiu kolizji, czy więc powinienem te linijkę zastąpić własnym kodem, który uwzględni w pętli for pozycję danych obiektów?

I czy właściwie moje rozwiązanie jest dobre, czy proponujecie coś innego?
Dodam jeszcze że wczytywanie kafli działa na tej zasadzie:

[(BITMAPID:Bg)(POSITION:0,0)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]
[(BITMAPID:Bg)(POSITION:100,200)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]
[(BITMAPID:Bg)(POSITION:40,560)(RECT:0,0)(TILESIZE:32,32)(COLLISION:1)]

tak bym dodał coś takiego:
[(BITMAPID:Bg)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)(POSITION:0,0)(POSITION:100,200)(POSITION:400,580)]

1 odpowiedź

+1 głos
odpowiedź 8 listopada 2015 przez niezalogowany
Musisz nieco szerzej wyjaśnić co chcesz zoptymalizować.

Masz 1000 obiektów samego tła, co przez to rozumiesz? Masz 1000 różnych grafik repreentujących różne tło, czy 1000 rysowanych kafli (wtedy rysujesz kafle wielowarstwowo: na początku rysujesz kafla tła, później na nich inne kafle reprezentujące obiekty, ...)?
komentarz 8 listopada 2015 przez GameProgrammer Obywatel (1,150 p.)
edycja 8 listopada 2015 przez GameProgrammer
Mam na razie obiekty StaticTile, dla tłą ustawiam po prostu kolizję 0.

Tak więc w pozycji 0,0 ładuję pierwszy kafel:

[(BITMAPID:Bg)(POSITION:0,0)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]

i wypełniam tym samym spritem cały ekran,czyli tworzę kolejno 1000 takich obiektów, bo tak to wychodzi mniej więcej na cały ekran:

[(BITMAPID:Bg)(POSITION:0,0)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]

[(BITMAPID:Bg)(POSITION:32,0)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]

[(BITMAPID:Bg)(POSITION:64,0)(RECT:0,0)(TILESIZE:32,32)(COLLISION:0)]

itd.

Te obiekty nie różnią się niczym, tylko pozycją wyświetlanego sprite, nawet sprite jest ten sam, Więc głupie jest tak bez sensu tworzyć 1000 obiektów. Więc chcę tworzyć po jednej instancji każdego obiektu, jeżeli różni się tylko pozycją na mapie,

 

Kafle rysują się warstwowo, w zależności od tego kiedy zostały wczytane.
komentarz 8 listopada 2015 przez niezalogowany

Hmm, sprytnie. Myślisz dobrze, jeżeli będziesz robił to wg schematu:

  • ustaw sprite na pozycji
  • rysuj
  • .... (aż zapełnisz cały poziom)
  • display();

To faktycznie mając jedynie 1 sprite'a jesteś w stanie pokryć cały obszar, niegłupie. Chociaż dla bardziej różnorodnego tła zrobi się nieco bardziej problematyczne, ale pomysł jest dobry.

Te 1000 kafli jest zawsze widoczne na ekranie, czy jakieś są poza kamerą?

komentarz 8 listopada 2015 przez GameProgrammer Obywatel (1,150 p.)
Tło będzie różnorodne, może to być równie dobrze 200 tych samych kafli które się powtarzają. Akurat na mapie testowej jest 1000 kafli tła, do tego jeszcze ze 100 bloków z kolizją, też się powtarzają. No ale powiedzmy jeżeli tło będzie różnorodne to stworzy się 5 obiektów i będę je kopiował na inne pozycje zamiast tworzyć 1000 osobnych dla samego tła. Zmniejszy to ilość obrotów pętli, już nie będzie 1000 razy sprawdzało kolizji, tylko jak jest collision 0, to po prostu ominie te kafle, a jak collision 1 to wtedy dopiero sprawdzi na wszystkich pozycjach. Nic nie wychodzi poza kamerę.
komentarz 8 listopada 2015 przez niezalogowany
Mimo wszystko masz sporą oszczędność.

Kolizja w SFML nie jest sprawdzana na sprite'ach, a na FloatRect (czyli obiektach czysto logicznych), więc wystarczy że prechowasz informację o pozycji colliderów i w razie potrzeby ustawisz wartości do FloatRect.

Na pewno myślisz w dobry sposób, można ten cały system napisać albo dobrze, albo źle. Więc proponuję ci teraz napisać sobie jakiś kod, który sprawdzi zużycie pamięci, czas wykonania, ... teraz, a także będzie to robił po wszlekich zmianach dzięki czemu będziesz wiedział czy czegoś nie skopałeś.

Na pewno zmniejszych zużycie zajmowanej pamięci przez obiekty, pytanie jak się zmieni wydajność i czas obliczeń, możesz się w sumie później pochwalić rezultatami bo jestem ciekawy.
komentarz 8 listopada 2015 przez GameProgrammer Obywatel (1,150 p.)
W sumie to nie wiem jak napisać kod na sprawdzenie zużycia pamięci.
komentarz 8 listopada 2015 przez niezalogowany
komentarz 8 listopada 2015 przez GameProgrammer Obywatel (1,150 p.)
Obecne zużycie RAMu jest według mnie spore:

http://screenshot.sh/mFdCdWr5U3RWI

Podobne pytania

0 głosów
1 odpowiedź 378 wizyt
pytanie zadane 1 października 2017 w C i C++ przez Jakub 0 Pasjonat (23,100 p.)
0 głosów
3 odpowiedzi 161 wizyt
pytanie zadane 8 stycznia 2016 w HTML i CSS przez Bakr Mądrala (6,880 p.)
0 głosów
1 odpowiedź 127 wizyt
pytanie zadane 6 sierpnia 2021 w C i C++ przez tonn204 Mądrala (7,170 p.)

89,693 zapytań

138,297 odpowiedzi

309,243 komentarzy

59,623 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...