转载:https://blog.csdn.net/ybn6775/article/details/81701167
AOI(Area Of Interest),中文就是感兴趣区域。通俗一点说,感兴趣区域就是玩家在场景实时看到的区域;也就是AOI会随着英雄的移动改变而改变。游戏的AOI算法应该算作游戏的基础核心了,许多逻辑都是因为AOI进出事件驱动的,许多网络同步数据也是因为AOI进出事件产生的。因此,良好的AOI算法和基于AOI算法的优化,是提高游戏性能的关键。

在这里我们只说设计思想理论, 不说具体代码。
4种方法:全场景同步法(最粗暴简单)、网格法、十字链表法、热点法

统一接口设计:
AOI需求大概是这样:
1.游戏地图上有一些npc和玩家在移动,每一个这样移动的对象我们叫做AOIEntity,每一个AOIEntity可以挂多个不同半径的AOI,每一个这种半径的AOI单元我们叫做AOINode,如此,AOIEntity拥有多个AOINode,然后每一个场景管理者AOIManager管理着多个这样的AOIEntity对象。
2.AOI进出事件由三种行为产生:进入场景,离开场景,在场景移动,因为这是AOIEntity相互之间的作用,故因放在AOIManager中统一管理,接口类似这样:
void AOIManager:Enter(AOIEntity *entity, cosnt Point& target_pos);
void AOIManager:Move(AOIEntity *entity, cosnt Point& target_pos);
void AOIManager:Leave(AOIEntity *entity);
3.添加一个AOINode的接口,主要参数是Id(用于标识这个AOI),半径,进出事件的callback函数:
void AOIEntity:AddNode(int aoi_id, float radius, AOICB enter_cb, AOICB leave_cb);
4.获取周围对象和观察者玩家对象集合的接口,这个可以在更上层,通过在响应进出事件的enter_cb, leave_cb中维护这样的集合。

1.全场景同步法(最粗暴简单)
即任一实体变动时,都广播给其他在场的所有实体。
适用范围:玩家比较少的小型场景,比如组队副本。
游戏实例:比较早期的游戏,比如:天骄II及其衍生品等。
缺点:玩家较多时,消息量骤增。
优化方案:每个实体变动时,遍历所有实体,判断距离在视野内的,才广播。也可以实时维护这个可见列表。
2.网格算法:
既是把整个场景用网格划分成一个一个小区域(划分粒度可调整),每一个区域是当前场景该区域内的AOIEntity集合,当有一个AOIEntity移动时,根据对象移动之前坐标和目的地坐标,算出移动前所在网格SrcGrid和目的地网格DstGrid,根据一个可调的偏移参数,算出受这次移动影响的各个网格所在的一个网格区域(通常是一个包含这些网格的一个大网格),遍历每一个这样的网格里的每一个AOIEntity,与这个移动AOIEntity互相作比较,主要是比较这些事情:
1.是不是对方曾经在我的一个AOINode的半径内,移动后就不在了,是则产生离开回调;
2.是不是对方曾经不在我的一个AOINode的半径内,移动后就出现了,是则产生进入回调;
注意虽然移动是一个AOIEntity在移动,但是这种比较却要是互相的。
上面说的是网格算法的最简单实现了,当然实践上有许多地方可以优化和调整,包括使用更高效的数据结构,不细说。
细分:还可以分为“九宫格法”和“灯塔法”。“九宫格法”——每个区域中记录的是处在本区域的实体。“灯塔法”——每个区域中记录的是会观察到我的实体。“灯塔法”可以看做是“九宫格法”的进一步优化。
适用范围:多数2DMMORPG。
游戏实例:天龙八部及其衍生品等。
缺点:存储空间不仅和对象数量有关,还和场景大小有关。更浪费内存。且当场景规模大过对象数量规模时,性能还会下降。
优化方案:区域大小根据场景具体情况进行配置,可提高效率。比如5人副本,可以配成整个场景一个区域。

3.十字链表算法:
算法基本上就是围绕两个双向链表在转–代表X轴的链表(叫做LinkListX)和代表Y轴的链表(叫做LinkLIstY)。对于每一个AOI单元,以AOIEntity的坐标位置为中心,可以构造出一个AOI矩形(以四元组[xleft,xright,ytop,ybottom]表示)。LinkListX链接的是所有这样的AOI矩形的xleft,xright,LinkListY链接的是所有这样的AOI矩形的ytop,ybottom,并且两者都是按照坐标值从小到大的顺序链接起来的。这样每一个AOI单元都在LinkListX,LinkListY上产生了总共4个节点,特殊的对于每一个可见的AOIEntity,以他们的坐标(XCenter,YCenter)在LinkListX,LinkListY上又产生了总共2个节点。现在当AOIEntity在场景中移动时,他所包含的在LinkList中的节点会相应的更改坐标值,而LinkList为了维护从小到大的顺序,会遍历链表,移动位置,直到重新有序。LinkList在这个过程,会产生AOI事件。

  • 具体来说,当AOIEntity要移动到(targetX,targetY), 对应的AOI矩形变成[targetX-R, targetX+R, targetY-R, targetY+R],显然这四个节点值的改变后LinkList不再有序,现在来调整LinkList,可以这样来理解这个过程,对象先在X轴上移动到targetX,对应的是在LinkListX上移动,每次交换两个节点的位置都应该判断:1.两者的拥有者是不是不同的Entity;2.是不是一个是代表Entity的节点,一个是代表AOI矩形边界的节点;3.两者的拥有者整体上能否确实产生AOI进出事件。然后在Y轴上移动到targetY,过程与X轴对称。
  • 可以总结一下,LinkList的节点的属性:
    struct LinkNode {
    byte _type; // 代表类型,主要是区分AOI矩形的边界和Entity本身
    AOINode *_owner; // 属于哪个AOI单元,这里把代表Entity本身的节点也当作一个R=0的AOI单元
    int _pos_val; // 坐标值,
    struct LinkNode *_next, *prev;
    }

