AWT Canvas BufferStrategy并调整闪烁大小

时间:2014-11-25 20:39:25

标签: java canvas awt game-development bufferstrategy

我正在尝试使用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 个答案:

答案 0 :(得分:1)

我使用createBufferStrategy(3),但2也应该没问题。

this answer

基本上鼓励你使用paintComponent,而不是paint()。 引用:

“这里的问题是paint做了很多重要的工作,调用paintComponent只是其中之一。”

您可能想尝试切换到paintComponent。你正在做的其他一切看起来都很好。

但是说过,在我自己的代码中,我根本不会调用paint()或paintComponent()。 相反,我随时写入bufferStrategy(render()循环运行次数尽可能多次)

我认为当你使用bufferStrategy时,你要写入paint()之外的缓冲区,并且在绘制期间只需将缓冲区写入屏幕。就像它在this answer中说的那样,虽然它没有得到任何分数,但它仍然可能有有效的提示。

所以我认为要么使用paintComponent并在那里做你的绘画(你仍然可以设置一个双缓冲策略,但是绘制到你的图形)或者写入paintComponent / paint之外的缓冲区并让组件绘制缓冲区什么时候需要。