1-啥是AOI
AOI全称Area Of Interest,中文就是感兴趣的区域,个人理解就是玩家关注的并且可视的地图区域。
在RPG游戏中,玩家角色移动,攻击,放技能等操作都需要向其他玩家广播,但服务端由于性能原因,会避免往整张地图上的角色进行广播。为了把性能消耗降到最低,同时不影响玩家的游戏体验,就只会向玩家关注并感兴趣的区域,也就是AOI进行广播。
2-AOI-网格法(九宫格)
1# 建立坐标系
我们(0,0)坐标为地址原点,再以16*8为一个格子,编号1,2…7,8共64个格子,建立坐标系与一张16:8的地图。如下图:
假设玩家处在编号为20的格子的坐标集中,那玩家的AOI(九宫格),就认为是玩家所在的格子和周围的8个格子,也就是上图的黄色部分。
%% 获得当前坐标所在格子的编号
get_cell(X, Y) ->
Y div 8 * 8 + X div 16 + 1.
2# 广播原则(以玩家移动为例子)
- 当前坐标和目标坐标在同一格子,向以当前格子为中心的九宫格中的玩家发送"移动"广播。
- 当前坐标和目标坐标不在同一格子,设"以当前格子为中心的九宫格"为Old,“以目标格子为中心的九宫格"为New,向New和Old交集(New U Old)的区域的玩家广播"移动",向Old和New差集(Old - New)区域中的玩家广播"离开”,向New和Old差集(New - Old)区域中的玩家广播"进入"。下面用图举例三种情况:
假设玩家从"格子19的坐标"移动到"格子20的坐标",也就是九宫格从黄底区域变成了红字区域。
因此:
向绿色区域的玩家发送"离开"广播,向蓝色区域的玩家发送"移动"广播,向黄色区域玩家发送"进入"广播
3-代码说明(erlang)
%% 获得当前坐标所在格子的编号
get_cell(X, Y) ->
Y div 8 * 8 + X div 16 + 1.
%% 执行判断
do_bool([]) -> ok;
do_bool([{
Bool, Fun}|L]) ->
case Bool of
true -> Fun;
false -> do_bool([{
Bool, Fun}|L])
end.
move_broadcast([X1,Y1], [X2,Y2]) ->
OldCell = get_cell(X1, Y1),
NewCell