2013-11-02 21 views
1

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

Так что мой текущий метод для визуализации кадра является манипулируя g2d объект определенного JPanel:.

(IMG является картой, что нарисовано Этот метод является частью класса, который имеет всю информацию, как ширина и высота экрана и положение камеры. (так PosX, Пози, ширина, высота берутся из Instace объекта это называется на)

public void DrawByManipulatedMapSubimage(BufferedImage img, Graphics2D g2d) 
{ 
    if (isActive) 
    { 
     BufferedImage img2 = img.getSubimage(PosX, PosY, width, height); 
     g2d.drawImage(img2,0,0,null); 
     List<MapObject> MapObjects = Map.getObjectInformation(); 
     List<UiComponent> UC = this.UI.getUiComponents(); 

     int l = this.Map.getObjectInformation().size(); 

     for (int i = 0; i < l; i++) 
     { 
      MapObject MO = MapObjects.get(i); 
      int MOX = MO.getPosX(); 
      int MOY = MO.getPosY(); 
      BufferedImage MOB = MO.getCurrentAnimation().getCurrentlyActiveFrameAsBufferedImage(); 

      g2d.drawImage(MOB, MOX - PosX, MOY - PosY, null); 
     } 

     for (int i = 0; i < UC.size(); i++) 
     { 
      UiComponent CC = UC.get(i); 
      if (CC.isVisible()) 
      { 
       Point P = CC.getPosition(); 
       int x = P.x; 
       int y = P.y; 
       g2d.drawImage(CC.getImg(),x,y,null); 
      } 
     } 
     try 
     { 
      Thread.sleep(0); 
     } 
     catch (InterruptedException ex) 
     { 
      Logger.getLogger(Viewport.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

что это в основном делает это, что он

  1. Пишет SubImage текущей активной карте, основываясь на том, где пользователь просматривает из (камера-View в пути)

  2. Рисует BufferedImage Расчетного Animation всех приложенных MabObjects (в основном всё, что связано изменить; как игрок, Npcs, движущиеся деревья, космические корабли, что угодно).

  3. Рисует все прикрепленные UserInterface-компоненты поверх двух последних вещей. (только такие вещи, как характер портретов, например; ни одна из кнопок или что-нибудь interactable)

То, что делает меня любопытно, что это не может быть случай, когда программа использует столько процессора, что его просто не может идти в ногу с рендерингом, так как программа имеет те же самые задержки, что и с прилагаемыми дополнениями x, как без них. Также эта программа использует около 5% моего процессора (при 30 кадрах в секунду)

Таким образом, проблема должна быть где-то еще. Возможно, у вас есть идея оптимизировать его?

ответ

3

То, что делает меня любопытно, что это не может быть случай когда программа использует столько процессора, что он просто не может идти в ногу с Rendering, как Программа имеет те же отставание работает с x прилагается дополнительные услуги без каких-либо ограничений. Кроме того, эта программа использует около 5% моего процессора (в 30к)

  • вызванные Thread.sleep(int), вы не должны использовать тему.сон (целое), только в тех случаях, которые вы хотите имитировать некоторый долгий и дорогой сон, в противном случае использовать таймер

  • Thread.sleep(0) == zero miliseconds заморозить текущий экземпляр JVM недо цикл закончился, ничего не происходит до тех пор пока этот цикл заморожен по Thread.sleep() закончился ,

  • задержки в Native OS не находится под 16milisecond, 25 может быть ограничение, но использовать таймер вместо с этим значением


g2d.drawImage

  • для сегодняшних Java6/7

    1. должен быть вызван переопределения paintComponent в JPanel,
    2. первым. строка кода внутри paintComponent должна быть super.paintComponent() == сбросить все предыдущие картины, иначе живопись совмещаться

    3. задерживается или перекрашен по Swing Timer на разумной частоте 33-50 milisecond

  • это о хороших practicies в живописи в свинге для хранения текущего моментального снимка в BufferedImage, и все изменчивые переменные или объекты могут храниться в List<Whatever>, внутри paintComponent до g2d.drawImage и для остальной окраски для петли внутри подготовленных array of Object s (List<Whatever>)


для лучшей помощи рано опубликовать SSCCE, короткий, работоспособный, компилируется, только о выпуске

ночи по
+0

Я удалил Thread.sleep (0); но нет никакой разницы. –

+0

вы должны добавить Swing Timer (50-125) с container.repaint(), вызванный после того, как координаты изменены в ActionListener – mKorbel

0

Вы, вероятно, страдаете от мусора Коллекции пауз, из-за чрезмерное выделение. Некоторые методы выглядят очень подозрительно относительно распределения (например, «getCurrentlyActiveFrameAsBufferedImage»). Используйте VisualGC для проверки скорости распределения, затем улучшите свою программу или попытайтесь получить большой эден. Большие двоичные объекты, такие как bitmaps/byte [], выделяются непосредственно на OldSpace, поэтому, если вы создаете слишком много из них, вы будете запускать много старых пауз. Если это так, настройка размера Eden не поможет.

Edit: проверить погоду в 'паузами' коррелируют с GC, запустив программу с -verbose: GC Вариант

Смежные вопросы