Низкий fps в низком вычислении java paintcomponent - PullRequest
1 голос
/ 12 марта 2012

Я делаю игру, в которой для целей этого вопроса у меня есть класс, расширяющий JFrame, который добавляет класс, расширяющий JPanel (GamePanel). в GamePanel у меня есть метод запуска, который имеет две функции update (); и перекрасить (); а затем Thread.sleep (20). Функция обновления занимает около 1-2 мс. У меня есть все мои материалы для рисования в paintComponent (Графика g), которые, кажется, правильно вызываются, когда я использую repaint (), так как вещи отображаются на экране.

Моя проблема в том, что он невероятно запаздывает. Когда у меня не было Thread.sleep (20), его нельзя было воспроизвести как 2fps. Я читал, что это потому, что repaint () не дали достаточно времени, чтобы закончить или что-то еще, поэтому я добавил задержку перед следующим циклом. что-то выше или ниже 20 мс, кажется, делает его более медленным.

Я пытался использовать графическую конфигурацию, двойную буферизацию и многое другое, но он остается медленным. На моем домашнем компьютере, который является Intel i5, четырехъядерным, 3,2 ГГц, я получаю только около 100 кадров в секунду, а на школьном компьютере я получаю около 15 кадров в секунду (хорошо, как я думаю, как двухъядерный amd). Петля paintComponent очень легкая! просто нарисовать карту со смещением в зависимости от позиции игрока, а затем нарисовать игрока в середине экрана! Я использую карту 2000x2000, 0.8mb. Пробовал переключаться на 1000х1000 0,4мб и без разницы.

Вот код:

@Override
public void paintComponent(Graphics g) {
    //Rendering settings and stuff
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

    //Draw map     gameMap.gameMap is a bufferedImage
    g2d.drawImage(gameMap.gameMap, gameMap.x, gameMap.y, null);
    //Draw health bar
    g2d.setColor(healthBarColor);
    g2d.setComposite(alphaHealthBarBackground);
    g2d.fillRect(100, 19, 200, 23);
    g2d.setFont(font);
    g2d.setComposite(alphaNormal);
    g2d.setColor(healthBarColor);
    g2d.drawString("HP: ", 20, 40);
    g2d.fillRect(100, 19, player.health * 2, 23);

    //Draw player      player.playerImage is a BufferedImage
    rotatePlayer.setToRotation(rotation, rotationAnchor.x, rotationAnchor.y);
    rotatePlayer.translate(xResolution / 2, yResolution / 2);
    g2d.drawImage(player.playerImage, rotatePlayer, this);
    g2d.setColor(Color.white);
}

Это дает 100fps на относительно крутом компьютере и 15fps на спуске!

Ответы [ 3 ]

4 голосов
/ 12 марта 2012

Не претендуя на конечное решение, просто несколько советов:

  1. Убедитесь, что ваши буферизованные изображения имеют ту же цветовую модель, что и по умолчанию GraphicsDevice, на которой они нарисованы.Метод GraphicsConfiguration.createCompatibleImage может создавать такие изображения.

  2. Если это возможно, попробуйте разбить всю огромную карту на плитки и пропустить рендеринг вне экрана (извид из игры) parts.

  3. Похоже, вы используете пассивный рендеринг, как вы упомянули о вызове repaint().Event Dispatch Thread используется для многих вещей в Swing и AWT, и он не может гарантировать приемлемое время для активно рендеринга игр.Возможно, стоит изменить дизайн рендеринга, чтобы использовать Active Rendering.Учебник и пример можно найти здесь .

0 голосов
/ 05 июля 2014

Я также занимаюсь разработкой Java-игры и сделал то же самое, что и вы (расширение JPanel и вызов repaint ()). Одно из отличий состоит в том, что я использую javax.swing.Timer для вызова метода ActionPerformed (ActionEvent e) для обновления моей игры каждые 5 мс. В конце метода вызывается repaint () для рендеринга.

Также, если вы используете Graphics2D для рендеринга, вы можете использовать RenderingHints, чтобы указывать компьютеру, как вы хотите, чтобы ваша игра воспроизводилась (например, скорость или качество, и тому подобное).

Я не измерил FPS точно, но у меня нет задержки в моей системе Ubuntu 12.10 и чуть медленнее в Windows 8.

Я прошу прощения, если мой ответ не совсем то, что вы хотели, но это то, что до сих пор работало для меня без проблем.

0 голосов
/ 12 марта 2012

Что ж, для разработки игр я не думаю, что рисование огромного изображения в Swing paintComponent когда-либо сможет побить любые рекорды скорости. 100 кадров в секунду по-прежнему впечатляет (и примерно на 40 кадров в секунду больше, чем частота обновления большинства ЖК-дисплеев).

Для большей скорости важно, чтобы используемые вами примитивы рисования были ускорены. На ваших школьных ПК им может просто не хватить приличной видеокарты, которая обеспечивает необходимое 2D-ускорение (как эти ПК чувствуют себя как обычные 2D-операторы в браузерах и программах рисования?)

Возможно, вы захотите взглянуть на среду, которая использует OpenGL, например, JOGL. Другой вариант - попробовать JavaFX 2 - он может иметь лучший конвейер рендеринга.

...