MMORPG服务器场景中的aoi算法思考

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lwtbn1/article/details/37961695

     最近在做一个移动平台上的MMORPG项目,负责服务器的工作,第一次做这种类型的游戏服务器的开发,准备工作时必须的,综合网上的资料和自己的想法,总结了一下AOI的实现方式,从以下三个方面来谈谈。水平有限,本文提出的实现方式可能会很笨拙,但是应付一般的场景还是可以的。
       1、关于怪物主动攻击玩家的检测
如果场景内有N个怪物,M个玩家,则进行一次检测需要计算N*M次玩家和怪物之间的距离,这种方法很笨。一种新的方式是:首先对游戏的场景进行一下划分,如下图,将场景划分成若干个格子,每个网格拥有唯一编号gridId,白色星代表当前玩家的位置,红色网格代表玩家所在的网格区域黄色的为8个临近区域,服务器为每个网格对象维护两个列表:monsterList和playerList,这两个列表记录了在当前网格中的怪物和玩家。

 

     当玩家进入场景后,将玩家当前所在的网格id(curGridId)设置为红色网格的gridId,将周围的8个黄色网格的gridId放入玩家的adjacentGridList中。具体的怪物攻击检测流程:

 

 

     这样处理的好处有:

     (1)    只有当玩家移动时才会进行怪物主动攻击玩家的检测。避免了不必要的检测;

     (2)    减少了计算怪物和玩家距离的次数,如一开始所述,如果场景内有N个怪物,M个玩家,则进行一次检测需要计算N*M次距离。该方法首先在场景更新线程中判断玩家是否从网格g1进入网格g2,判断时会与周围8个格子的中心点计算,最差的情况是计算8次,但是此处也可以优化,如果知道玩家的移动向量,则只进行一次计算就可以确定玩家是否跨越了格子。怪物攻击玩家检测线程中,只计算玩家当前所在的格子中的怪物与玩家的距离,计算次数为(假设每个格子中怪物和玩家平均分布):(N/格子数量)*(M/格子数量)。

     2、怪物移动控制
     游戏中会单独启动一个线程(T_MonsterMove)去执行怪物移动的操作,该线程属于定时线程,以1秒或更短的频率根据怪物的类型更新怪物的位置。并将移动后怪物的坐标信息发送给客户端,T_MonsterMove线程并不需要和主逻辑线程进行同步操作,因为T_MonsterMove线程中移动的怪物都是处于服务器托管的,怪物主动攻击线程检测到玩家进入怪物攻击范围后,会将该怪物从服务器托管列表中移除,交由客户端托管。
     3、怪物和玩家移动等信息的广播范围
在游戏中,我们把格子的大小定义为玩家360度视野的范围。adjacentGridList保存的是玩家相邻的8个格子id和curGridId保存的是当前玩家所在的格子的id。以玩家移动信息为例,只需要将消息发送给这9个格子中的玩家即可。将信息发送给相邻的8个格子的玩家可以避免玩家突然闪进视野的情况发生。


原文地址:https://www.cnblogs.com/xuxinstyle/p/11210071.html