《绝地求生大逃杀》(下称PUBG)这款游戏已经发布一年了,获取了很多赞誉和奖项。然而因为神仙泛滥,让我等原本就夕阳红枪法的玩家成盒几率大大上升。虽然有大牛开发了仿PUBG的练枪游戏,但这些游戏都是单机的,一我的练枪太无聊,想要和小伙伴一块儿练,怎么办呢?html
Unity
开发功底,以及入门级的Java
语法;Import
到 Unity 内;Unity SDK
、GameCloud SDK
;BmobGame_UnitySDK_vx.x.x_xxxxxx.unitypackage
Import 到Unity内;delegate
用于处理各类通知;LocalPlayer
的移动、面向角度、姿态(卧倒/下蹲/持有手枪/持有步枪)等数据,调用SDK接口同步到服务器;LocalPlayer
的瞬时动做(如开火/跳跃/换弹匣、拾取物品等Pose)经过SDK接口直接发送到其它玩家;LocalPlayer
的血量、击杀数、名次,并渲染其它玩家的位置、角度、姿态。获取其它玩家直接发送的瞬时动做,操做Animator;BGS官网
登陆管理后台,建立游戏,修改 服务器运行配置
,包括 每秒帧率
(默认60Hz)、房间最多玩家数
(2个或以上);玩家眷性配置
,设置各个属性的名称、类型、长度、值域、由云端/客户端编辑、其它玩家是否可见等。下方有 PUBG
的玩家眷性例子;Eclipse
或 Android Studio
,建立Java项目,导入 BmobGame_JavaCloud_vx.x.x_xxxxxx.jar
,并建立 Player.java
和 Room.java
,分别继承自 PlayerBase.class
和 RoomBase.class
后,编写游戏逻辑代码。下方有案例;接下来大概介绍一下开发的要点,Demo源码、具体开发流程敬请期待后续教程java
本人Unity不熟络,在拿着一个半成品的Unity FPS项目的状况下,添加3D模型、制做Animation和Animator花费了较多时间,到如今尚未把持有武器状态下的模型和动做结合起来。数据库
可是在基于客户端基本完工的状况下,接入BGS,把它从一个单机游戏变成了多人联网游戏,仅花费1小时。立刻就能够多人开黑啦。后端
超清/720P模式观看体验更好哦安全
能够说除了动做不完善以外,联网射击对战游戏基本上的要素都具有啦服务器
玩家的属性有如下几种类型:网络
类型 | 使用案例 |
---|---|
boolean | 是否无敌状态 |
int | 血量、分数 |
float | 2D游戏的面朝角度 |
double | 吟唱读条进度 |
boolean[] | 各类持续姿态 |
int[] | 物品栏、外观项 |
float[] | 角色位置、3D游戏的面朝角度 |
double[] | 高物理精度游戏的部分参数 |
当属性类型为 int
、 int[]
时,须要指定最大值 max
,以便服务器优化同步效率ide
当属性类型为 xxx[]
时,须要指定数组长度 count
,以便服务器优化同步效率函数
每一个玩家眷性还有 export
、editable
两个开关,默认都为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、一、2 那么knapsack为[1,8,4]意味着这个玩家有 1把枪、8颗子弹、4颗手雷 这个属性之因此Editable为false,是为了防止客户端外挂能够随意编辑生成道具 取而代之的是客户端发送拾取、消耗、丢弃道具的指令到云端代码,经由合法性判断后操做该属性、同步到客户端
Bmob.class
的用法与 Bmob Java云函数 的 modules.oData
彻底一致主要须要开发者实现的有 Room.java
、Player.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 | 房间被建立时 | 将房间的 id 、joinKey 等保存到 Bmob数据库 ,可进行好友对战、匹配对战 |
onGameStart | 全部玩家均已准备,游戏开始时 | 初始化物品数量和位置、安全区的位置 |
onTick | 游戏中,以每秒屡次的频率调用(取决于每秒帧率配置) | 实现安全区、轰炸区等游戏设定 |
onDestroy | 房间被销毁时 | 将房间信息从 Bmob数据库 删除 |
继承自 PlayerBase.class
, 做用有:
如下是类属性 :
名称 | 类型 | 做用 |
---|---|---|
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
, 如客户端上报击中其它玩家,Action
为 Damage
,添加方法
@BmobGameSDKHook public void onAction_Damage(byte[] damage) { // 使用setHp修改被击中玩家的血量,若是<=0,则断定死亡,通知全部用户 }