我正在为一个学校项目编写一款 2D RPG 风格、基于 Sprite 的游戏,我们的团队决定该游戏应该有一个跟随玩家而不是固定的相机,这自然意味着游戏当玩家移动时需要动态加载世界数据。我知道这可以通过分块加载世界的各个部分来实现,就像在 Minecraft 中一样,但我希望能够有选择地、频繁地加载少量数据,而不是不那么频繁地加载大块数据。例如,玩家向上移动一个单位,因此游戏可以在加载顶行时从内存中丢弃底行数据,而不是时不时地加载整个 block 或卸载一个 block 。目前所有相关的世界数据都存储在二维数组中,那么有没有一种有效的方法可以从世界文件中加载数组中的特定数据点,而不必加载整个数据或大块加载?
话又说回来,也许大块加载是更好的选择,因为从硬盘驱动器加载需要更长的时间,有什么想法吗?
假设在这种情况下,我的世界文件由称为区域的较小文件组成,这些文件基本上是 block 。
然后我的问题是:“我如何从主世界文件中加载这些特定区域而不立即加载整个内容?”
最佳答案
您可以看到example它主要用于存储巨大的矩阵,因为加载巨大的矩阵需要大量的内存。如果将矩阵存储在随机访问文件中,而不是加载到内存中,则可以非常快速地检索它们。将矩阵映射到 RandomAccessFile 所需的一切供以后使用。我不会迭代整个示例,而只会迭代您需要清楚理解的主要部分,以便您可以根据需要重新实现它。
public long position(int x, int y) {
return (long) y * width + x; // returns the position of a value in the file
}
public double get(int x, int y) {
assert x <= 0 && x > width; // simply bound check
assert y <= 0 && y > height; // simply bound check
long p = position(x, y) * 8; // 8 for double, if integer then use 4
int mapN = (int) (p / MAPPING_SIZE);
int offN = (int) (p % MAPPING_SIZE);
return mappings.get(mapN).getDouble(offN);
}
get
方法从存储在文件中的矩阵中的特定位置(行、列)检索值。 mappings
只是像 list
这样的数据结构在Java中。喜欢get
方法,你需要一个set
方法也是如此。
public void set(int x, int y, double d) {
assert x <= 0 && x > width;
assert y <= 0 && y > height;
long p = position(x, y) * 8;
int mapN = (int) (p / MAPPING_SIZE);
int offN = (int) (p % MAPPING_SIZE);
mappings.get(mapN).putDouble(offN, d);
}
重要:MAPPING_SIZE
可以设置为1 << 31
或更低的值,因为 Java 不支持一次 2 GB (2^31) 或更大的映射。所以,如果你使用 set MAPPING_SIZE = 1 << 30
,它将文件划分为 1 GB 的映射。为简单起见,您可以将其视为分割一个大矩阵并将它们存储为小块(这些称为映射)。如果你的矩阵很小,那么你不需要担心它。
关于java - 如何从 Java 中的序列化对象加载选择性数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40777163/