单一世界十万在线webgame的设计思路(三)--地图模块设计思路
地图模块:
地图在传统策略类webgame里都是以平面的方式展示和存储的。地图的移动都是在这个平面上实现。但一般来说,平面地图的设计容量都会有一个上限,一般来地图多为400*400,他的人数上限就是16w,实际上服务器容纳3~5w人后,整张地图就会显得很拥挤了。如果要想容纳几百万人在线,平面地图的尺寸就需要扩容得相当大了,这样玩家从地图中间移动到边缘的时间会相当恐怖,因此平面地图在这里不是很合适。因此,地图不能用平面来构造,必须是立体的方法构造。在这里我设计了两组方案:
立体平面空间:
如上图所描述的,立体平面空间,就是把多块地图一层层叠加在一起,形成一个立体的空间。这样如果用户不够,再增加一个新的平面就行。游戏的背景可以根据需要做调整(例如整个世界是被大海隔开的5片大陆组成,在这5片大陆之外,还有其它的超位面空间,这些空间自身是互不相连的,但是可以通过传送阵进行位面传送)。这样做的好处是,用户容易理解,以往用户的操作习惯不用改变,毕竟都是在平面地图上战斗。只不过要做跨位面的战斗的移动计算上会存在问题(逻辑上的问题:是否允许跨大陆的远征军)
用户坐标的表示方法:地图层次、x坐标、y坐标
数据库设计方案:
采用了层次结构,只需要增加一个地图层次的字段,这个地图表就能沿用。(参考字段:ID、地图层次、X坐标、y坐标、地图类型、玩家ID、城池ID)
虽然说,加入了一个地图层次的字段能解决地图的表示问题,不过,因为整个游戏世界是单一世界的服务器,当所用地图信息存储到一张表的时候,这数据量就不容小视。在这之前做webgame项目的时候,整张地图是预先生成好数据库记录的,当有玩家加入游戏的时候,就去修改表里的玩家ID和城池ID。同时因为地图大小只有400*400,整张表也就16w条记录。但如果是要做一个承载500w人的服务器,那地图的尺寸最好是要800*800,并且地图的层次为15~20层,就算最小的15层,按照原先的设计思路,至少需要预先插入960w条记录。
数据量看上去比较夸张,不过对于SqlServer来说也不是处理不了,并且我们还将计划把地图表单独用一台服务器来处理,其压力远小很多。不过也不能不考虑当发生性能瓶颈时的优化处理。优化的方法有两个:
1. 拆分:按照地图层次,把这张表拆分成15~20张表,或者拆分到15~20个数据库里
2. 用疏矩阵存储:地图不预先生成用户的地图信息,而是有玩家加入时才插入数据。这个方案在服务器早期人数比较少时会得到良好的性能效果,但当用户人数达到一定量时,还是避免不了因为记录函数过多而导致而外的开销。
全立体空间:
全立体空间就是取消了平面的坐标显示,用户都是在一个三维的立体地图里战斗。好处是地图不用那么分散,在移动计算让很好处理,存在的问题就是游戏在显示的时候,如何表现地图的三维效果会比较困难。
用户坐标的表示方式:x坐标 y坐标 z坐标
数据库存储方案:
三维空间的数据库表设计结构可以和上面的表一样,而且也只能采用疏矩阵的方式存储,因为做成三维空间后,可表示的位置的记录数更多了。
可移动基地在全立体空间的设想:
早在两年前,看过《超时空要塞F》的时候,就产生了一个想法http://www.cnblogs.com/yahle/archive/2008/05/27/1208355.html,就是玩家的基地是可以移动的。玩家的母舰在游戏的过程中,已一定的速度在整个世界里移动。
可以移动体系的设计要点:
1. 用户的基地可移动
2. 用户基地只能拥有一个(武林三国、travian都能建立多个)
3. 空间坐标由x坐标 y坐标 z坐标 组成,并且坐标的值应为小数
4. 同一个坐标里运行多个玩家存在,玩家的航线交叉并不会造成影响(只是为了方便计算减少判断过程)
5. 移动的数据通过后台定时刷新
a) 每个短周期(1~60s)在内存里更新坐标
b) 每个长周期(10~100个短周期时间)将坐标的数据更新的数据库
6. 攻击舰队移动的时间是按照2个阶段来进行的
a) 第一个阶段是从母舰移动到目标坐标的时间
b) 第二个阶段,在快到达时(前60分钟),做一个判断,判断攻击舰队的雷达能否搜索到目标的母舰坐标,能则做攻击坐标的新修正,如果不能则继续按照原先的坐标点移动。以上判断将每隔1分钟做一次,直到到达目标坐标点。如果到达目标坐标点仍然无法视为攻击失败,舰队返回
7. 舰队的移动距离和舰队所携带的能量有关,超过移动范围的坐标,舰队是无法出发的。
8. 部队和母舰应该是可以进行空间跳跃实现长距离的移动,不过空间跳跃需要在制定地点消耗大量的能量才能实现。
9. 默认情况下,母舰移动速度为1格(x、y、z坐标)/天。
10. 默认舰队的雷达查询范围为1格
11. 默认母舰的雷达查询范围为3格