END.

MMORPG游戏中AOI视野算法解析相关推荐

  1. java 寻路算法_游戏中的寻路算法解析

    游戏角色的自动寻路,已经是游戏中一个历史比较悠久的领域,较为成熟也有很多种实现.这里摘录一句后面所提的参考资料中的描述:"业内AI开发者中有一句话:"寻路已不是问题."我 ...

  2. 算法:游戏内AOI视野算法(十字链表)

    为什么要有这个算法? 对于一个游戏场景内的实体来说,当战斗频繁的时候,可能存在上千实体的数据同步,例如上千实体移动时的坐标同步,大型战斗场景时全场景实体的属性的同步等等,这样就会造成一个问题,同步数据 ...

  3. 23种设计模式在MMORPG游戏中的应用

    设计原则和设计模式是软件工程领域的两个重要概念,设计原则提供了编写高质量.可维护代码的指导思想,而设计模式则为特定问题提供了经过验证的解决方案.下面是7大设计原则和23种设计模式的总结: 7大设计原则 ...

  4. 那些游戏中的寻路算法

    在游戏中,AI人物的移动往往有许多种实现方法,本文主要列出其中的几种常见的2D寻路方法并附上完整源代码,供读者参考,批评以及指正. 所有的代码均在Unity下完成,并通过测试可以使用. Depth-F ...

  5. 游戏中的AI算法总结与改进

    一.人工智能的定义 人工智能(AI,Artificial Intelligent),指的是通过算法编程使计算机模仿人完成一些像人一样的任务,同时在执行任务时模仿人的思维和智慧,甚至通过大量学习训练积累 ...

  6. Linux源码中的mktime算法解析

    Linux源码中的mktime算法解析 我们知道,从CMOS中读出来的系统时间并不是time_t类型,而是类似于struct tm那样,年月日时分秒是分开存储的. 那么,要把它转化为系统便于处理的ti ...

  7. 游戏服务器AOI兴趣点算法原理--四叉树与九宫格 (golang)

    定义: 获取感兴趣的区域(Area Of Interest)的算法.主要用于常用的游戏服务器压力,降低网络风暴的可能. 常见的AOI算法有九宫格,四叉树,灯塔,十字链表等算法.本文主要举例九宫格和四叉 ...

  8. 游戏差异更新—BSDiff算法解析

    为何需要差异更新? 差异更新即在软件更新时只更新差异化的部分,以达到用最小的下载量完成软件的更新需求.该思想由来已久,从刚接触电脑时的操作系统.应用软件快速更新功能或填补漏洞,到迭代更加频繁的移动应用 ...

  9. OpenCV中泛洪填充算法解析与应用

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:opencv学堂 泛洪填充(Flood Fill)很多时 ...

最新文章

  1. sap系统工单关闭_什么样的系统算是坑
  2. Web前端人员如何面试?常见vue面试题有哪些?
  3. 泛型中的模糊继承,解析T的意义
  4. linux+eth0+流量监控,linux流量监控脚本 | 旺旺知识库
  5. 服务器升级虚拟化,刀片服务器内置虚拟化 IBM升级服务器
  6. appweb ejs_具有快速路线的EJS
  7. oracle+行换列,Oracle的数据表中行转列与列转行的操作实例讲解
  8. ElasticSearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解...
  9. java jdk安装 win10,Win10安装多个jdk,共存环境配置,自由切换
  10. 2022年考研数据结构_2 线性表
  11. 实现手机访问网站时点击手机号码直接拨打电话的功能
  12. 【车道线检测与寻迹】【1月8日】车辆、道路模型与道路跟踪
  13. 黄绿色——五色配色篇
  14. cardinal numbers (基数词) - ordinal numbers (序数词)
  15. OneDrive登录时出现问题· 请稍后重试。(错误代码: 0x8004de25)
  16. 2种前端实现图片加水印的方式
  17. KCF算法(相关滤波算法) 跟踪目标
  18. 嫁人就嫁程序猿:不说话则已,开口就是段子手
  19. String简单介绍
  20. Linux 下的pxi设备,什么是PXI?

热门文章

  1. Beeline 的进阶使用
  2. 如何利用阿里云赚钱_5种利用云赚钱的策略
  3. QQ浏览器怎么同步通讯录?QQ浏览器同步通讯录的方法
  4. 浙江工业大学计算机应用基础,本科教学-浙江工业大学计算机科学与技术.doc
  5. 一英寸芯片大小_芯片生产线的6英寸,8英寸。12英寸。40英寸。是什么意思
  6. 永磁同步电机控制系列
  7. 网络游戏运营的整体流程
  8. 低功耗电池摄像机、低功耗摄像机、低功耗WiFi摄像机
  9. 谷歌大脑提出VeLO优化器,无需调参,最高比Adam快16倍!
  10. 127.0.0.1:3000端口已被占用