Java程序双重缓冲,但仍有一半时间闪烁

时间:2014-05-13 23:20:55

标签: java flicker buffering

我正在关注

中的中间java教程

https://www.youtube.com/watch?v=M2GoiOas2u8&list=PL54DB126285ED0420

但我遇到双缓冲闪烁的问题。

我的两个班级中的相关代码如下

GamePanel.Java

private void gameRender()
{
    if (dbImage == null) // create the buffer
    {
        dbImage = createImage(GWIDTH, GHEIGHT);
    }
    if (dbImage == null)
    {
        System.err.println("dbImage is still null!");
        return;
    }
    else
    {
        dbg = dbImage.getGraphics();
    }

    // Clear the screen
    dbg.setColor(Color.WHITE);
    dbg.fillRect(0, 0, GWIDTH, GHEIGHT);

    // Draw Game elements
    draw(dbg);
}

// Draw all game content in this method
public void draw(Graphics g)
{
    world.draw(g);
}

private void paintScreen()
{
    Graphics g;
    try
    {
        g = this.getGraphics();
        if (dbImage != null && g != null)
        {
            g.drawImage(dbImage, 0,  0,  null);
        }
        Toolkit.getDefaultToolkit().sync(); //For some OS.
        g.dispose();
    }
    catch(Exception e)
    {
        System.err.println(e);
    }
}

World.Java

    public void draw(Graphics g)
{
    for (int i = 0; i < arrayNumber; i++)
    {
        g.drawImage(blockImg[i], blocks[i].x, blocks[i].y, null);
    }
}

其中arrayNumber = 1200。 当地图向右或向下移动时,此程序只有闪烁问题(意味着block.x和blocks.y为i的每个值增加),但不是相反。我尝试用[arrayNumber - i]替换每个[i]并修改for循环的参数,从右下方绘制。这使得只有在向上和向左移动地图时才会出现闪烁。

所以我知道我应该以某种方式在世界级中修改这个run方法以某种方式使用双缓冲,但是我想知道如何这样做,因为世界不会扩展JPanel?

1 个答案:

答案 0 :(得分:1)

不要使用this.getGraphics();,这不是Swing中的绘画方式。

Swing使用被动绘画算法,这意味着您无法控制绘画过程。 Swing将决定应该绘制什么和何时绘制。

默认情况下,Swing组件已经双重缓冲。

不应该打击这个,你应该理解并接受它。

首先覆盖paintComponent GamePanel super.paintComponent并在此处渲染您的游戏状态(不要忘记致电{{1}})

请查看Performing Custom PaintingPainting in AWT and Swing,了解有关如何在Swing中实现绘画的详细信息