java - Java中游戏实体位置的高效映射

标签 java algorithm data-structures dictionary

在 Java (Swing) 中,假设我有一个 2D 游戏,屏幕上有各种类型的实体,例如玩家、坏人、 Prop 等。当玩家在屏幕上移动时,顺序为了有效地检查玩家附近的事物,我想我希望根据角色的位置对角色附近的事物进行索引访问。

例如,如果玩家“P”在以下示例中踏上元素“E”...

| | | | | |
| | | |P| |
| | |E| | |
| | | | | |

... 会做类似的事情:

if(player.getPosition().x == entity.getPosition().x && 
              entity.getPosition.y == thing.getPosition().y)
{
    //do something
}

这很好,但这意味着实体保持其位置,因此如果我在屏幕上有许多实体,我将不得不遍历所有可能的可用实体并根据玩家位置检查每个实体的位置。这似乎真的很低效,尤其是当您开始获得大量实体时。

所以,我怀疑我想要某种类似

的 map
Map<Point, Entity> map = new HashMap<Point, Entity>();

并将我的点信息存储在那里,以便我可以在恒定时间内访问这些实体。这种方法的唯一问题是,如果我想将一个实体移动到屏幕上的不同点,我必须在 HashMap 的值中搜索我想移动的实体(效率低下,因为我不知道它提前指向位置),然后在我找到它后将其从 HashMap 中删除,并使用新的位置信息重新插入它。

关于我应该在这里使用哪种数据结构/存储格式以便根据实体的位置有效地访问实体以及基于实体的位置有什么建议或建议吗?

最佳答案

空间分区可能是有效的。

您可以进行固定划分,例如统一网格,也可以进行加权网格,前提是您的 map 上存在一些异常聚集的热点。对于每个占用的分区,创建一个包含它包含的所有实体的容器。

插入是常数时间。假设 n 非常大并且您已经有效地设置了分区,则移除实际上是 n(您的实体总数)的无穷小部分。邻近查找与删除共享相同的运行时间。尽管如此,从技术上讲仍然是 O(n),但分数很小。如果分区变得异常拥挤,这一点就会变得很明显。

要获取实体 x 单元内的所有实体的列表,您必须首先获取以 2x 宽的正方形为中心的所有分区的列表你的实体。如果您使用网格分区,这是相当微不足道的。接下来,您遍历这些分区中的所有实体,并返回与相关实体的距离为 x 或更短的每个实体。

一种更复杂的分区方法是动态分区树中的空间,确保任何分区都不能包含超过给定数量的实体。如果一个分区已满,您可以沿空间均值划分它并创建两个两个空间分区,这样每个分区都包含原始分区实体的一半。这使得插入和查找具有对数运行时间,因为您无法再在常数时间内发现所需的分区,但鉴于分区数量上限,删除成为常数时间。

关于java - Java中游戏实体位置的高效映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3027538/

相关文章:

java - 在 Websphere Clustring 环境中分离 Log4j 日志

arrays - 计算乘积不能被 k 整除的子数组的个数

java - 切换 Camel 中的窃听队列

algorithm - 最坏情况下的 NFA 复杂度是 O(N*M) 还是 O(N*M^2)?

algorithm - 包络算法优化——放置圆圈的最佳位置

java - DoublyLinkedList(普林斯顿版)删除方法如何工作?

javascript - 拥有 N(数组中出现的次数)和一个数组,如何获取数组中出现 N 次的元素?

c++ - 我可以更好地找到给定值在二叉搜索树中的位置吗?

java - 是否可以从索引数据结构中删除并同时避免移位?

java - 如何正确使 dbunit 引用 xml 数据集中的 dtd 文件?