interactive_game_sdk 0.0.4-dev.5 interactive_game_sdk: ^0.0.4-dev.5 copied to clipboard
A new flutter plugin project.
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:interactive_game_sdk/interactive_game_sdk.dart';
import 'package:interactive_game_sdk/events.dart';
import 'package:interactive_game_sdk/interactive_game_player.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
debugShowCheckedModeBanner: false,
home: MyApp(),
);
}
}
class MyApp extends StatefulWidget {
@override
_MyAppStateTest createState() => _MyAppStateTest();
}
class _MyAppStateTest extends State<MyApp> implements OnDialogClickListener {
String _currentUserId;
SWGameClient _gameClient;
SWGamePlayer _gamePlayer1;
SWGamePlayer _gamePlayer2;
bool _isGameLoading1 = false;
bool _isGameLoading2 = false;
bool _isGameError1 = false;
bool _isGameError2 = false;
String _gameLoadingText1 = "loading...";
String _gameLoadingText2 = "loading...";
double _gameRatio1 = 9.0 / 16.0;
double _gameRatio2 = 9.0 / 16.0;
bool _isStop1 = true;
bool _isStop2 = true;
int _delayTime1 = 0;
int _delayTime2 = 0;
int flex = 1;
//保存在线用户ID
List<dynamic> _mUserList = [];
//保存对设备1有操作权限的用户ID
List<dynamic> _padCtrlList1 = [];
//保存对设备2有操作权限的用户ID
List<dynamic> _padCtrlList2 = [];
TextStyle _textStyle = new TextStyle(
fontSize: 10.0,
color: Colors.black,
);
@override
void initState() {
super.initState();
initPlatformState();
String alphabet = '123456789';
int strLength = 5;
//随机当前用户ID
String left = '';
for (var i = 0; i < strLength; i++) {
left = left + alphabet[Random().nextInt(alphabet.length)];
}
_currentUserId = left;
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
_gameClient = SWGameClient();
//SDK初始化
_gameClient.init('请填写appId');
//设置SDK日志开关
_gameClient.debugMode(true);
//添加频道相关回调
_gameClient.setEventHandler(GameClientChannelEventHandler(
//加入频道成功
onJoinChannelSuccess: (channel) {
BotToast.showText(text: '加入频道成功\n channel $channel');
},
//加入频道失败
onJoinChannelFailed: (channel, errorCode, errorMsg) {
BotToast.showText(
text:
'加入频道失败\n channel $channel errorCode $errorCode errorMsg $errorMsg');
},
//设置游戏成功
onSetPlayCloudGameSuccess: (gameId, padCount) {
BotToast.showText(text: '设置游戏成功\n gameId $gameId padCount $padCount');
},
//设置游戏失败
onSetPlayCloudGameFailed: (gameId, padCount, errorCode, errorMsg) {
BotToast.showText(
text:
'设置游戏失败\n gameId $gameId padCount $padCount errorCode $errorCode errorMsg $errorMsg');
},
//websocket消息报错
onErrorNotify: (errorCode, errorMsg) {
BotToast.showText(
text: 'websocket消息报错\n errorCode $errorCode errorMsg $errorMsg');
},
//用户列表更新
onUserListUpdate: (userList) {
print('用户列表\n userList $userList');
_mUserList.clear();
_mUserList.addAll(userList);
setState(() {});
BotToast.showText(text: '用户列表\n userList $userList');
},
//用户操作权限更新
onCtrlPadUpdate: (ctrlPadList) {
setState(() {
for (int i = 0; i < ctrlPadList.length; i++) {
Map<dynamic, dynamic> map = ctrlPadList[i];
//权限更改用户的ID
String userId = map['userId'];
//更改后能操控的设备位置列表
List<dynamic> positionList = map['positionList'];
//移除更改之前的权限
if (_padCtrlList1 != null && _padCtrlList1.contains(userId)) {
_padCtrlList1.remove(userId);
}
if (_padCtrlList2 != null && _padCtrlList2.contains(userId)) {
_padCtrlList2.remove(userId);
}
//添加更改之后的权限(positionlist 有可能为空,为空即为当前用户对所有设备都无操作权限)
if (positionList != null) {
for (int i = 0; i < positionList.length; i++) {
if (positionList[i] == 1) {
_padCtrlList1.add(userId);
} else if (positionList[i] == 2) {
_padCtrlList2.add(userId);
}
}
}
}
});
BotToast.showText(text: '控制权列表\n ctrlPadList $ctrlPadList');
},
//用户加入频道
onUserJoin: (userId) {
if (_currentUserId != userId) {
_mUserList.add(userId);
setState(() {});
}
BotToast.showText(text: '用户加入\n userId $userId');
},
onUserOffline: (userId) {
BotToast.showText(text: '用户离线\n userId $userId');
},
onUserOnline: (userId) {
BotToast.showText(text: '用户上线\n userId $userId');
},
//用户离开频道
onUserLeave: (userId) {
_mUserList.remove(userId);
setState(() {});
BotToast.showText(text: '用户离开\n userId $userId');
},
onKick: (userId) {
BotToast.showText(text: '踢用户\n userId $userId');
},
onBan: (userId) {
BotToast.showText(text: '封禁用户\n userId $userId');
},
//游戏切换通知
onPlayUpdate: (positionList) {
_isGameLoading1 = true;
_gameLoadingText1 = "loading...";
_isGameLoading2 = true;
_gameLoadingText2 = "loading...";
setState(() {});
//游戏切换后 重新加载新游戏
_gamePlayer1.startPlay(positionList[0]);
_gamePlayer2.startPlay(positionList[1]);
BotToast.showText(text: '玩法改变通知位置列表\n positionList $positionList');
},
));
GamePlayerChannelEventHandler _gamePlayerChannelEventHandler =
GamePlayerChannelEventHandler(
onPlayStarted: (gamePlayer, playtime) {
//云游戏开始
if (gamePlayer == _gamePlayer1) {
_isGameLoading1 = false;
_isStop1 = false;
setState(() {});
} else if (gamePlayer == _gamePlayer2) {
_isGameLoading2 = false;
_isStop2 = false;
setState(() {});
}
},
onPlayOrientationChanged: (gamePlayer, portrait) {
//横竖屏改变
},
onPlayNetWorkDelay: (gamePlayer, delayInMS) {
//云游戏延迟
if (_gamePlayer1 == gamePlayer) {
_delayTime1 = delayInMS;
setState(() {});
} else if (_gamePlayer2 == gamePlayer) {
_delayTime2 = delayInMS;
setState(() {});
}
},
onPlayError: (gamePlayer, status, errorFrom, errorCode, errorMsg) {
//云游戏出错
if (gamePlayer == _gamePlayer1) {
_isGameLoading1 = true;
_isGameError1 = true;
_gameLoadingText1 =
"连接失败,点击重试\n onPlayError\n status: $status\n errorFrom: $errorFrom\n errorCode: $errorCode\n errorMsg: $errorMsg";
setState(() {});
} else if (gamePlayer == _gamePlayer2) {
_isGameLoading2 = true;
_isGameError2 = true;
_gameLoadingText2 =
"连接失败,点击重试\n onPlayError\n status: $status\n errorFrom: $errorFrom\n errorCode: $errorCode\n errorMsg: $errorMsg";
setState(() {});
}
},
);
_gamePlayer1 = SWGamePlayer.createPlayerView();
_gamePlayer1.setEventHandler(_gamePlayerChannelEventHandler);
_gamePlayer2 = SWGamePlayer.createPlayerView();
_gamePlayer2.setEventHandler(_gamePlayerChannelEventHandler);
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
}
//设备连接出错,重连方法
Future<void> onTapLeft() {
if (_isGameError1) {
_gamePlayer1.reStart();
_isGameError1 = false;
}
}
Future<void> onTapRight() {
if (_isGameError2) {
_gamePlayer2.reStart();
_isGameError2 = false;
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: BotToastInit(),
//1. call BotToastI navigatorObservers: [BotToastNavigatorObserver()],
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: new Column(
children: [
new Row(children: [
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(3, 3, 1.5, 3),
child: Column(
children: [
AspectRatio(
aspectRatio: _gameRatio1,
child: Stack(children: [
_gamePlayer1.playerView,
Visibility(
child: new GestureDetector(
child: Container(
color: Colors.orange,
child: new Center(
child: new Text(_gameLoadingText1),
),
),
onTap: this.onTapLeft,
),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _isGameLoading1,
)
]),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
),
flex: flex,
),
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(1.5, 3, 3, 3),
child: Column(
children: [
AspectRatio(
aspectRatio: _gameRatio2,
child: Stack(children: [
_gamePlayer2.playerView,
Visibility(
child: new GestureDetector(
child: Container(
color: Colors.orange,
child: new Center(
child: new Text(_gameLoadingText2),
),
),
onTap: this.onTapRight,
),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: _isGameLoading2,
)
]),
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
),
flex: 1,
),
]),
new Row(children: [
Expanded(
child: new Offstage(
offstage: _isStop1,
child: new Row(children: [
Expanded(
child: Center(
child: Container(
child: new OutlineButton(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text(
'${_delayTime1}ms',
style: _textStyle,
),
onPressed: () {},
),
),
),
flex: 1,
),
Expanded(
child: Container(
child: new CtrlButton(
callback: this,
mUserList: _mUserList,
padCtrlList: _padCtrlList1,
padIndex: 1),
),
flex: 1,
),
Expanded(
child: Container(
child: new OutlineButton(
child: Text(
'返回',
),
onPressed: () {
_gamePlayer1.sendBackCommand();
}),
),
flex: 1,
),
]),
),
flex: 1,
),
Expanded(
child: new Offstage(
offstage: _isStop2,
child: new Row(children: [
Expanded(
child: Center(
child: Container(
child: new OutlineButton(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text('${_delayTime2}ms', style: _textStyle),
onPressed: () {},
),
),
),
flex: 1,
),
Expanded(
child: Container(
child: new CtrlButton(
callback: this,
mUserList: _mUserList,
padCtrlList: _padCtrlList2,
padIndex: 2),
),
flex: 1,
),
Expanded(
child: Container(
child: new OutlineButton(
child: Text(
'返回',
),
onPressed: () {
_gamePlayer2.sendBackCommand();
}),
),
flex: 1,
),
]),
),
flex: 1,
),
]),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Center(
child: new OutlineButton(
child: Text('当前用户id: $_currentUserId'),
onPressed: () {
setState(() {
if (flex == 1) {
print('点击了放大按钮');
flex = 2;
_gamePlayer1.refreshFrame(245.5, 436);
_gamePlayer2.refreshFrame(120.5, 214);
} else {
print('点击了缩小按钮');
flex = 1;
_gamePlayer1.refreshFrame(183, 325);
_gamePlayer2.refreshFrame(183, 325);
}
});
},
),
),
flex: 1,
),
Expanded(
child: Center(
child: new OutlineButton(
child: Text('用户列表'),
onPressed: () {
_showUserList();
},
),
),
flex: 1,
),
]),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Center(
child: new OutlineButton(
child: Text('加入频道'),
onPressed: () {
_gameClient.joinChannel(
'请填写频道id', _currentUserId, 'token');
},
),
),
flex: 1,
),
Expanded(
child: Center(
child: new OutlineButton(
child: Text('离开频道'),
onPressed: () {
_gameClient.leaveChannel();
_gamePlayer1.destroy();
_gamePlayer2.destroy();
pop();
},
),
),
flex: 1,
),
]),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Center(
child: new OutlineButton(
child: Text('游戏49'),
onPressed: () {
_gameClient.setPlayCloudGameMulti(49, 2);
},
),
),
flex: 1,
),
Expanded(
child: Center(
child: new OutlineButton(
child: Text('游戏43'),
onPressed: () {
_gameClient.setPlayCloudGameMulti(43, 2);
},
),
),
flex: 1,
),
Expanded(
child: Center(
child: new OutlineButton(
child: Text('点击放大缩小'),
onPressed: () {
setState(() {
if (flex == 1) {
print('点击了放大按钮');
flex = 2;
_gamePlayer1.refreshFrame(245.5, 436);
_gamePlayer2.refreshFrame(120.5, 214);
} else {
print('点击了缩小按钮');
flex = 1;
_gamePlayer1.refreshFrame(183, 325);
_gamePlayer2.refreshFrame(183, 325);
}
});
},
),
),
flex: 1,
),
]),
],
),
),
);
}
//显示用户列表
_showUserList() {
showDialog<Null>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return new AlertDialog(
title: new Text('用户列表'),
content: new SingleChildScrollView(
child: new Container(
width: 160,
height: 320,
child: new ListView.builder(
padding: new EdgeInsets.all(5.0),
itemExtent: 50.0,
itemCount: _mUserList.length,
itemBuilder: (BuildContext context, int index) {
return new Text("${_mUserList[index]}");
},
)),
),
);
});
}
//授予权限
@override
void onGrant(padIndex, userId) {
if (padIndex == 1) {
_gamePlayer1.grantCtrlPadUserId(userId);
} else {
_gamePlayer2.grantCtrlPadUserId(userId);
}
}
//撤回权限
@override
void onRevoke(padIndex, userId) {
if (padIndex == 1) {
_gamePlayer1.revokeCtrlPadUserId(userId);
} else {
_gamePlayer2.revokeCtrlPadUserId(userId);
}
}
static Future<void> pop() async {
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
}
//权限列表操作接口
abstract class OnDialogClickListener {
void onGrant(int padIndex, String userId);
void onRevoke(int padIndex, String userId);
}
class CtrlButton extends StatefulWidget {
final List<dynamic> mUserList;
final List<dynamic> padCtrlList;
final OnDialogClickListener callback;
final int padIndex;
CtrlButton(
{Key key, this.callback, this.mUserList, this.padCtrlList, this.padIndex})
: super(key: key);
@override
State<StatefulWidget> createState() => _CtrlButtonState();
}
class _CtrlButtonState extends State<CtrlButton> {
List<dynamic> mUserList;
List<dynamic> padCtrlList;
OnDialogClickListener callback;
int padIndex;
@override
void initState() {
super.initState();
mUserList = widget.mUserList;
padCtrlList = widget.padCtrlList;
callback = widget.callback;
padIndex = widget.padIndex;
}
//权限列表弹框
_showMyMaterialDialog(BuildContext context) {
showDialog<Null>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return new AlertDialog(
title: new Text('授权列表'),
content: new SingleChildScrollView(
child: new Container(
width: 160,
height: 320,
child: new ListView.builder(
padding: new EdgeInsets.all(5.0),
itemExtent: 50.0,
itemCount: mUserList.length,
itemBuilder: _listItemBuilder1,
)),
),
);
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new OutlineButton(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text(
'授权',
),
onPressed: () {
_showMyMaterialDialog(context);
},
);
}
Widget _listItemBuilder1(BuildContext context, int index) {
if (padCtrlList != null && padCtrlList.contains(mUserList[index])) {
return GestureDetector(
child: Container(
child: Row(
children: <Widget>[
SizedBox(
height: 10.0,
width: 10,
),
Text(
mUserList[index],
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 16.0,
color: Colors.blue,
),
),
Spacer(), // use Spacer
Image.asset("images/permission_able_on.png"),
SizedBox(
height: 10.0,
width: 10,
),
],
),
),
onTap: () {
Navigator.pop(context);
callback.onRevoke(padIndex, mUserList[index]);
},
);
} else {
return GestureDetector(
child: Container(
child: Row(
children: <Widget>[
SizedBox(
height: 10.0,
width: 10,
),
Text(
mUserList[index],
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 16.0,
color: Colors.blue,
),
),
Spacer(), // use Spacer
Image.asset("images/permission_able_off.png"),
SizedBox(
height: 10.0,
width: 10,
),
],
),
),
onTap: () {
Navigator.pop(context);
callback.onGrant(padIndex, mUserList[index]);
},
);
}
}
}