> 文章列表 > 【从零开始学Skynet】实战篇《球球大作战》(十一):战斗场景设计

【从零开始学Skynet】实战篇《球球大作战》(十一):战斗场景设计

【从零开始学Skynet】实战篇《球球大作战》(十一):战斗场景设计

        现在的服务端框架有支撑数万玩家的能力,且支持横向拓展(即 增加物理机数量),理论上具有无上限的负载能力。下面以《球球大 作战》为例,说明怎样使用这套框架。

1、战斗流程

        玩家登录后,玩家可以做些非战斗操作(仿照work示例,可以实现 成就、背包、邮件、好友等功能),如下图所示:

当点击开始比赛按钮时,客户端会发生“进入战斗协议。战斗流程如下图所示:

 

        服务端会开启很多scene 服务,每个服务处理一场战斗。收到进入战斗的协议后,agent会随机选择一个战斗服务。进入战斗后,agent会与某个scene服关联。注意图中的虚线方框,不同方框里的服务可能位于不同节点,理论上scene服务可以部署在任意节点上,这增加了服务端的扩展能力。

2、游戏玩法

   我们简化一下《球球大作战》的玩法。如下图所示:
        战场中包含球和食物这两种对象,每个玩家控制一个球,其中黑 色小圆代表食物。当玩家进入战斗时,场景中会添加一个代表玩家的小球,它出生在随机的位置上,默认是很小尺寸(半径)。玩家可以 控制球移动的速度,比如设置为(1,0)会一直向右走,直到设置为0, 0)才停下来。场景中会随机生成一些食物,遍布各处,当小球碰 (吃)到食物时,食物消失,球的尺寸增长。

3、战斗协议

《球球大作战》的战斗流程涉及如下几条协议:

(1)进入战场协议      

        当玩家点击“开始比赛按钮时,客户端发送enter协议(见下图),服务端会做出能不能进入战斗的判定,并且将agent和某个scene 关联起来。
  • 如果成功进入战场,服务端会回应成功信息,且向同战场的其他玩家广播有人进入的消息。广播的消息包含三个参数,分别是刚进入的玩家id、它的坐标尺寸
  • 如果进入失败,例如玩家已经在战斗中,会回应失败信息,如您已在战场中,不能重复进入”

 (2)战场信息协议

        进入战场后,客户端需要显示战场中的球和食物。服务端会发送balllistfoodlist协议,如下图所示:

         以balllist为例,它依次包含了各个球的信息,每个球包含4个参数,分别是玩家idx坐标、y坐 标和尺寸。 服务端生成食物时,会给每个食物一个唯一id。在食物信息协议 foodlist中每个食物会包含idx坐标、y坐标这3个参数。

(3)生成食物协议

        战场会随机生成一些食物。服务端会广播addfood协议(如下图所示),此协议包含新生成食物的id、x坐标、y坐标。

 (4)移动协议

        当需要改变移动方向时,客户端会发送shift协议(如下图所示),设置小球的x方向速度和y方向速度。

        所有游戏逻辑由服务端判定。每当小球的位置发生变化时(每隔一小段时间),服务端就会广播move协议(见下图),更新小球的坐标。move协议是发送频率最高的协议,假设服务端每0.2秒更新一次 小球位置,战场上有10个小球,那么每个客户端每秒将收到50move协议。

        

说明:每个客户端每秒将收到50move协议,这个频率非常高,但有不少优化方法,比如可以将多个小球的位置信息合并成一条 协议或使用AOI算法做优化(后面会提到)。

(5)吃食物协议 

        当小球吞下食物时,服务端会广播eat协议(见下图),此协议的参数包含玩家id、被吃掉的食物id和玩家的新尺寸

(6)离开协议

        当玩家掉线时(离开战场),服务端会广播leave协议(如下图所示),告诉战场中每一位玩家,有人离开了。

 

        完整的《球球大作战》还包含玩家间的碰撞、球分裂、排行榜等 功能。这些功能不算复杂,写法和“生成食物”“吞下小球很相似,大家有时间可以自行实现。