【问题标题】:Java optimizing painting a background image for a gameJava优化为游戏绘制背景图像
【发布时间】:2010-03-03 15:24:58
【问题描述】:

作为任务的一部分,我正在重新创建“塞尔达传说与过去的联系”。

我遇到了以下问题,游戏世界是一个 BufferedImage,我 subImage() 是玩家当前位置所需的部分。游戏可以运行,但使用了 80% / 110% 的 CPU。一份资料显示,罪魁祸首是图像的绘制。

所以我想我把背景放在一个单独的 JPanel 中,与 Player、敌人等 JPanel 分开。 将它们相互叠加(JLayeredPane)并减少重新绘制背景面板的频率。

但是我该如何做到这一点,我如何告诉 swing 每秒绘制一个面板 x 次和其他 y 次?如果您有更好的优化方法,请告诉我。

这是我目前所拥有的:

public class Main extends JFrame
{
    private ZeldaGame game = new ZeldaGame();
    private View view = new View(game);
    private BackgroundView bckView = new BackgroundView(game);
    private Controller ctl = new Controller(game, view, bckView, this);

    public Main()
    {
        setLayout(null);

        view.setBounds(0, 0, game.getWidth(), game.getHeight());
        bckView.setBounds(0, 0, game.getWidth(), game.getHeight());

        JLayeredPane pane = new JLayeredPane();
        pane.add(bckView, 1);
        pane.add(view, 0);

        setLayeredPane(pane);

        setSize(game.getWidth(), game.getHeight());
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);
    }

    public static void main(String[] args)
    {
        new Main();
    }
}

谢谢。

【问题讨论】:

    标签: java image jpanel paint


    【解决方案1】:

    实际上不可能有不同的渲染时间,因为帧缓冲区的工作方式——结果会是大量令人讨厌的闪烁。您需要做的是使用Canvas 而不是JPanelJLayeredPane,您可以覆盖画布的paint() 方法或使用bi.getGraphics() 并使用以下任一方法对背景和循环中的字符进行blit这些方法按正确的顺序排列。我建议使用像GTGE 这样的精简引擎,它将从所有混乱的优化细节中抽象出来。您正在认真使用的这些高级组件不是为游戏设计的,您根本不应该使用它们。

    【讨论】:

    • 谢谢 由于您对 bi.getGraphics 的建议,我找到了一篇文章,请参阅我的回答。 GTGE 听起来很棒,但我自己做是为了体验。无论如何,它是一个任务。 PS JCanvas 不是 Java 的一部分,所以您是指 Canvas 还是 JCanvas 项目?
    • GTGE 现在是开源的,看看里面 (code.google.com/p/gtge)——在那里我学到了很多用于 Java2D 游戏的有效技术,以及它的 very close如果你自己从头开始做,你会怎么做:) 对不起,我指的是 Canvas 而不是 JCanvas(哎呀)。
    【解决方案2】:

    好的,我发现了我的方式的错误。我使用的是被动渲染,而我应该使用 active rendering。主动渲染基本上通过调用 setIgnoreRepaint(true) 来关闭自动重绘;在框架上并自己做循环。

    另外,我不需要使用 JPanels。

    【讨论】:

    • 即使是被动渲染也可以,有时效率更高。基本上,通过被动渲染,您所做的只是覆盖 Canvas 的 paint(Graphics g) 方法并允许它更新视图。然而,由于游戏组织、结构的原因,这里并不总是可以有视图渲染代码(也许您的代码结构(可能不是模型-视图-控制器)限制您在每次更新结束时进行渲染)。但基本上,通过被动渲染,无论如何你都可以使画布无效,它会意识到它需要重新绘制。
    猜你喜欢
    • 1970-01-01
    • 2010-11-27
    • 2014-04-30
    • 1970-01-01
    • 2013-10-28
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多