0

我根据我在 stackoverflow 上找到的大量示例将这段代码放在一起。当我运行程序时,整个屏幕剧烈闪烁。我确定我忽略了一些简单的事情,但到目前为止一直无法找到解决方案。我已经调试了几个小时,主要是在在线论坛阅读的帮助下,所以我想是时候问问观众了。

公共类屏幕扩展 JComponent {

    @Override
    public Dimension getPreferredSize(){
        Dimension tempDimension = Toolkit.getDefaultToolkit().getScreenSize();
        return tempDimension;
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D)bufferStrategy.getDrawGraphics();
        g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); //sprites overlap instead of overwrite
        if(game==null){
            drawSplash(g2D);
        }else{
            drawBoard(g2D);
        }
        g2D.dispose();
        bufferStrategy.show();
    }
}

如果需要任何其他代码,我可以提供。谢谢你的帮助,stackoverflow!

4

1 回答 1

0

为了实现您得到的结果,您要么拥有另一个从顶级容器扩展的类,Canvas要么正在使用BufferStrategy来自顶级容器的类。无论哪种情况,两者都必须在屏幕上可见。

基本上,它们是在互相争斗,因为它们是两种不同的绘画算法。Swing 是一种被动绘制算法,会根据需要绘制更新BufferStrategy,而使用主动算法的 Swing 则要求您根据需要安排对缓冲区的更新。

两者都使用双缓冲算法。

所以,你应该选择一个或另一个......

public class Screen extends JComponent {

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g.create();
        g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); //sprites overlap instead of overwrite
        if (game == null) {
            drawSplash(g2D);
        } else {
            drawBoard(g2D);
        }
        g2D.dispose();
    }
}

或类似...

public void gameEngine(BufferStrategy strategy) {

    // Main loop
    while (!done) {
        // Prepare for rendering the next frame
        // ...

        // Render single frame
        do {
            // The following loop ensures that the contents of the drawing buffer
            // are consistent in case the underlying surface was recreated
            do {
                // Get a new graphics context every time through the loop
                // to make sure the strategy is validated
                Graphics2D g2D = (Graphics2D) strategy.getDrawGraphics();

                // Render to graphics
                g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); //sprites overlap instead of overwrite
                if (game == null) {
                    drawSplash(g2D);
                } else {
                    drawBoard(g2D);
                }
                // Dispose the graphics
                g2D.dispose();

                // Repeat the rendering if the drawing buffer contents
                // were restored
            } while (strategy.contentsRestored());

            // Display the buffer
            strategy.show();

            // Repeat the rendering if the drawing buffer was lost
        } while (strategy.contentsLost());
    }
}

这几乎是从JavaDocs 中删除的BufferStrategy

顺便说一句,这...

@Override
public Dimension getPreferredSize(){
    Dimension tempDimension = Toolkit.getDefaultToolkit().getScreenSize();
    return tempDimension;
}

是一个非常糟糕的设计,您正在对可能不符合现实的组件状态做出假设。您应该允许窗口决定它最终想要多大,这可以通过使用setExtendedState和传递它来实现JFrame.MAXIMIZED_BOTH,这将考虑到其他操作系统元素,如任务栏或停靠栏

于 2015-03-01T04:09:17.647 回答