Java 将图像加载到 class - 最有效的做法?

Java load image to class - most efficient practice?

我正在 Java 中编写基于图块的 2D 游戏。角色将根据游戏逻辑放置在瓷砖上。每个角色都与一张图片相关联,该图片将使用 java.awt.Graphics2D 绘制到屏幕上。但是,地图上的每个角色可能有不止一个实例。

存储和访问角色图像的推荐做法是什么?

我能想到三种可能的实现方式:

  1. 为每个角色分配一个 java.awt.image.BufferedImage 类型的私有变量。每次需要绘制对象时,都会使用 getter 访问图像。但是,这样会不会导致对象的尺寸过大呢?
  2. 使用另一个实用程序 Class 将所有图像存储在静态变量中。每次需要绘制字符时,可以通过将 id/name 传递给实用程序 Class 中的静态 getter 方法来调用图像。这会比以前的方法更有效还是更慢?
  3. 每次需要绘制角色时加载图片即可。每次需要绘制角色时,这都会引起 ImageIO.read(new File(character.getImagePath())。这可能是最快的吗?

我看了很多关于如何优化游戏的文章,我发现在开始时加载需要的资源并存储它们以备后用是非常重要的。在文件 I/O 代码中可以找到一些最长的操作。甚至有可能发生一些异常。例如,在您的第三个选项中,如果 ImageIO 抛出 IOException 会发生什么?你不会有图像,你必须渲染其他东西。如果图像读取时间比预期的长,同样会削弱用户的游戏体验。

这是一个预加载资源的示例片段(在您的 .jar 中):

// Imports and other stuff...

// Parameter flocation: resource location
private BufferedImage preloadImage(String flocation){
    BufferedImage bufimg = null;
    System.out.println("Attempting to load image: '" + flocation + "'");

    try {
        bufimg = ImageIO.read(this.getClass().getResourceAsStream(flocation));
    } catch(IOException e){
        System.err.println(
                "An error occurred while attempting to load '" + flocation + "'");

        return null;
    }

    // Now store this somewhere safe!
    return bufimg;
}

对于您的第一个和第二个选项,您仔细想想确实没有太大区别。第一个只是为每个字符添加一个字段,而另一个为您管理所有字符图像。就个人而言,我更喜欢第一个选项,因为它减少了代码混乱,增加了可读性。当然,您可能决定根据主题对代码进行分组,因此第二个选项完全没问题。