美文网首页游戏设计&游戏开发Bmob后端云-让移动开发更简单程序员
放大招!!!落地成盒?教你开发自己的联网"吃鸡&quo

放大招!!!落地成盒?教你开发自己的联网"吃鸡&quo

作者: 大王12 | 来源:发表于2018-03-22 15:05 被阅读209次

    《绝地求生大逃杀》(下称PUBG)这款游戏已经发布一年了,获取了不少赞誉和奖项。然而由于神仙泛滥,让我等本来就夕阳红枪法的玩家成盒概率大大上升。虽然有大牛开发了仿PUBG的练枪游戏,但这些游戏都是单机的,一个人练枪太无聊,想要和小伙伴一起练,怎么办呢?


    步骤

    1. 要看懂这篇文章,首先,你得有一定的Unity开发功底,以及入门级的Java语法;
    2. 访问 Unity 的 Asset Store 下载一个射击类游戏项目,并且 Import 到 Unity 内;
    3. 访问 BGS官网,注册账号并下载 Unity SDKGameCloud SDK;
    4. BmobGame_UnitySDK_vx.x.x_xxxxxx.unitypackage Import 到Unity内;
    5. 修改SDK,将游戏开始跳转的 Scene 改为你下载的射击类游戏 Demo Scene;
    6. 在 Demo Scene 进行SDK的初始化,绑定 delegate 用于处理各种通知;
    7. 将本地角色 LocalPlayer 的移动、面向角度、姿态(卧倒/下蹲/持有手枪/持有步枪)等数据,调用SDK接口同步到服务器;
    8. LocalPlayer 的瞬时动作(如开火/跳跃/换弹匣、拾取物品等Pose)通过SDK接口直接发送到其它玩家;
    9. 击中其它玩家时,将事件详情通知到服务器云端代码,包括所用武器、击中身体部位、对方的id;
    10. 读取服务器同步的数据,修改 LocalPlayer 的血量、击杀数、名次,并渲染其它玩家的位置、角度、姿态。获取其它玩家直接发送的瞬时动作,操作Animator;
    11. BGS官网 登录管理后台,创建游戏,修改 服务器运行配置 ,包括 每秒帧率(默认60Hz)、房间最多玩家数 (2个或以上);
    12. 修改 玩家属性配置,设置各个属性的名称、类型、长度、值域、由云端/客户端编辑、其它玩家是否可见等。下方有 PUBG 的玩家属性例子;
    13. 打开 EclipseAndroid Studio,创建Java项目,导入 BmobGame_JavaCloud_vx.x.x_xxxxxx.jar,并创建 Player.javaRoom.java,分别继承自 PlayerBase.classRoomBase.class 后,编写游戏逻辑代码。下方有案例;
    14. 打包运行游戏,就可以多人同时在线对战啦~

    接下来大概介绍一下开发的要点,Demo源码、具体开发流程敬请期待后续教程


    开发体验

    本人Unity不熟络,在拿着一个半成品的Unity FPS项目的情况下,添加3D模型、制作Animation和Animator花费了较多时间,到现在还没有把持有武器状态下的模型和动作结合起来。

    但是在基于客户端基本完工的情况下,接入BGS,把它从一个单机游戏变成了多人联网游戏,仅花费1小时。马上就可以多人开黑啦。


    运行效果

    Demo测试运行视频 (B站无广告传送门)

    超清/720P模式观看体验更好哦

    可以说除了动作不完善之外,联网射击对战游戏基本上的要素都具备啦


    玩家属性配置

    玩家的属性有以下几种类型:

    类型 使用案例
    boolean 是否无敌状态
    int 血量、分数
    float 2D游戏的面朝角度
    double 吟唱读条进度
    boolean[] 各种持续姿态
    int[] 物品栏、外观项
    float[] 角色位置、3D游戏的面朝角度
    double[] 高物理精度游戏的部分参数

    当属性类型为 intint[]时,需要指定最大值 max,以便服务器优化同步效率

    当属性类型为 xxx[] 时,需要指定数组长度 count,以便服务器优化同步效率


    每个玩家属性还有 exporteditable 两个开关,默认都为false,以下是这两个开关的描述:

    Export :

    效果 使用案例
    true 该玩家属性对所有玩家开放 位置、角度、姿态、外观项
    false 该玩家属性仅本玩家可获取 PUBG的血量、击杀数等

    Editable :

    效果 使用案例
    true 该值由客户端进行修改,服务器只读 位置、角度、姿态
    false 该值由服务器进行修改,客户端只读 PUBG的血量、击杀数等

    一个属性不能同时 Export==false 且 Editable==True,因为这种属性往往不需要经过网络


    以下是 PUBG 的推荐玩家属性配置

    名称 类型 最大值/数组长度 Export Editable 描述
    hp int 100 / - false false 血量
    score int 100 / - false false 击杀数
    position float[] - / 3 true true 位置
    rotation float[] - / 3 true true 角度
    surface int[] 255 / 8 true true 外观件
    knapsack int[] 65535 / 255 false false 物品栏
        案例中的 knapsack(背包),设计原理是index为物品id,对应数字为物品个数
        例如游戏中共有3种道具,分别是枪、子弹、手雷,我们定它们的id分别为0、1、2
        那么knapsack为[1,8,4]意味着这个玩家有 1把枪、8颗子弹、4颗手雷
        
        这个属性之所以Editable为false,是为了防止客户端外挂可以随意编辑生成道具
        取而代之的是客户端发送拾取、消耗、丢弃道具的指令到云端代码,经由合法性判断后操作该属性、同步到客户端
    

    云端代码

    • BGS的云端代码可以完美实现游戏的后端逻辑层,并且有热更新机制,可以随时修改、升级
    • 缝合了Bmob数据服务,可以快速进行Bmob数据库的增删查改,其中 Bmob.class 的用法与 Bmob Java云函数modules.oData 完全一致

    主要需要开发者实现的有 Room.javaPlayer.java


    Room.java

    继承自 RoomBase.class , 作用是管理、监控房间的生命周期

    以下是类属性

    名称 类型 作用
    roomId int 房间id,创建房间时产生,客户端SDK加入房间时需要携带
    players Player.class[] 该房间内所有玩家
    playerCount int 该房间内玩家数
    masterId String 创建房间的玩家id
    masterKey String 销毁/踢出玩家需要携带的key
    joinKey String 加入房间需要携带的key
    isPlaying boolean 该房间是在游戏中还是等待中
    startTime long 该房间的游戏开始时间毫秒数

    以下是可主动调用的方法

    方法名 参数 返回值 作用
    dispatchGameOver - - 让房间游戏结束
    sendToAll byte[] boolean 向所有玩家推送消息
    sendToAllExcept byte[],Player boolean 向某玩家以外的所有玩家推送消息

    以下是需要Override的生命周期相关监听方法

    这些方法都没有参数,返回值均为void

    方法名 调用时机 使用案例
    onCreate 房间被创建时 将房间的 idjoinKey等保存到 Bmob数据库,可进行好友对战、匹配对战
    onGameStart 所有玩家均已准备,游戏开始时 初始化物品数量和位置、安全区的位置
    onTick 游戏中,以每秒多次的频率调用(取决于每秒帧率配置) 实现安全区、轰炸区等游戏设定
    onDestroy 房间被销毁时 将房间信息从 Bmob数据库 删除

    Player.java

    继承自 PlayerBase.class , 作用有:

    1. 管理、监控玩家的行为和生命周期
    2. 修改玩家属性值(editable==false的属性)
    3. 监听玩家属性值变动(editable==true的属性)

    以下是类属性

    名称 类型 作用
    room Room 房间对象
    no int 玩家在该房间的id,加入房间时分配
    roommates Player.class[] 该房间内所有玩家,可以用roommates[no]进行索引

    以下是可主动调用的方法

    方法名 参数 返回值 作用
    syncToClient - void 修改参数结束后,将修改同步到客户端
    getStatus - int 获取玩家状态,有无人/等待/准备/游戏中/被淘汰/掉线
    getUserId - String 加入房间时传入的用户id
    send byte[] boolean 向本玩家推送消息
    sendToAll byte[] boolean 向该房间的所有玩家推送消息
    sendToOthers byte[] boolean 向本玩家以外的所有玩家推送消息
    kick - boolean 将本玩家踢出房间

    以下是需要Override的生命周期相关监听方法

    这些方法都没有参数,返回值均为void

    方法名 调用时机 使用案例
    onJoin 玩家加入房间时 操作Bmob数据库
    onLeave 玩家主动退出房间时 操作Bmob数据库
    onReady 玩家在房间内准备时 -
    onUnready 玩家取消准备 -
    onGameStart 本轮游戏开始 初始化玩家属性
    onTick 游戏开始后以一定频率被调用 更新安全区位置和半径、发送通知
    onGameOver 游戏结束 保存游戏记录到Bmob数据库
    onOffline 玩家掉线 可通知其它玩家
    onReconn 玩家重连 更新一些自定义数据到本玩家,并通知其它玩家
    onKicked 玩家被踢出房间 -

    Player.java 允许自定义 获取属性方法、修改属性方法、监听属性方法

    例如,如果云端代码需要修改玩家的hp属性,需要在 Player.java 添加方法:

    @BmobGameSDKHook
    public native void setHp(int hp);
    

    如果需要获取玩家的position属性,添加方法:

    @BmobGameSDKHook
    public native float[] getPosition();
    

    需要监听玩家的position属性变动,添加方法:

    @BmobGameSDKHook
    strictfp void onUpdate_Position() {
        // TODO 与当前安全区进行计算,是否扣除玩家血量
    }
    

    需要处理客户端的 Action, 如客户端上报击中其它玩家,ActionDamage,添加方法

    @BmobGameSDKHook
    public void onAction_Damage(byte[] damage) {
        // 使用setHp修改被击中玩家的血量,如果<=0,则判定死亡,通知所有用户
    }
    

    内测中,感兴趣加官方群:726133616

    其他教程:

    Unity联网对战游戏小Demo
    如何实现各种游戏的思路杂想

    相关文章

      网友评论

      • justcrowl:很棒啊,期待后续的介绍。
        大王12:@justcrowl :+1: 可以加Q群深入了解:634442818

      本文标题:放大招!!!落地成盒?教你开发自己的联网"吃鸡&quo

      本文链接:https://www.haomeiwen.com/subject/igeaqftx.html