接下來打算做一個國戰類的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消息。