如果你玩过mmo的游戏,你可能会有这样的游戏体验,当我们身处某个地图中时,我们在手机屏幕中看到的通常只有地图的一部分,我们能看到附近其他玩家的移动情况,如果跑一跑地图,也许能看到刷出来的boss或者打酱油的npc。所谓视野管理,就是如何维护玩家在地图当中看到的移动的其他玩家和npc。
以下是我的理解,如有错漏,欢迎批评指正。
最暴力的方式:一个列表维护一张地图所有玩家数据
我们先用最暴力的方式,我们可以维护一个地图上所有玩家的位置列表。针对某个玩家的位置更新,我们做以下处理:
- 当某个玩家假设为A玩家发生移动时,通知其他所有的玩家A玩家移动了,修改列表中玩家A的位置;
- 当玩家A离开地图时,将玩家A从列表中删除;
- 当新的玩家加入地图时,新增玩家的位置到列表中。
这样是最简单的方式,逻辑简单,维护一个列表就可以解决地图中某个移动玩家位置变化的问题。
但这样也会产生以下问题:
- 当地图中一个玩家的位置发生变化,就要通知地图上所有的玩家,而事实上,玩家的实际视野范围并不需要 知道所有地图上玩家的位置更新情况。
比如玩家A只是在主城的小角落里和npc对话,玩家B在玩家A看不到的城门那里跑来跑去,玩家A是根本不需要关心B的移动情况的。服务器地图上给1000个人发广播消息,和只需给在视野内的10个人发广播消息,所需要的带宽压力是不一样的。
于是针对这种问题我们需要进行优化。
常用的方案:视野管理的九宫格法
你也许想到了,既然如此,针对玩家A,我们只给玩家A发该玩家视野内的其他玩家移动情况不就可以了吗?
那么我们这里就涉及到了两个概念,一是如何定义玩家视野,二是如何将玩家视野与整张地图关联起来。
这里介绍一种aoi算法的九宫格法版本。
首先我们可以将整张地图进行划分,划分为等大的格子,类似这样:
玩家A进入地图时,我们认为玩家的位置在地图上的某个格子上。
我们定义玩家在视野范围在这周边的九宫格内,其中九宫格是略大于一个手机屏幕小于两个手机屏幕的。
这样我们只需要关注九宫格内其他格子玩家的位置,而不是整个地图的玩家的位置。
当玩家A移动时(比如从格子5移动到格子4),我们可以做以下处理:
- 如果玩家A加入地图时,算出玩家在哪个格子,加入该格子,通知九宫格内其他格子的玩家;
- 玩家A离开地图时,通知九宫格内其他格子的玩家,同时从玩家A从格子中删除;
- 如果玩家A在格子内移动,我们通知九宫格内其他格子所有的玩家关于玩家A的位置变化。
- 如果玩家A跑出了原本的格子,那么我们通知离开的这几个格子里的玩家(下图中的格子3、格子6以及格子9)。同理也需要通知新加入的格子里的其他玩家(下图中的格子11、格子12以及格子13),玩家A从新加入的格子中获取需要关注的新玩家。
关于aoi算法还有灯塔法、十字链表法,如果这篇文章点赞过5个,那么我就继续更新下篇~
喜欢的话就点个赞吧~