Java 性能加载图像游戏类

Java 性能加载图像游戏类,java,performance,variables,drawing,Java,Performance,Variables,Drawing,我试图在游戏中为物体绘制图像的几种方法之间做出选择 我希望对象有自己的draw()方法,但我担心可能会导致不必要的图像副本或其他效率下降,无论是否明显 第一种方法是在级别开始时加载缓冲区图像 public class levelone{ BufferedImage imageguy; public void draw(Graphics2d g){ g.drawImage(imageguy, null, guy.getx(), guy.gety());

我试图在游戏中为物体绘制图像的几种方法之间做出选择

我希望对象有自己的
draw()
方法,但我担心可能会导致不必要的图像副本或其他效率下降,无论是否明显

第一种方法是在级别开始时加载
缓冲区图像

public class levelone{

    BufferedImage imageguy;

    public void draw(Graphics2d g){
        g.drawImage(imageguy, null, guy.getx(), guy.gety());
    }

}
第二种方法将图像加载到guy.class中,并从那里用
guy.draw(g)绘制图像在levelone.class中调用

第三种方法将图像加载到levelone.class中,并使用
guy.draw(imageguy,g)从guy.class中绘制图像


请帮助我了解最好的方法。如果不清楚我在问什么,一定要说出来,我会尽量让你更容易理解。

这更像是一个设计问题。首先,这是:

。。。其他一些效率下降,无论是否明显

。。。这不是一种非常健康或富有成效的思维方式。如果不明显,就不值得担心。否则,如果你要在每个时钟周期中都沉迷于游戏,那么你也可以用汇编代码编写游戏

但这里可能有更广泛的设计级别可伸缩性问题值得注意

值得注意的是,将渲染/绘图逻辑与高级类耦合可能会成为维护负担。这取决于你的项目范围,但是如果它是一个相当大的项目,如果你把绘图/渲染逻辑与游戏逻辑分开,你会有更多的喘息空间。然后,从游戏设计的角度出发,你可以将全部注意力集中在一个“怪物”或“物品”或类似的东西需要做什么,而不必担心它将如何绘制。这幅画是在别处画的

但是,如果我们假设您希望在这些对象中具有绘图逻辑,那么您的问题似乎最终归结为您希望在哪里存储与游戏中的对象相关的图形的一些图像缓冲区

简而言之,答案是“视情况而定”。你有信心做出什么样的假设?例如,在您发布的代码中:

public void draw(Graphics2d g){
    g.drawImage(imageguy, null, guy.getx(), guy.gety());
}
。。。如果你所要做的只是将对象图像快速地显示在图形上,这看起来有点可笑。如果你所要做的只是将物品的图像以blit方式显示在图形上,那么你最好干脆取消
draw
方法,让一个公共访问者看到该图像,让一个中心位置负责在正确的时间和地点以blit方式显示这些图像

在这一点上,如果您所做的只是在对象中存储图像并向它们公开访问器,那么您也可以让外部世界自行加载/存储这些图像并对其进行blitting,让对象保持干净,完全没有绘图逻辑。这还将为您提供最大的灵活性,使您可以优化绘制对象的时间和方式,而无需干涉所有对象

但是,你总是要从一个物体上blit图像吗?游戏中的一个物体可能会画出其他的东西、形状、文字等,这种情况会发生吗?如果是这样,您可能希望保留
draw
方法

所以对我来说,最终的问题是,你真的想在你的物体里画画吗

  • 如果没有,那么您将拥有最大的灵活性来优化您的核心内容,因为您可以将最有效地加载、存储和绘制图形的责任留给中央渲染引擎,而不是将该责任分散到游戏中的每个对象上(如果你想以不同的方式做事,就可能不得不改变所有这些)

  • 如果您确实希望这样做,那么您也可以完全封装在对象内部渲染对象所涉及的所有细节,包括保留它所需的任何资源,以便外部世界不必为此烦恼,只需调用“绘制”并传入图形目标(例如Graphics2D)

  • 所以我想说,也许你的建议中没有一个是理想的。但如果有一个选择可能不好,我会说这是你的第三个选择。那就是:

    第三种方法将图像加载到levelone.class中并从中绘制 guy.class和guy.draw(imageguy,g);在levelone.class

    这里的问题是,你在两个世界中都遇到了最坏的情况。你正在将这个“家伙”的绘画细节泄露给外部世界,但外部世界仍然必须依靠这个“家伙”通过将这些绘画细节传回来完成绘画。如果没有其他事情,你真的想给这个家伙或外部世界第一这是一种责任,后者更灵活,但前者更封闭。当外部世界必须将一个男人的形象传还给这个男人让他画画时,你就得不到这些好处。如果你真的想让一个男人“画自己”,那么你通常希望能够在没有外界太多帮助的情况下做到这一点。将坚定的责任交给一个实体,而不是将其分散到多个实体

    关于同一映像的不必要副本,无论您如何使用中心映像缓存,都可以轻松解决。简单的方法是使用映射。加载映像时,在映射中搜索路径。如果路径已存在,则返回对已加载映像的引用。否则,加载映像并将该路径/映像作为键/值对插入到地图