安卓接入指南
集成依赖
将 moving_library-x.x.x.aar
文件复制到 app 项目的 libs
文件夹下。
然后,在 project 的 gradle 中添加:
buildscript {
dependencies {
// ...
// 添加kotlin插件 sdk使用
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
}
}
在 app 的 gradle 中添加:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
defaultConfig {
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
}
repositories {
// 如果项目类库的libs文件中有项目依赖的aar文件,需要添加此配置后再引入
flatDir {
dirs 'libs'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 引入libs文件夹中的aar资源
implementation(name: 'moving_library-2.0.0', ext: 'aar')
// ...
}
上手使用
初始化
在 Application 中 onCreate
方法中添加初始化和配置代码:
//初始化和配置SDK
//建议在Application 的 onCreate方法中添加
Moving.init(this) //必选!初始化SDK
.setWssConnectUrl(GameDefaultConfig.WSS_CONNECT_URL) //可选 设置WebSocket服务器
.setWssConnectTimeout(15*1000) //可选 设置WebSocket连接超时时间(毫秒)
.setWssConnectionLostTimeout(60) //可选 设置WebSocket心跳间隔时间
.setWssReconnectFrequency(60) //可选 设置WebSocket断开后的重连次数,可以设置的很大,不会有什么性能上的影响
// .setDecodeType(MovingDecodeType.DECODE_SOFT) //可选 设置强制软解硬解
.setShowLog(true); // 可选 设置是否显示日志
主页面逻辑实现
添加监听器
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// 添加监听器
Moving.getInstance().addMovingListener(this);
}
移除监听器
@Override
protected void onDestroy() {
super.onDestroy();
// 移除监听器
Moving.getInstance().removeMovingListener(this);
}
启动SDK
Moving
.getInstance()
.prepare2Start(
new MovingPre2StartParam(startToken)
);
实现监听器回调逻辑
@Override
public void onHandleMovingMessage(MovingListenerCode messageCode, String messageJson) {
switch (messageCode) {
case SDK_MIGRATE_ASK:// 询问迁移
// 提醒 正在游戏中
break;
case SDK_AUTH_SUCCESS:// 鉴权成功
break;
case SDK_IN_THE_QUEUE:// 排队中
// 提醒需要排队
break;
case SDK_QUEUE_CHANGE:// 排队状态改变
// 提醒队列变化实现 排队位置在messageJson中
break;
case SDK_PREPARE_SUCCESS:// 准备成功,可以开始游戏
// 开始游戏按钮设为可用状态
break;
default:
break;
}
}
游戏界面逻辑实现
添加游戏组件
在游戏界面xml布局文件中添加游戏界面组件:
<com.tingyutech.movingsdk.views.MovingGameView android:id="@+id/mMovingGameView"
android:layout_width="match_parent" android:layout_height="match_parent"
app:Moving_inputMode="cursor" app:Moving_isShowDebugInfo="true" />
其中自定义属性参考如下:
app:Moving_isShowDebugInfo
为是否展示调试文本信息,默认不展示app:Moving_inputMode="cursor"
为设置虚拟输入空间,默认不使用虚拟输入组件none
: 不使用触屏模式输入模式cursor
: 使用触屏鼠标模式handle
: 使用触屏手柄模式
继承 MovingGameActivity 并复写抽象方法
提示
完成 UI 初始化部分后,需要主动调用父类的 startGame(startToken);
方法才会开始游戏。
public class GameActivity extends MovingGameActivity {
// 游戏界面组件,需要在getMovingGameView()方法中返回
MovingGameView mMovingGameView;
@Override
protected int getContentLayoutId() {
MyApplication.setGameViewStyle(this); // 设置Activities样式
// 第一步:设置UI布局
return R.layout.activity_custom_game;
}
@Override
protected void initUIViews(Bundle savedInstanceState) {
// 第二步:初始化游戏组件
mMovingGameView = findViewById(R.id.mMovingGameView);
// 测试游戏界面组件能力
findViewById(R.id.mSettingButton).setOnClickListener(v -> showOptionMenuDialog());
// Demo中是从Demo服务器获取开始方法需要的参数 startToken
// 此方法调用之后才会开始游戏,开始游戏时需要传入 startToken
startGame(startToken);
}
@Override
protected MovingGameView getMovingGameView() {
// 第三步:设置游戏组件
return mMovingGameView;
}
@Override
protected void onGameStop() {
EasyToast.getDEFAULT().show("游戏结束,自动关闭游戏页面");
// 如果需要拦截游戏结束后自动关闭页面,可把super的调用删掉即可
super.onGameStop();
}
@Override
protected void getRenewToken(String deadline, @NonNull RenewTokenDeadlineListener renewTokenDeadlineListener) {
// Demo中是从Demo服务器获取开始方法需要的参数 RenewToken
// ...
// 更新RenewToken
renewTokenDeadlineListener.refreshRenewToken(RenewToken);
}
// @Override
// protected boolean onBack2StopGame() {
// // 此处可以返回true来拦截默认的退出游戏事件
// return false;
// }
//
// @Override
// protected boolean onError2StopGame() {
// // 此处可以返回true来拦截默认的退出游戏事件
// return false;
// }
}
游戏界面高级功能使用
动态切换输入组件
// 不使用任何触屏虚拟输入
mMovingGameView.setTouchInputMode(MovingGameView.INPUT_MODE_NONE);
// 使用触摸光标模式
mMovingGameView.setTouchInputMode(MovingGameView.INPUT_MODE_CURSOR);
// 使用虚拟手柄模式
mMovingGameView.setTouchInputMode(MovingGameView.INPUT_MODE_HANDLE);
使用自定义触屏虚拟组件
// 可选,使用自定义虚拟鼠标组件,不设置则使用默认组件
mMovingGameView.setCursorView(new MyCursorView(GameActivity.this));
// 可选,使用自定义虚拟手柄组件,不设置则使用默认组件
mMovingGameView.setHandleView(new MyHandleView(GameActivity.this));
// 自定义组件不支持xml中配置模式,xml中配置的输入组件类型使用的是默认组件样式
// 如果使用自定义组件,设置自定义组件后需要主动刷新一次或者调用动态切换组件的方法setTouchInputMode()
mMovingGameView.refreshTouchInputMode();
清空自定义触屏虚拟组件
清空自定义组件与使用自定义组件类似,需要清空哪个,哪个设置为空即可
// 可选,清空自定义虚拟鼠标组件
mMovingGameView.setCursorView(null);
// 可选,清空自定义虚拟手柄模式
mMovingGameView.setHandleView(null);
// 清空自定义组件后需要主动刷新一次或者调用动态切换组件的方法setTouchInputMode()
mMovingGameView.refreshTouchInputMode();
视频等级修改参数
视频等级修改参数。通过 displayGrade 接口获取
Moving.getInstance().setServiceLevel("需要设置的质量参数");
交互时序图
如下是 SDK 和客户端 APP 的简要交互时序图,请参考该图接入 SDK 业务。
sequenceDiagram
Client->>+SDK: 初始化(传 authToken)
SDK-->>Client: 认证成功
opt 确认迁移
Note over Client,SDK: 当前用户已有会话,需要确认是否连接<br>如果确认,直接开始游戏即可
SDK->>Client: 询问迁移
end
opt 等待排队
Note over Client,SDK: 当前需要排队
SDK->>Client: 提示需要排队
opt 排队位置更新
SDK->>Client: 更新队列位置
end
SDK->>Client: 排队完成
end
deactivate SDK
Note right of Client: 不管是用户已有会话,<br>还是排队完成或者不需要排队,<br>都要手动调用开始游戏。
Client->>+SDK: 开始游戏(传startToken)
SDK->>Client: 进度 20%
SDK->>Client: 进度 30%
SDK->>Client: 进度 60%
SDK->>Client: 进度 95%
SDK->>-Client: 游戏启动成功
loop renewToken
SDK->>+Client: 请求 renew token
Client-->>-SDK: 返回
end
opt 画质切换
Client->>+SDK: 画质切换{grade}
SDK->>-Client: 设置成功
end
opt 手动结束游戏
Client->>SDK: 结束游戏
end
opt 被动结束游戏
SDK->>Client: 游戏被结束事件{code, reason}
end
sequenceDiagram
participant 客户端
participant MovingSdk
客户端->>MovingSdk:Application onCreate()中初始化 init(this)
客户端->>客户端:进入开始界面
Note right of 客户端:开始页面 onCreate中 添加SDK监听器 addMovingListener(this)<BR>实现接口 MovingListener onHandleMovingMessage方法;在此方法中监听MovingSdk的回调事件<BR>onDestroy中 添加SDK监听器 removeMovingListener(this)
Note right of 客户端:获取AuthToken
客户端->>MovingSdk:尝试开始游戏 prepare2Start(new MovingPre2StartParam(AuthToken))
MovingSdk-->客户端: SDK_MIGRATE_ASK 询问迁移
MovingSdk-->客户端: SDK_IN_THE_QUEUE 排队中
MovingSdk-->客户端: DK_QUEUE_CHANGE 排队状态改变
MovingSdk-->客户端: SDK_PREPARE_SUCCESS 准备成功,可以开始游戏
Note left of MovingSdk: 如需更多详细回调,请查看【监听参数说明】相关内容
客户端->>客户端:进入游戏界面
Note right of 客户端:继承 MovingGameActivity 实现抽象方法
MovingSdk-->客户端: getContentLayoutId() 获取layout id
MovingSdk-->客户端: initUIViews() 初始化组件MovingGameView组件
MovingSdk-->客户端: getMovingGameView() 返回初始化的getMovingGameView组件实例
Note right of 客户端:获取StartToken 调用父类 startGame(StartToken)
MovingSdk-->客户端: getRenewToken(String deadline, @NonNull RenewTokenDeadlineListener renewTokenDeadlineListener) 更新RenewToken
Note right of 客户端:如果调用getRenewToken 后10秒还为收到客户端的token 更新(RenewTokenDeadlineListener.refreshRenewToken)<BR>则再次调用getRenewToken<BR>最多循环3次,3次超时后不再调用getRenewToken
客户端->>MovingSdk: 更新RenewToken renewTokenDeadlineListener.refreshRenewToken(RenewToken)