以下为个人学习笔记整理。

# 浅谈 AOI

AOI(Area Of Interest)—— 感兴趣区域。在多人在线类游戏中,通常使用 AOI 来描述一个实体的可见范围,例如周围的其他实体。一方面用于减轻客户端的压力,保证不影响玩家体验的情况下,尽可能少的显示物体。另一方面很多游戏机制的实现也依赖于 AOI,例如光环效果,怪物 AI,地雷引爆等。

# 实现方式

常见的 AOI 实现有两种:

  • 十字链表形式
  • 网格划分形式

# 十字链表实现

假设每个点都是一个实体,因此可以根据实体的 x,z 坐标构建一个双向十字链表如下图。

image-20220111170626414

# 实体位置变更

根据对应的 x,z 坐标,删除之前的节点,把新坐标插入到十字链表相应位置即可。

# 计算 Enter_me

根据节点自身的 AOI 范围(蓝色方块)双向遍历链表,计算出区域内的全部对象,在和上一次记录的 Enter_me 做一个差集即可。

image-20220111170926710

# 加速

在地图过大的情况下,插入和删除所用的时间就会暴增,因此需要加入锚点来快速定位插入位置。下图中黑色点。

锚点会根据坐标编号存储在单独的数组内,用于插入和删除节点时可以快速从某个位置进行查找,减少查询开销。

image-20220111172613922

# 特点

  • 内存开销取决于实体数量,实体越多开销越大,「双向链表」+「十字链表」会有更多的额外内存消耗。
  • 查询、增删效率取决于锚点设置。
  • 实体位置频繁变动的情况下比较不理想,需要频繁插入和删除。

# 网格划分实现

把地图切割为均等大小的网格,把物体加入到不同网格的集合内,计算 AOI。

image-20220111174634755

# 实体位置变更

通过实体坐标对网格长宽取整的方式就能快速获取到对应的网格,当实体位置变化时,只需要更新位移前后所属的网格集合即可。

image-20220111175456921

# 计算 Enter_me

Enter_Grid 内的所有实体就是进入实体。

image-20220111175051155

# 特点

  • 实现简单,且运行高效。
  • 大地图且稀疏实体的情况下,会有更多额外的内存开销 —— 构建 Grid 结构。
  • 能够应对频繁的位置变化。
更新于 阅读次数

请我[恰饭]~( ̄▽ ̄)~*

鑫酱(●'◡'●) 微信支付

微信支付

鑫酱(●'◡'●) 支付宝

支付宝