在Java(Swing)中,我说我有一个2D游戏,我在屏幕上有各种类型的实体,例如玩家,坏人,通电等。当玩家在屏幕上移动时,按顺序为了有效地检查玩家附近的内容,我认为我希望根据他们的位置对角色附近的东西进行索引访问。
例如,如果玩家'P'在以下示例中步入元素'E'...
| | | | | |
| | | |P| |
| | |E| | |
| | | | | |
...会做类似的事情:
if(player.getPosition().x == entity.getPosition().x &&
entity.getPosition.y == thing.getPosition().y)
{
//do something
}
这很好,但这意味着实体保持其位置,因此,如果我在屏幕上有多个实体,我将不得不循环遍历所有可用的实体并检查每个位置与玩家位置。这似乎真的很低效,特别是如果你开始获得大量的实体。
所以,我怀疑我想要某种类似
的地图Map<Point, Entity> map = new HashMap<Point, Entity>();
并将我的点信息存储在那里,以便我可以在固定的时间内访问这些实体。该方法的唯一问题是,如果我想将实体移动到屏幕上的不同点,我将不得不搜索HashMap的值以寻找我想要移动的实体(因为我不知道它的效率低效)提前点位置),然后一旦我发现它从HashMap中删除它,并用新的位置信息重新插入它。
我应该在这里使用哪种数据结构/存储格式的建议或建议,以便根据实体的位置有效访问实体,以及基于实体的职位?
答案 0 :(得分:4)
空间划分可能有效。
你可以做固定的划分,比如统一网格,或加权网格,除非你的地图上有热点,事情变得异常聚集。对于每个占用的分区,创建一个包含其所包含的所有实体的容器。
插入是恒定时间。删除是 n (您的实体总数)的实际上无穷小部分,假设 n 非常大并且您已经有效地设置了分区。邻近查找与移除共享相同的运行时。尽管如此,技术上仍然是O( n )。如果分区变得异常拥挤,这将变得明显。
要获取实体的 x 单位内的所有实体的列表,您必须首先获得以2
更复杂的分区方法是动态分区树中的空间,确保没有分区可以包含多于给定数量的实体。如果分区变满,则将其沿空间均值划分,并创建两个空间分区,使每个分区保留原始分区实体的一半。这使得插入和查找具有对数运行时,因为您无法再在恒定时间内发现所需的分区,但是在给定上限分区的情况下,删除变为恒定时间。
答案 1 :(得分:3)
如果Entity
和Point
之间存在一对一的映射,并且您希望能够在两个方向上进行映射,那么bimap是最自然的数据结构。
Guava有BiMap<K,V>
实现,支持BiMap<V,K> inverse()
视图操作。这只是一种观点,所以它的成本并不高。
或者,您可以管理自己的Map<Entity,Point>
和Map<Point,Entity>
,但这会重新发挥作用。
答案 2 :(得分:0)
效率低,因为我不提前知道它的Point位置
我是否正确,该实体对象中没有位置信息?我建议添加它。或者,您可以拥有当前实体位置Map<EntityIdType, Point>
的地图并首先获取位置。没什么好看的。