我正在尝试使用Java2D制作一个简单的游戏,以获得最大的兼容性。它在Mac OS X Yosemite上的Java 8下运行良好,但是当我在Windows 7下尝试相同的代码时,它就不那么流畅了。调整 JFrame 大小时画布会闪烁,这真的很丑陋。
我的应用程序使用带有BufferStrategy的AWT画布,其工作方式如下。另一个线程在环境中移动时调用重新绘制。但是对于窗口大小调整处理,我的策略如下:
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);
}
}
}
也许我没有以正确的方式使用缓冲区策略?
我使用 createBufferStrategy(3),但 2 也应该没问题。
在这个答案中,基本上鼓励你使用 paintComponent,而不是 paint()。引用:
"这里的问题是油漆做了很多重要的工作,称油漆组件只是其中之一。
您可能想尝试切换到paintComponent。您正在做的所有其他事情看起来都很好。
然而话虽如此,在我自己的代码中,我根本不调用 paint() 或 paintComponent()。相反,我只要有可能就写入bufferStrategy(render()循环运行尽可能多的次数)
我认为当你使用bufferStrategy时,你会写入paint()之外的缓冲区,而在paint期间,你只是将缓冲区写入屏幕。 就像它在这个答案中所说的那样,虽然它没有获得任何分数,但它可能仍然有有效的提示。
所以我认为要么使用 paintComponent 并在那里进行绘画(我认为您仍然可以设置双缓冲策略,但绘制到您的图形)或写入 paintComponent/paint 之外的缓冲区,让组件在需要时绘制缓冲区。