关于AOI的一些想法

449 阅读2分钟

AOI,即 Area of Interest,其实就是一个可视距离检测(个人理解),就是只关心自己视野内或者感兴趣的对象,其他的对象直接忽略

使用的算法

  • 全局遍历,这种最消耗性能,但是可以用来检验其他的算法的正确性

  • 网格法,现在我自己用到的服务器使用的就是这种

    • 将地图按照长度宽度都为 W 划分成 N 个格子
    • 当玩家A移动时,检测玩家新移动到的点所在的格子跟旧格子是否为同个格子
    • 如果是同一个格子,则不触发任何操作
    • 如果是不同的格子
      • 将玩家A在旧格子能看到的其他玩家从观察对象列表中移除, 此时操作的是玩家A的观察对象列表
      • 将玩家A在新格子能看到的其他玩家假如到观察对象列表中, 此时操作的是玩家A的观察对象列表
      • 将玩家A从旧格子的观察对象列表中移除, 此时操作的是旧格子的观察对象列表
      • 将玩家A添加到新格子的观察对象列表中, 此时操作的是新格子的观察对象列表
    • 然后触发格子变动时的一些回调
      • 通知看到旧格子的玩家,将玩家A从他们的观察对象列表中移除, 此时操作的是能看到旧格子的玩家的观察对象列表
      • 通知看到新格子的玩家,将玩家A添加到他们的观察对象列表中, 此时操作的是能看到新格子的玩家的观察对象列表
      • 将玩家A从旧格子的对象列表中移除,对象数减一, 此时操作的是旧格子的对象列表
      • 将玩家A添加到新格子的对象列表中,对象数加一, 此时操作的是新格子的对象列表
      • 区域刷怪检测
  • 十字链表法,这种据说比较高效

    • 场景里维护两个列表,一个X轴的,一个Y轴的
    • 这两个链表都是双链表
    • 按照坐标从小到大排序好,插入的时候就排好序的
    • 找指定区间的集合的话,就是遍历两个链表,找出在 x1~x2y1~y2 里的集合
    • 提供的接口有下面三个
      • Add
      • Leave
      • Move

一些问题

  • 在十字链表法里,如果场景中对象很多,几万个,那么遍历链表,会不会很耗性能

  • 在十字链表法里,频繁地增删节点,会不会有性能问题