我写了一个java自上而下的2D游戏,它使用生成的图块作为地图。每个图块由包含其x / y坐标的Tile类描述。
当他们在地图上移动时,我需要能够让玩家“打开”。玩家类知道它当前的x / y,而Tile类知道它被分配给的x / y。
目前,需要渲染的所有切片都存储在Tile[][]
中。我对java很新,但似乎不是一个好主意(如果可能的话)只是简单地使用我想要的数据索引的x / y坐标 - 主要是因为我目前渲染的瓷砖可能并不总是从0,0
开始。假设玩家在1000,1000
时加载了已保存的游戏 - 当我不需要时,我肯定不会从0,0
加载游戏。
那么,存储这些坐标的最佳方法是什么?
在PHP中可以完成,因为我知道数组不关心从0开始的索引:
$tiles[1000][1000] = new Tile()
但我不确定Java推荐的方法是什么。不得不遍历每个单独的区块并检查x / y是否匹配,效率非常低。
答案 0 :(得分:2)
老实说,你问的是一个非常高级的话题。这种涉及大型地图的项目实际上无法用简单的数组来完成。有些人会建议使用简单的偏移和动态数组,但效率极低。
但是,我可以给你一个建议。您可以以块的形式加载切片。比如说,每个块是一个32乘32的2D数组。您可以加载当前块和周围的块,而不是通常加载围绕播放器位置的图块。例如,假设位置1000,1000落在块C中。然后加载块C和所有周围的块。当您从块C移动到块D时,您卸载围绕C的块,而是加载围绕块D的块块类看起来像这样:
class Chunk {
private Tile tiles[32][32];
private Coordinate origin; // (0, 0) on this chunk's array is actually equal to origin on the map
// Example: if the chunk started at (128, 128), then origin would be (128,128)
...
public static Chunk loadChunk(...) { ... }
...
}
你需要Map类来帮助定位和加载块:
class Map {
public Chunk currentChunk;
public ArrayList<Chunk> loadedChunks;
...
public ArrayList<Chunk> getSurroundingChunks( Chunk ch ) {...}
...
}
几乎所有使用大型地图的游戏都会以大块地图的形式加载(我的游戏是一个值得注意的例子,尽管该游戏的编程通常很差)。
当然,它在算法上很复杂,你需要进一步研究它,而不仅仅是阅读这篇文章。但它应该为您提供一个适用于任何大小的地图的强大系统,并且已被证明可以在现实世界中使用。
该系统的一个缺点是,由于垃圾收集,在Java中很难预测卸载。但是,我不知道一个强大的加载系统,至少不会受到Java垃圾收集器的轻微伤害。
请注意
这种技术也称为延迟加载。这意味着您只需将实际需要的内容加载到内存中。这是用于加载大量可预测数据的最佳技术,因为它允许您最小化加载时间和内存消耗。基于块的加载并不是唯一的延迟加载,但我甚至可以说它可能是最好的。
答案 1 :(得分:0)
您可以使用Map
来保存数据,并使用Coordiate
对象作为关键字。 Coordinate
对象应实现equals
和hashCode
。这应该非常快速和简单。
您可以向地图添加项目:
map.put(new Coordinate(1000,1000), new Title(...));
你可以通过以下方式恢复它:
Title title = map.get(new Coordinate(1000,1000));
答案 2 :(得分:0)
另一种方法是使用Dictionary来存储切片。它不一定是最有效的,但它会起作用:
java.awt.Point p = new java.awt.Point(1000,1000);
Tile t = // however you get your tiles
java.util.Dictionary<java.awt.Point, Tiles> theDictionary = new java.util.Dictionary<>();
theDictionary.put(p, t);