Как ускорить мои игры в секунду? - PullRequest
0 голосов
/ 21 декабря 2011

У меня есть игра, которая в каждом цикле рендеринга проходит по всем блокам на моей карте (128x128), что, как вы, вероятно, можете сказать, вызывает большое отставание.Когда я впервые сделал это, мне нужно было сделать так, чтобы отображались только блоки на экране, иначе он мгновенно рухнул.Теперь я только рендеринг блоков на экране, но по-прежнему цикл по всем блокам, чтобы увидеть, если они на экране, что делает мои fps около 2.

    for (int y = 0; y < 128; y++) {
        for (int x = 0; x < 128; x++) {
            Block b = LevelGen.getBlockAt(x, y);
            if (Forgotten.isInsideGameWindow(x * 30, y * 30)) {
                arg1.drawImage(b.getTexture(), x * 30, y * 30);
            }
        }
    }

Есть ли способ сделать это такне проходит через все из них?

Ответы [ 3 ]

3 голосов
/ 21 декабря 2011

Определите размер вашего окна отображения и просматривайте только те блоки, которые находятся внутри него.

final int tile_size = 30;

final RectangleType displayWindow = Forgotten.getDisplayWindow ();

final int left = displayWindow.getLeft () / tile_size - 1;
final int right = displayWindow.getRight () / tile_size + 1;
final int top = displayWindow.getTop () / tile_size - 1;
final int bottom = displayWindow.getBottom () / tile_size + 1;

for (int y = top; y < bottom; ++y)
   for (int x = left; x < right; ++x)
       canvas.drawImage (LevelGen.getBlockAt (x,y).getTexture (),
                         x * tile_size, y * tile_size);

Вы также можете выяснить, какие области холста на самом деле хотят рисовать, и вместо этого оставить список «грязных прямоугольников» для перерисовки областей. Всякий раз, когда плитка изменяется или когда спрайт / частица / что-либо проходит через ее пространство, добавьте эту плитку в прямоугольник. Даже если вы просто используете один грязный прямоугольник, который увеличивается, чтобы охватить все обновления в течение кадра, если в вашей игре фактически не происходит "что-то происходящее" во всех точках на дисплее все время, частота кадров в среднем будет выше ( но страдают от масштабных эффектов)

с учетом этого:

      public class Map {
            private Rectangle dirtyRect = null;

            public void dirty (Rectangle areaAffected) {
                   if (null == dirtyRect) {
                        dirtyRect = areaAffected; return;
                   }
                   dirtyRect = new Rectangle ( Math.min (dirtyRect.getLeft (),
                                                         areaAffected.getLeft () ),
                                               Math.min (dirtyRect.getTop (),
                                                         areaAffected.getTop () ),
                                               Math.max (dirtyRect.getRight (),
                                                         areaAffected.getRight () ),
                                               Math.max (dirtyRect.getBottom (),
                                                         areaAffected.getBottom () ));
            }

Затем используйте грязный прямоугольник вместо displayWindow для нормального рисования, и вы можете проверить if (null == getDirtyRectangle ()) return;, чтобы вообще пропустить рисование, если ничего не изменилось.

0 голосов
/ 21 декабря 2011

Ну, вы можете поместить все блоки в массив, включить координаты в объект блока, а затем использовать их для рисования блока. Тогда вам нужно будет только пройти через блоки, которые появляются на экране. Полезно, только если на экране не так много блоков.

0 голосов
/ 21 декабря 2011

Вы можете просто вставить разрыв внутри вашего блока кода ... но тогда я не вижу цели этого кода, просматривающего 16, 32 или 256 раз ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...