Odciążenie procesora z obliczeń ogromnej pętli

0

Obliczam mnóstwo warunków w pętli for, gdyż potrzebuję tego do rysowania mapy, która składa się z kafelków.
Mapa jest to tablica dwuwymiarowa o danej szerokości i wysokości, przykładowo 10x3:

int[][] map = {
 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 { 1, 1, 0, 0, 1, 0, 1, 1, 1, 0 },
 { 2, 1, 2, 2, 1, 2, 2, 2, 1, 1 }
};

Tekstura to obraz 512x1024 z czego każdy "kafelek" jest w wymiarach 32x32, co analogicznie daje nam 16 kolumn i 32 wiersze tekstur o wymiarach 32x32, jest to 512 wartości (ID) i każdą z tych wartości komputer sprawdza przy pomocy if'a:

public void rysuj(Texture tekstura, int[][] mapa){
    for(int y = 0; y < 3; y++){
        for(int x = 0; x < 10; x++){
            int ID = 1; // Pierwszy kafelek (0,0)
            for(int IDy = 0; IDy < 32; IDy++){
                for(int IDx = 0; IDx < 16; IDx++){
                    if(mapa[y][x] == ID) draw(tekstura, IDx*0.0625f, IDy*0.03125f, IDx*0.0625f+0.0625f, IDy*0.03125f+0.03125f, x*32, y*32, x*32+32, y*32+32);
                    ID++; // Przechodzimy do kolejnej kolumny (16,0), (32,0), (48,0) itd.
                }
            }
        }
    }
}

To jest wycinek (kafelek 32x32) z całej tekstury (512x1024):
IDx*0.0625f, IDy*0.03125f, IDx*0.0625f+0.0625f, IDy*0.03125f+0.03125f

Komputer ma spore zadanie (przy mapie 25x5 komputer używa 40% CPU, a mapy będą większe). Komputer ma 30 kafelków mapy (10x3), każdy z tych kafelków musi zostać sprawdzony jakie ma ID (spośród 512 ID danej tekstury), wyciąć go i narysować. FPSy na moim komputerze trzymają się równo 60, ale bez tego procesu, komputer używa niecałe 8% CPU, a 32% na samo rysowanie malutkiej mapy jest dość sporym obciążeniem.

Jestem ciekaw czy jest jakiś prostszy sposób rysowania kafelkowej mapy, niż mój, czy jest jakiś sposób bardziej optymalny? Zużywający mniej procesora?

0

Co ty właściwie robisz? Czemu masz aż 4 pętle for? Przy takiej mapie powinny być tylko dwie!
WTF: for(int IDy = 0; IDy < 32; IDy++) , for(int IDx = 0; IDx < 16; IDx++)

Nie powinno być to tak (mniej więcej, nie wiem czym to właściwie rysujesz):

public void rysuj(Texture tekstura, int[][] mapa){
    for(int y = 0; y < 3; y++){
        for(int x = 0; x < 10; x++){
            double idx = (mapa[y][x]%16)*SzerokscKafelka;
            double idy = (mapa[y][x]/16)*WysokoscKafelka;
            draw(tekstura, idx, idy, idx + SzerokscKafelka, idy+WysokoscKafelka, x*32, y*32, x*32+32, y*32+32);
        }
    }
}

Słyszałeś o czymś takim jak Magic Numbers?

0

Dwie pierwsze pętle sprawdzają X i Y mapy, a dwie kolejne (z IDx i IDy) sprawdzają X i Y tekstury.
Przykładowo:
x = 0; y = 0; czyli pierwszy kafelek mapy i do tego kafelka sprawdzana jest tekstura co 32x32 pikseli:
IDx = 0; IDy = 0; czyli 1 kolumna i 1 wiersz, dalej IDx = 1; IDy = 0; czyli 2 kolumna i 1 wiersz, i tak dalej aż przeleci do IDx = 16 i IDy = 32; wraca do x i y, jest x = 1; y = 0; czyli drugi kafelek mapy i robi to samo, czyli sprawdza teksturę.

Jest to okropne, wiem, strasznie komputer obciąża, ale nic innego nie wydumałem ^^, dlatego poszukuję innego, lepszego - bardziej optymalnego sposobu ;/

Chodzi mi mniej więcej o taki efekt:
user image

W tle są tile'sy, gdzie np. ID = 1 to trawa, ID = 2 to woda, itd.

0

Lekcja na dziś: Map<K,V> bo mam wrażenie że to rozwiązałoby twoje chore problemy...

0

Ten twój rysunek jest źle pomyślany. Pamiętaj, że kafelki powinny się ładnie łączyć, a to znaczy, że będziesz miał kilka rodzajów elementów tego samego rodzaju oraz kilka rodzajów granic między różnymi typami terenu.

0

Na szybko wczytałem się w mapy i działa poprawnie, zobaczymy w przyszłości przy mapach 100+

Dziękuję :>

0

Nie lepiej użyć Tiled Map Editor i jakieś biblioteki do gier np. Slick2d?

1 użytkowników online, w tym zalogowanych: 0, gości: 1