MMORPG游戏AOI解决方案
接下来打算做一个国战类的MMO手游,国战类手游首相要解决的就是多人同屏AOI问题。稍微看了一下主流的解决方案,做个简单的记录。
目前最常见的是有两种解决方案,九宫格和十字链表。
一 九宫格
主要思路是讲场景地图分成多个格子,每个格子记录其周围的格子信息。
1 进入
角色进入场景,根据其坐标,将其置于一个格子之中;
然后向角色所在格子及其周围格子中的所有玩家发送add消息。
2 移动
设玩家移动之前的九宫格集合为old_set,移动之后的集合为new_set,则
向(old_set - new_set)集合中玩家发送leave消息;
向(new_set - old_set)集合中玩家发送add消息;
向(old_set & old_set)集合中玩家发送move消息;
3 离开
角色离开场景,向角色所在格子及其周围格子中的所有玩家发送leave消息。
缺点,因为是用格子定的是否向其发送消息,不可见的一些角色也会被发送,会有消息冗余,浪费宽带。
二 十字链表
首相,根据场景中所有角色的x坐标排序,将其放入一个链表x_list中;
然后,根据场景中所有角色的y坐标排序,将其放入一个链表y_list中。
这样,所有的角色同时位于两个链表中。
1 进入
玩家进入时,根据x、y坐标排序,分别插入到x_list,y_list中。
同时,根据可视距离,得到x_list中可视的角色集合x_set,y_set中可视的角色集合y_list,
那么(x_set & y_set)就是真正可视的角色集合,向其发送add消息
2 移动
根据角色之前的位置可以得到old_set;
移动之后,需要根据新的x、y坐标,重新找到角色在x_list,y_list中的位置,
然后的到新的可见角色集合为new_set,则
向(old_set - new_set)集合中玩家发送leave消息;
向(new_set - old_set)集合中玩家发送add消息;
向(old_set & old_set)集合中玩家发送move消息;
3 离开
向当前真正可视的角色发送levea消息,然后从x_list和y_list中删除即可。
缺点,每次移动需要重新更新角色在链表中的位置,浪费CPU
一般的游戏都采用的九宫格的方式来处理AOI消息。