AWT Canvas BufferStrategy 和调整大小闪烁
Posted
技术标签:
【中文标题】AWT Canvas BufferStrategy 和调整大小闪烁【英文标题】:AWT Canvas BufferStrategy and resize flickering 【发布时间】:2015-01-24 00:28:03 【问题描述】:我正在尝试使用 Java2D 制作一个简单的游戏,以获得最大的兼容性。它在 Mac OS X Yosemite 上的 Java 8 下运行良好,但是当我在 Windows 7 下尝试相同的代码时,它就没有那么流畅了。当 JFrame 被调整大小时,画布会闪烁,这真的很难看。
我的应用程序使用带有 BufferStrategy 的 AWT Canvas 并像这样工作。当环境中有东西移动时,另一个线程调用重绘。但是对于窗口大小调整处理,我的策略如下:
public class TestCanvas
private static final Color[] colors = new Color[]Color.black, Color.darkGray, Color.gray, Color.lightGray, Color.blue.darker().darker(), Color.blue, Color.blue.brighter().brighter(), Color.white;
public static void main(String[] args)
JFrame frame = new JFrame("Test Canvas");
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
Canvas canvas = new Canvas()
@Override
public void paint(Graphics g)
BufferStrategy bufferStrategy = getBufferStrategy();
g = bufferStrategy.getDrawGraphics();
paint100Circles(g);
g.dispose();
bufferStrategy.show();
@Override
public void update(Graphics g)
paint(g);
@Override
public void repaint()
paint(null);
;
contentPane.add(canvas, BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(1000, 1000);
frame.setVisible(true);
canvas.createBufferStrategy(2);
public static void paint100Circles(Graphics g)
Random random = new Random(0);
for (int i = 0; i < 100; i++)
int x = Math.abs(random.nextInt()) % 1000;
int y = Math.abs(random.nextInt()) % 1000 + (Math.abs(random.nextInt() % 1000) / 25);
int size = 50 + Math.abs(random.nextInt()) % 50;
g.setColor(colors[Math.abs(random.nextInt()) % colors.length]);
g.fillOval(x, y, size, size);
也许我没有以正确的方式使用 BufferStrategy?
【问题讨论】:
【参考方案1】:我使用 createBufferStrategy(3) 但 2 也应该没问题。
在this answer 中,基本上鼓励您使用paintComponent,而不是paint()。 引用:
“这里的问题是paint做了很多重要的工作,调用paintComponent只是其中之一。”
您可能想尝试切换到paintComponent。你正在做的其他一切看起来都很好。
不过话虽如此,在我自己的代码中,我根本不调用paint() 或paintComponent()。 相反,我会尽可能地写入 bufferStrategy(render() 循环尽可能多地运行)
我认为,当您使用 bufferStrategy 时,您会在paint() 之外写入缓冲区,而在绘制期间只需将缓冲区写入屏幕。就像它在this answer 中所说的那样,虽然它没有获得任何分数,但它可能仍然有有效的提示。
所以我认为要么使用paintComponent并在那里进行绘画(我认为你仍然可以设置双缓冲策略,但绘制到你的图形)或写入paintComponent/paint之外的缓冲区并让组件绘制缓冲区当它想要的时候。
【讨论】:
谢谢!删除paint()、update() dans repaint() 并使用双缓冲策略添加一个新的Timer(1000/30, ActionEvent) 似乎并不能消除调整大小时的闪烁。 即使使用 createBufferStrategy(3) 或 4。 并且使用paintComponent() 而不是Canvas 的JPanel 实现闪烁较少,但看起来双缓冲策略根本不起作用,对象看起来像是直接在框架上渲染。跨度> 也许我遗漏了什么? 我绝对不是这方面的专家,我有点害怕做出任何猜测。这方面有很多文章。我只是从基本的游戏编程中知道无限运行渲染循环,它以最佳速度将像素推入缓冲区。画布会在它们进入时显示它们。我认为覆盖paint()会导致麻烦,因为它会在哪里(简化)display.setPixels(buffer.getPixels())。据我所知,panel.paintComponent 是直接在表面上渲染而不是双缓冲。它根据需要重新粉刷的部分来决定替换哪些区域。以上是关于AWT Canvas BufferStrategy 和调整大小闪烁的主要内容,如果未能解决你的问题,请参考以下文章
Java - 如何创建bufferedStrategy到jframe
Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ② ( AWT 绘图步骤 | Graphics 绘图常用 API )
Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ② ( AWT 绘图步骤 | Graphics 绘图常用 API )