Моя игра (каркас) не может идти быстрее 30 кадров в секунду (около 33 мс между вызовами обновления) в полноэкранном режиме. Я использую таймер для цикла. На самом деле это становится немного сложнее, поскольку, когда я уменьшаю задержку постепенно, время между вызовами i измеряется гайками. Он перескакивает с установленной задержкой на два или более ожидаемое значение. Похоже, что порог составляет 30 мс. Нет проблем в оконном режиме, когда расхождения начинают появляться с порогом 4 мс. Оба режима действуют нормально при более высоких задержках. Вот часть кода, который я считаю уместным.Полноэкранный режим ограничения частоты кадров
fps = 30;
timer = new Timer(1000/fps, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
tick();
}
Вышеуказанная установка таймера. Ниже - все остальное.
private void tick(){
update(gameTime);
draw(gameTime);
}
Вот моя графика (2D) и BufferedImage.
public DrawBatch(DeviceManager deviceManager) {
this.deviceManager = deviceManager;
color = Color.MAGENTA;
bufferedImage = deviceManager.getBufferedImage();
bufferedGraphics = (Graphics2D)bufferedImage.getGraphics();bufferedGraphics = (Graphics2D)bufferedImage.getGraphics();
bufferedGraphics.setBackground(color);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
bufferedGraphics.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
метод Розыгрыш (GameTime Gametime) начинается с этого метода:
public void begin(){
bufferedGraphics.clearRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
}
Теперь мы можем сделать с помощью bufferedGraphics. рисовать (GT дт) заканчивается этим. (вдохновленный XNA)
public void end(){
if(deviceManager.isFullScreen())deviceManager.getGraphics().drawImage(bufferedImage, 0,0, null);
else deviceManager.getGraphics().drawImage(bufferedImage, 3,25, null);
deviceManager.getGraphics().dispose();
bufferedImage.flush();
}
Я перерабатывают же BufferedImage с момента создания нового (наряду с объектом Graphics) сделал один ад утечки памяти. Не знаю, использовать ли один и тот же графический объект вместо выполнения .dispose()/new Graphics каждый кадр.
В оконном режиме BufferedImage нарисован на jFrame.getGraphics() и в fulls-creen на graphicDevice.getFullScreenWindow(). GetGraphics().
Вот полноэкранная настройка.
public void setFS(){
jFrame.setVisible(false);
jFrame.dispose();
jFrame.setIgnoreRepaint(true);
jFrame.setResizable(false);
jFrame.setUndecorated(true);
graphicDevice.setFullScreenWindow(jFrame);
graphicDevice.getFullScreenWindow().setIgnoreRepaint(true);
graphicDevice.setDisplayMode(new DisplayMode(width, height, 32, 60));
jFrame.setVisible(true);
fullScreen = true;
}
И оконная установка.
public void setW(){
jFrame.setVisible(false);
jFrame.dispose();
jFrame.setIgnoreRepaint(true);
jFrame.setResizable(false);
jFrame.setUndecorated(false);
graphicDevice.setFullScreenWindow(null);
jFrame.setSize(width, height);
jFrame.setVisible(true);
jFrame.getContentPane().setPreferredSize(new Dimension(800, 600));
jFrame.pack();
fullScreen = false;
}
Любая идея, почему различное поведение режимов? (За исключением частоты кадров и некоторых потенциальных утечек памяти, программа работает плавно.)
Я считаю, что ваши тики получают вызов быстрее/медленнее, потому что Swing Event Dispatch Thread - это поток, который ваш таймер не контролирует. Вы должны ограничить количество вызовов в заданный таймфрейм другим способом. – arynaq
На весу приходит немало вещей, которые, кажется, имеют смысл, так это то, что EDT становится перегруженным, а таймер просто укладывает на него события. Таймер имеет метод под названием [setCoalesce] (http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html#setCoalesce (boolean)), который сжимает несколько коротких запросов в один запрос на EDT – MadProgrammer
Да. EDT подавлен на 'graphicDevice.getFullScreenWindow(). GetGraphics()' уходит каждый цикл. Был ли EDT хорошей идеей для игрового цикла? Одним из недостатков является то, что я не могу использовать некоторые из SwingUtilities. Знать кого-нибудь другого? –