Эффективные методы быстрой перерисовки карты (Java / JPanel) - PullRequest
1 голос
/ 25 сентября 2011

В настоящее время я работаю над простым 2D шутером сверху вниз, в котором вы перемещаете своего персонажа по карте. Графика все еще находится в фазе «тестирования» (сплошные цвета и прямоугольники). Процесс рисования выглядит следующим образом:

  • У меня есть карта (в основном это просто стены или свободное пространство), хранящаяся в виде целочисленного массива, который затем перебирается и рисуется на моей JPanel.
  • После того, как карта нарисована, я прохожу каждую «сущность» на карте (бонусы, другие персонажи) и размещаю их.
  • Наконец, я рисую персонажа пользователя

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

В настоящее время он работает , но кажется медленным . У меня только 4 стены, 2 сущности, и нарисован персонаж пользователя, и он со скоростью 90FPS, довольно часто выпадает около 60-70. Это было бы приемлемо, если бы игра была закончена, однако у меня все еще есть более причудливая графика, гораздо больше объектов, стен, пуль и т. Д., Которые будут отображаться на карте. Я пытался увеличить скорость моего gameLoop, который может достигать 230 FPS, но даже тогда, когда я перемещаюсь в области с объектами или стенами, он достигает 50-70.

Я пытался ограничить то, что нарисовано, только тем, что видно, но результаты были в целом незначительными и даже отрицательными.

Текущий метод paintComponent() выглядит примерно так:

public void painComponent(Graphics g) {

for(int x = 0; x < Map.size.getWidth() ; x++) {

        for(int y = 0; y < Map.size.getHeight(); y++) {

                if(mapArray[y][x] == WALL) {
                    g.setColor(Color.BLACK);
                    g.fillRect(x, y, wallSize, wallSize);
                }

        }
    }

    for(int i = 0; i < map.countEntities(); i++) {

        Entity obj = map.getEntity(i);

        g.setColor(Color.WHITE);
        g.fillRect(obj.getCoords().x, obj.getCoords().y, obj.getSize().width, obj.getSize().height);

    }

    Robot bot = map.getPlayerBot();

    g.setColor(Color.BLACK);
    g.fillRect(bot.getCoords().x, bot.getCoords().y, bot.getSize().width, bot.getSize().height);
}

У кого-нибудь из вас, гуру, есть какие-нибудь советы, чтобы немного ускорить это?

Ответы [ 2 ]

2 голосов
/ 25 сентября 2011

Помимо ответов, упомянутых в следующих ссылках: Оптимальная производительность рисования Java 2D , Проблемы производительности Java2D , Графика игры Java 2D и Какотображать множество SVG-файлов в Java с высокой производительностью

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

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

0 голосов
/ 11 октября 2011

Ответ Сефа был принят во внимание и реализован, но он не увеличил скорость.Видимо, нарисованное изображение не было проблемой вообще.Проблема была в таймере, который я использовал для вызова методов обновления.Я использовал экземпляр класса Timer, который кажется очень ненадежным, особенно с такими небольшими интервалами, как эти.После удаления таймера и вызова моих методов обновления, основанных на системных часах, я смог достичь и поддерживать невероятно высокий FPS.

...