网络游戏开发实战系列 1.3 MMORPG AOI算法的原理与详解

前言

MMORPG核心算法之一就是AOI,本文主要从3个点来分析一下AOI算法的基本原理与实现步骤详解。

(1) 为什么MMORPG里面要使用AOI?

(2) AOI算法类型与AOI同步的主要事件;

(3) 基于九宫格AOI算法的实现详解;

对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀

为什么MMORPG里面要使用AOI

假设MMORPG的一个单服游戏服务器上有3000个人在服务端的游戏地图上正在游戏,如果在理论上服务端要维持这3000人的游戏的数据与状态等, 客户端要创建3000个这样的玩家来在客户端上,接受服务端发来的3000个人中的玩家状态的变化,从而更新画面,同步状态。这样会导致一个问题,对于客户端而言,它要维持3000个角色个体的消息处理,动画等逻辑处理。对于服务端而言,每次有要给人状态有变化,要全部发给其它的2999个角色,这样带宽也会很高,新进来一个人登录到游戏服,要把所有的3000人的状态全部传送过去也是占用很大带宽。

对于客户端而言,他其实不用也不可能一下全部看到地图上的所有玩家,他只要处理好在他视野范围内能看到的玩家就好了。对于服务端而言,只要把状态发送给”能看见他”的其它玩家就可以了。这样客户端+服务端的同步数据量与计算量将大幅度的减少。决定某个玩家能看见哪些玩家,以及哪些玩家进入了“能看见”区域,哪些玩家又离开了”能看见区域”这个技术我们叫做AOI(Area Of Interest)。对于每个客户端而言,只要同步它周围AOI的玩家的状态就可以了,然后服务器负责管理好哪些角色进入了AOI区域,哪些离开了AOI区域,然后告诉客户端,客户端对于进入AOI区域的角色就创建出来,离开AOI区域的角色就删除掉。

AOI算法类型与AOI同步的主要事件

分析了MMORPG为什么要使用AOI,接下来聊下主流的AOI的算法与AOI代码编写前要理解的几个概念。目前主流的AOI算法有十字链表与九宫格算法。当MMORPG引入AOI管理后,就会多出几个概念:

(1) EnterAOIEvent: 一个角色,怪物或NPC,进入A玩家的AOI区域内,服务器就会发送一个事件EnterAOI,告诉这个A玩家对应的客户端,这个客户端收到这个事件后,更具服务器的状态把角色创建出来;

(2) LeaveAOIEvent: 一个角色,怪物或NPC,离开A玩家的AOI区域,服务器就会发送一个事件LeaveAOI, 告诉这个A玩家对应的客户端,这个客户端收到这个事件后把离开的角色怪物或NPC删除掉。

本文我们的AOI算法采用的是九宫格算法,我们把整个可视范围(AOI)划成一个九宫格。如图:

为什么很多游戏用九宫格算法,我们列举出来它的几个特点:

1: 基于九宫格,我们将地图分成MxN的块, 某个玩家A在地图上一定会属于某个块。这个块+连同它周围的9个块都属于这个玩家A的AOI区域。在这9个块的游戏玩家就是玩家A的AOI区域内的玩家, 玩家A对周围的角色与玩家的状态变化感兴趣。

2: 基于九宫格,玩家A周围的九个块上的角色也同时对玩家A的状态变化感兴趣的角色,所以当A有了状态变化的时候,我们能基于A快速的找出对这个状态感兴趣的人。

总结一下,基于九宫格,非常方便的能找到对玩家A状态变化感兴趣的人玩家A对哪些人的状态变化感兴趣。

基于九宫格AOI算法的实现详解

讲解完九宫格的一些特点以后,解析来分析一下九宫格算法的详细步骤:

step1: 确定一个AOI区域的大小,你在游戏中你看角色与怪物的可视范围(AOI),一般我们选的和视野差不多大;

step2: 视野AOI大小确定后,将视野AOI大小, 分成九宫格, 这样得到每一个块的大小;

step3: 将整个的地图按照九宫格的每个大小分成对应的块;

step4: 将每个格子对应一个格子管理对象,这个管理对象保存和记录了所有在这个格子的角色,怪物或NPC;

step4: 创建一个玩家到服务器的同时,根据玩家的位置,将玩家对象保存到对应的格子管理对象上。

Step5: 每次玩家移动,根据移动后的位置重新计算玩家所在的格子,这里注意,有可能移动使得玩家改变了格子,也有可能没有改变。如果格子没有改变,不用做任何处理;

Step6: 当玩家A所在的格子发生变化的时候,玩家A的九宫格的块就会发生变化。

a类格子对象:在原来玩家A的九宫格中,但是不在现在玩家A的新九宫格中的格子对象;

b类格子对象:在原来玩家A的九宫格中,也在现在玩家A的新九宫格中的格子对象;

c类格子对象:不在原来玩家A的九宫格中,但在现在玩家A的新九宫格中的格子对象;

Step7: 对于b类格子,我们直接跳过不用处理;

Step8: 对于a类格子对象,我们要遍历它里面的所有玩家,告诉它们玩家A离开了它们的AOI,给它们发送玩家A离开的LeaveAOI的事件, 让它们的客户端删除掉玩家A对象。给玩家A发送这些玩家的LeaveAOI事件,让玩家A的客户端,删除掉这些对象。

Step9: 对于c类格子对象,我们遍历这些格子里面的所有玩家,把这些玩家的状态与EenterAOI事件发送给玩家A,让玩家A创建出来这些新视野块里面的对象。把玩家A的状态与EnterAOI事件同步发送给这些玩家,让这些玩家客户端把对象A创建出来。

加上AOI以后,这样我们的每个客户端就只要同步它能看见的玩家的状态就可以了。

今天的分享就到这里,关注我们,学习更多的网络游戏同步的教程。

附:视频教程

Unity / 精选推荐 MMORPG核心技术:AOI算法源码分析与详解​www.bycwedu.com/promotion_channels/690101486

猜你喜欢

转载自blog.csdn.net/Thomas_YXQ/article/details/134513908
1.3
今日推荐