subGame.nvue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170
  1. <template>
  2. <view>
  3. <!-- :src="url" src = 'http://192.168.0.112:7456/build/index.html' :src="LocationGameUrl" -->
  4. <!-- @receivedtitle="onReceivedTitle" @pagefinish="onPageFinish"-->
  5. <view class="web-view">
  6. <web-view class="web-view-child" :src="url" ref="webview" @pagestart="onPageStart"
  7. @onPostMessage="handlePostMessage" @error="onError"></web-view>
  8. </view>
  9. <view class="web-back" @click="navBack">
  10. <image style="width: 40rpx;height: 40rpx;" src="/static/gameCloseW.png"></image>
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. import reqUtil from "@/util/util-js/requstUtil.js";
  16. import config from "@/common/config.js";
  17. import fruit from "@/components/fruitMachine/fruit.js"
  18. // import AccAndOri from "@/util/util-js/AccAndOri.js"
  19. import puchConfig from "@/util/util-js/puchConfig.js"
  20. import EquipmentAction from "@/util/util-js/EquipmentAction.js"
  21. import ActionJump from "@/util/util-js/action/jump-0.2.js"
  22. var currentWebview;
  23. var orientId = null,
  24. accId = null;
  25. import {
  26. mapState,
  27. mapMutations
  28. } from 'vuex';
  29. export default {
  30. computed: mapState([
  31. 'avatarUrl', 'gender', 'userName', 'city', 'BLEConnectDevice', 'instructionState',
  32. 'currentInstruction',
  33. 'cIndex', 'globalAcc', 'globalOri', 'LocationGameUrl',
  34. 'ConnectBindingDevice',
  35. 'currentModeIndex'
  36. ]),
  37. data() {
  38. return {
  39. url: '',
  40. pagefinish: '',
  41. error: '',
  42. PageStart: false, // 记录网页请求的加载状态,true 加载成功 false 加载失败
  43. gameQuitListener: false, //游戏是否初始化退出监听
  44. xA: 0,
  45. yA: 0,
  46. zA: 0,
  47. oldxA: 0,
  48. oldzA: 0,
  49. bUpdateOnce: false,
  50. bDelayOnce: false,
  51. mass: puchConfig.BOXING_MASS,
  52. //X轴的变化数组值
  53. xAccArray: [],
  54. xMax: 0,
  55. maxTimeoutId: null,
  56. bMaxPause: false,
  57. xMin: 0,
  58. minTimeoutId: null,
  59. bMinPause: false,
  60. bCalculation: false,
  61. calTimeout: null,
  62. //角度比 z/x
  63. angleRatio: 1, //
  64. //当前选择的item
  65. decodeItem: null,
  66. //拳击数据判断对象
  67. EquipmentActionObj: null,
  68. BLENum: 0,
  69. BLEACX: 0,
  70. BLEACYL: 0,
  71. //是否是游戏里面开启的监听,如果是的话,退出游戏界面时候需要关闭相应的监听,如加速计和陀螺仪
  72. bGameOpenListen: false,
  73. //手机陀螺仪和加速计android模块
  74. bMyAttitudeListen: false,
  75. /**
  76. * 跳绳相应数据
  77. */
  78. //跳绳数据判断对象
  79. actionJumpObj: null,
  80. BLEAccIndex: 0
  81. }
  82. },
  83. onLoad() {
  84. let _self = this;
  85. var pages = getCurrentPages();
  86. var page = pages[pages.length - 1];
  87. currentWebview = page.$getAppWebview();
  88. //监听一次调用setOnceGameOption
  89. console.log("子组件初始化");
  90. uni.$once("setOnceGameOption", (option) => {
  91. console.log("setOnceGameOption=", option);
  92. if (option && option.item) {
  93. this.decodeItem = JSON.parse(decodeURIComponent(option.item));
  94. this.url = this.decodeItem.gameWebUrl;
  95. let temp = {
  96. fObjectId: this.decodeItem.gameId,
  97. recentlyType: 0
  98. }
  99. // console.log("game temp:", config.URL.RECENTLYPLAYINGADD);
  100. //添加最近在玩的游戏
  101. reqUtil.requestData(config.URL.RECENTLYPLAYINGADD, temp).then(res => {
  102. console.log('RECENTLYPLAYINGADD =====', res);
  103. if (res.code == 0) {}
  104. },
  105. e => {
  106. console.log(e)
  107. });
  108. }
  109. });
  110. //子窗体onload 后获取父窗体的onload数据
  111. uni.$emit("game-load");
  112. uni.getCurrentSubNVue().addEventListener("hide", function() {
  113. console.log("subNVue子窗体已隐藏!");
  114. //通知游戏,页面退出
  115. _self.sendMessage("onSubHide", {
  116. msg: '退出页面'
  117. });
  118. uni.$off('updateBLEDeviceData', _self.BLECallback);
  119. //json
  120. uni.$off('updateBLEDeviceJson', _self.BLEJsonCallback);
  121. //去掉监听
  122. if (_self.bMyAttitudeListen) {
  123. _self.gStopSimulateBLEUpdate();
  124. }
  125. // console.log(_self.BLEConnectDevice);
  126. //如果连接了蓝牙设备是手柄
  127. if (_self.BLEConnectDevice && _self.BLEConnectDevice.deviceType == "BLEHandle") {
  128. //开启设备回调 3/4关闭
  129. _self.onWriteBLEConnectionValue({
  130. value: "4"
  131. });
  132. //关闭json 回调
  133. _self.onWriteBLEConnectionValue({
  134. value: "6"
  135. });
  136. uni.$off('updateBLEDeviceData', _self.gWatchBLEUpdate);
  137. } //关闭跳绳模式指令
  138. else if (_self.BLEConnectDevice && _self.BLEConnectDevice.deviceType == "BLERope") {
  139. console.warn("还没设置关闭跳绳模式")
  140. _self.B_CloseRopeSkipping();
  141. uni.$off('updateBLEDeviceData', _self.gWatchBLEUpdate);
  142. }
  143. uni.$emit("game-unload", {
  144. globalAcc: _self.globalAcc,
  145. globalOri: _self.globalOri,
  146. bGameOpenListen: _self.bGameOpenListen
  147. });
  148. });
  149. //*****注释蓝牙操作******
  150. // 监听事件
  151. // uni.$on('callbackCloseBLE', this.callbackCloseBLE);
  152. // uni.$on('callbackBLEState', this.callbackBLEState);
  153. // uni.$on('updateBLEDeviceData', this.BLECallback);
  154. //监听物理返回按钮
  155. plus.key.addEventListener('backbutton', () => {
  156. this.navBack();
  157. }, false);
  158. //设置store状态
  159. _self.$store.state.bGamePlaying = true;
  160. },
  161. onUnload() {
  162. this.$store.state.bGamePlaying = false;
  163. console.log("subNVue子窗体 onUnload!");
  164. //*****注释蓝牙操作******
  165. // uni.$off('callbackCloseBLE', this.callbackCloseBLE);
  166. // uni.$off('callbackBLEState', this.callbackBLEState);
  167. //取消相应的绑定事件
  168. uni.$off('watchAcceleration', this.gWatchAcceleration);
  169. uni.$off("watchAcceleration", this.gWatchBoxingAcc);
  170. uni.$off("watchAcceleration", this.gWatchHitBoxingAcc);
  171. uni.$off('watchOrientation', this.gWatchOrientation);
  172. uni.$emit("game-unload");
  173. },
  174. methods: {
  175. ...mapMutations(['addlocalCalorie', 'syncRequestEvent', 'onWriteBLEConnectionValue',
  176. 'gCreateFilterObj', 'gUpdateFilter', 'B_OpenRopeSkipping', 'B_CloseRopeSkipping',
  177. 'gStopSimulateBLEUpdate', 'gStartSimulateBLEUpdate', 'gUpdateSandbagAlgorithm',
  178. 'gCreateSandbagAlgorithm', 'onConvertDeviceData'
  179. ]),
  180. navBack() {
  181. this.sendMessage("onQuit", {
  182. type: "right-button",
  183. msg: '点击右上角按钮退出游戏'
  184. });
  185. uni.showModal({
  186. title: '提示',
  187. content: '是否退出游戏?',
  188. success: (res) => {
  189. //如果游戏需要监听退出,则需要走完游戏端流程,才能退出,否则直接退出
  190. if (this.gameQuitListener) {
  191. this.sendMessage("onQuitModal", {
  192. data: res,
  193. msg: '退出提示'
  194. });
  195. } else {
  196. if (res.confirm) {
  197. uni.getCurrentSubNVue().hide('auto');
  198. }
  199. }
  200. }
  201. })
  202. },
  203. //蓝牙断开连接时候
  204. callbackCloseBLE() {
  205. this.sendMessage("onDeviceClose", {
  206. msg: '设备断开连接。'
  207. });
  208. },
  209. //蓝牙状态回调
  210. callbackBLEState(res) {
  211. // console.log("game callbackBLEState==", res);
  212. // 暂时只返回数据连接错误信息
  213. // uni.$emit("callbackBLEState", {
  214. // state: -1,
  215. // msg: "设备数据错误"
  216. // });
  217. this.sendMessage("onDeviceState", res)
  218. },
  219. BLECallback(data) {
  220. let dataType = 'Box';
  221. // if (data.hasOwnProperty("ax")) {
  222. // dataType = "Accelerometer"
  223. // }else if(data.hasOwnProperty("gx")){
  224. // dataType = "Gyroscope"
  225. // }
  226. // 设备回调后面用这个接口
  227. let BLEState = {
  228. device: this.BLEConnectDevice, //连接的蓝牙设备
  229. instructionState: this.instructionState, //开启的指令状态
  230. currentInstruction: this.currentInstruction, //当前发送的指令记录
  231. dataType: dataType, //回调的数据类型
  232. data: data //蓝牙回调的数据
  233. }
  234. this.sendMessage("onDeviceUpdateData", BLEState);
  235. },
  236. BLEJsonCallback(data) {
  237. let dataType = 'Json';
  238. // 设备回调后面用这个接口
  239. let BLEState = {
  240. device: this.BLEConnectDevice, //连接的蓝牙设备
  241. instructionState: this.instructionState, //开启的指令状态
  242. currentInstruction: this.currentInstruction, //当前发送的指令记录
  243. dataType: dataType, //回调的数据类型
  244. data: data //蓝牙回调的数据
  245. }
  246. this.sendMessage("onDeviceUpdateJson", BLEState);
  247. },
  248. /**
  249. * 图片转化base64
  250. * @param {Object} url
  251. * @param {Object} callback
  252. */
  253. urlToBase64(url, callback) {
  254. let toBase64Url;
  255. uni.request({
  256. url: url,
  257. method: 'GET',
  258. responseType: 'arraybuffer',
  259. success: async res => {
  260. let base64 = uni.arrayBufferToBase64(res.data);
  261. toBase64Url = 'data:image/jpeg;base64,' + base64;
  262. if (callback)
  263. callback(toBase64Url, res.data);
  264. }
  265. })
  266. },
  267. /**
  268. * 初始化发送数据给游戏
  269. */
  270. sendGameInit() {
  271. this.urlToBase64(this.avatarUrl, (toBase64Url) => {
  272. let device = null;
  273. /**
  274. * 卡路里消耗参数
  275. */
  276. let calorieParams = null;
  277. if (this.BLEConnectDevice) {
  278. // device = {
  279. // cname: this.BLEConnectDevice.cname,
  280. // ename: this.BLEConnectDevice.ename,
  281. // name: this.BLEConnectDevice.name
  282. // };
  283. // calorieParams = {
  284. // runUnit: 0.55, // 比跳的稍微大一点
  285. // jumpUnit: 0.5 // 跳的次数 * 0.5
  286. // };
  287. device = {
  288. cname: this.BLEConnectDevice.cname,
  289. ename: this.BLEConnectDevice.ename,
  290. name: this.BLEConnectDevice.name
  291. };
  292. calorieParams = {
  293. hitUnit: puchConfig.getBoxingCalorie(1)
  294. };
  295. } else if (this.ConnectBindingDevice) {
  296. device = {
  297. cname: this.ConnectBindingDevice.cname,
  298. ename: this.ConnectBindingDevice.ename,
  299. name: this.ConnectBindingDevice.name
  300. };
  301. calorieParams = {
  302. hitUnit: puchConfig.getBoxingCalorie(1)
  303. };
  304. }
  305. //到时候可能要区分是什么类型
  306. let item = {
  307. id: this.decodeItem.gameId,
  308. name: this.decodeItem.gameName
  309. };
  310. // console.log(this.BLEConnectDevice, device);
  311. let gameData = {
  312. avatarUrl: this.avatarUrl,
  313. avatarBase64Url: toBase64Url,
  314. userName: this.userName,
  315. gender: this.gender,
  316. caloriUnit: 10,
  317. calorieParams: calorieParams,
  318. //蓝牙连接的设备
  319. device: device,
  320. item: item
  321. }
  322. this.sendMessage("onGameInit", gameData);
  323. // console.log("onGameInit =", gameData);
  324. })
  325. },
  326. /**
  327. * 统一发送信息
  328. * @param {Object} gameData
  329. */
  330. sendMessage(functionName, gameData) {
  331. let data = {
  332. "funName": functionName,
  333. "gameData": gameData
  334. }
  335. if (!this.PageStart) {
  336. console.warn("页面未初始化不能传消息", data);
  337. return;
  338. }
  339. let initStr = JSON.stringify(data);
  340. this.$refs.webview.evalJs("onWebViewMessage(" + initStr + ")");
  341. },
  342. sendMessageToWebview() {
  343. if (!this.PageStart) {
  344. uni.showModal({
  345. title: "暴躁的提示",
  346. content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
  347. })
  348. return false;
  349. }
  350. /**
  351. * 下面的 jsfunction 代码你要自己在你的网页里面写一个方法 大致如下
  352. * 下面就是你基本的html知识了,我就不想说什么了,自己学。
  353. window.jsfunction = function(data){
  354. console.log('data', data);
  355. }
  356. */
  357. this.sendMessage("onDeviceUpdateData", {
  358. H: 1
  359. });
  360. },
  361. handlePostMessage: function(postData) {
  362. console.log("handlePostMessage得到参数", postData.detail);
  363. let temp = postData.detail.data[0];
  364. let gameData = temp.gameData;
  365. if (temp.funName == "uploadInfo") {
  366. //TODO:写入排行榜分数,后面需要在游戏完结里面调用
  367. //TODO: 后面游戏时间,卡路里的需要写入数据库,目前只是处理了分数
  368. // let num = Math.round(Math.random() * 10000);
  369. //1. gameScore 处理上传的分数
  370. // let _temp = {
  371. // gameId: '1595755153789139696',
  372. // score: 1230,
  373. // cityCode: '110101',
  374. // };
  375. //2. calorieBurned 处理卡路里
  376. // 记录卡路里到本地
  377. this.addlocalCalorie(gameData.calorieBurned);
  378. console.log("gameData.calorieBurned", gameData.calorieBurned);
  379. //然后更新上服务器
  380. this.syncRequestEvent({
  381. success: () => {
  382. // uni.$emit('updateArcbarData', '');
  383. let _temp = {
  384. //假如排行id 为空,排行榜就是游戏自己的id
  385. gameId: this.decodeItem.gameRankingId == null ? this.decodeItem
  386. .gameId : this.decodeItem.gameRankingId,
  387. score: gameData.gameScore,
  388. cityCode: this.city.cityCode,
  389. bMaxLimit: true
  390. }
  391. console.log('_temp =====', _temp);
  392. reqUtil.requestData(config.URL.UPLOADRANKING, _temp, "POST").then(res => {
  393. console.log('UPLOADRANKING =====', res);
  394. if (res.code == 0) {
  395. //TODO 后续游戏数据处理
  396. this.sendMessage("onUploadInfo", {
  397. code: 0,
  398. msg: '上传成功'
  399. });
  400. } else {
  401. //TODO 后续游戏数据处理
  402. this.sendMessage("onUploadInfo", {
  403. code: 400,
  404. msg: '上传失败'
  405. });
  406. }
  407. },
  408. e => {
  409. console.log(e)
  410. });
  411. },
  412. fail: () => {
  413. this.sendMessage("onUploadInfo", {
  414. code: 400,
  415. msg: '上传失败'
  416. });
  417. }
  418. });
  419. //3. gameTime 游戏时间
  420. //TODO 后面处理游戏时长
  421. } else if (temp.funName == "gameInit") {
  422. // 获取游戏信息
  423. this.sendGameInit();
  424. } else if (temp.funName == "aiRandomInfo") {
  425. // 获取aiRandomInfo
  426. reqUtil.requestData(config.URL.AIRANDOMINFO, {}).then(res => {
  427. console.log('AIRANDOMINFO =====', res);
  428. if (res.code == 0) {
  429. let data = res.data;
  430. this.urlToBase64(data.aiAvatar, (toBase64Url) => {
  431. let sendData = {
  432. aiId: data.aiId,
  433. aiName: data.aiName,
  434. aiGender: data.aiGender,
  435. aiType: data.aiType,
  436. aiAvatarBase64Url: toBase64Url
  437. }
  438. this.sendMessage("onAiRandomInfo", sendData);
  439. })
  440. }
  441. },
  442. e => {
  443. console.log(e)
  444. });
  445. } else if (temp.funName == "fruitInfo") {
  446. let fruitIndexArray = [0, 0, 0];
  447. if (gameData.hasOwnProperty("calorie")) {
  448. fruitIndexArray = fruit.getFruitIndex(gameData.calorie);
  449. }
  450. this.urlToBase64("https://bbeng-bucket.oss-cn-beijing.aliyuncs.com/cocos/fruitMachine.png", (
  451. toBase64Url) => {
  452. this.sendMessage("onFruitInfo", {
  453. // 水果雪碧图
  454. fruitBase64Url: toBase64Url,
  455. // 雪碧图 单张图片宽高
  456. unitWidth: 100,
  457. unitHeight: 100,
  458. unit: "px",
  459. imageStartPosY: 0,
  460. imageEndPosY: -1200,
  461. fruitIndexArray: fruitIndexArray
  462. });
  463. })
  464. } else if (temp.funName == "urlToBase64") {
  465. if (gameData.url) {
  466. this.urlToBase64(gameData.url, (toBase64Url) => {
  467. this.sendMessage("onUrlToBase64", {
  468. base64: toBase64Url,
  469. });
  470. })
  471. } else {
  472. this.sendMessage("onUrlToBase64", {
  473. base64: {},
  474. });
  475. }
  476. } else if (temp.funName == "openAccelerometer") {
  477. //打开加速计s
  478. // if (this.globalGameAcc) {
  479. // uni.$on('watchAcceleration', this.gWatchAcceleration);
  480. // } else {
  481. // AccAndOri.bindAcc((accId) => {
  482. // this.$store.state.globalGameAcc = accId;
  483. // console.log("开启的:globalGameAcc=",this.globalGameAcc);
  484. // uni.$on('watchAcceleration', this.gWatchAcceleration);
  485. // });
  486. // }
  487. if (this.globalAcc) {
  488. uni.$on('watchAcceleration', this.gWatchAcceleration);
  489. } else {
  490. uni.$emit("bindAcc", {
  491. callback: (accId) => {
  492. console.log("开启的:globalAcc=", accId);
  493. this.bGameOpenListen = true;
  494. this.$store.state.globalAcc = accId;
  495. uni.$on('watchAcceleration', this.gWatchAcceleration);
  496. }
  497. });
  498. }
  499. } else if (temp.funName == "closeAccelerometer") {
  500. uni.$off('watchAcceleration', this.gWatchAcceleration);
  501. uni.$emit("unBindAcc", this.globalAcc);
  502. this.$store.state.globalAcc = null;
  503. } else if (temp.funName == "openOrientation") {
  504. //打开陀螺仪
  505. if (this.globalOri) {
  506. uni.$on('watchOrientation', this.gWatchOrientation);
  507. } else {
  508. // AccAndOri.bindOri((oriId) => {
  509. // this.$store.state.globalOri = oriId;
  510. // uni.$on('watchOrientation', this.gWatchOrientation);
  511. // });
  512. uni.$emit("bindOri", {
  513. callback: (oriId) => {
  514. console.log("开启的:globalOri=", oriId);
  515. this.bGameOpenListen = true;
  516. this.$store.state.globalOri = oriId;
  517. uni.$on('watchOrientation', this.gWatchOrientation);
  518. }
  519. });
  520. }
  521. } else if (temp.funName == "closeOrientation") {
  522. // uni.$off('watchOrientation', this.gWatchOrientation);
  523. uni.$off('watchOrientation', this.gWatchOrientation);
  524. uni.$emit("unBindOri", this.globalOri);
  525. this.$store.state.globalOri = null;
  526. } else if (temp.funName == "bindBoxingPost") {
  527. if (this.globalAcc) {
  528. uni.$on('watchAcceleration', this.gWatchBoxingAcc);
  529. } else {
  530. uni.$emit("bindAcc", {
  531. callback: (accId) => {
  532. console.log("bindBoxingPost开启的:globalAcc=", accId);
  533. this.bGameOpenListen = true;
  534. this.$store.state.globalAcc = accId;
  535. uni.$on('watchAcceleration', this.gWatchBoxingAcc);
  536. }
  537. });
  538. }
  539. } else if (temp.funName == "unbindBoxingPost") {
  540. uni.$off('watchAcceleration', this.gWatchBoxingAcc);
  541. uni.$emit("unBindAcc", this.globalAcc);
  542. this.$store.state.globalAcc = null;
  543. } else if (temp.funName == "setAngleRatio") {
  544. if (gameData) {
  545. this.angleRatio = Number(gameData.angleRatio);
  546. console.log("this.angleRatio:", this.angleRatio);
  547. this.sendMessage("onSetAngleRatio", {
  548. angleRatio: this.angleRatio
  549. });
  550. }
  551. } else if (temp.funName == "bindHitBoxingPost") {
  552. console.log("bindHitBoxingPost");
  553. if (this.ConnectBindingDevice) {
  554. uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
  555. //hotman 沙袋情景
  556. this.gCreateSandbagAlgorithm();
  557. this.gStartSimulateBLEUpdate();
  558. return;
  559. }
  560. if (!this.BLEConnectDevice) return;
  561. //用设备来区分,开启什么加速计;
  562. if (this.BLEConnectDevice.deviceType == "BLEHandle") {
  563. //处理蓝牙设备情况下
  564. //开启设备回调 3/4关闭
  565. this.onWriteBLEConnectionValue({
  566. value: "3"
  567. });
  568. setTimeout(() => {
  569. //设置加速计b:20ms a:10ms
  570. this.onWriteBLEConnectionValue({
  571. value: config.refreshRate
  572. });
  573. }, 2000)
  574. uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
  575. if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode ==
  576. "general") {
  577. //手机情景或者自由模式
  578. this._createEquipmentBasedOnBoxingPostHit();
  579. } else if (this.BLEConnectDevice.usageMode == "hotman") {
  580. //hotman 沙袋情景
  581. this.gCreateFilterObj();
  582. }
  583. } else if (this.BLEConnectDevice.deviceType == "mySelf") {
  584. //处理手机本身情况下
  585. if (this.globalAcc) {
  586. uni.$on('watchAcceleration', this.gWatchHitBoxingAcc);
  587. } else {
  588. //开启手机加速计
  589. uni.$emit("bindAcc", {
  590. callback: (accId) => {
  591. console.log("bindHitBoxingPost开启的:globalAcc=", accId);
  592. this.bGameOpenListen = true;
  593. this.$store.state.globalAcc = accId;
  594. uni.$on('watchAcceleration', this.gWatchHitBoxingAcc);
  595. if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice
  596. .usageMode == "general") {
  597. //手机情景或者自由模式
  598. this._createEquipmentBasedOnBoxingPostHit();
  599. } else if (this.BLEConnectDevice.usageMode == "hotman") {
  600. //hotman 沙袋情景 todo
  601. console.warn("没有处理手机加速计的 gCreateFilterObj");
  602. // this.gCreateFilterObj();
  603. }
  604. }
  605. });
  606. }
  607. } else if (this.BLEConnectDevice.deviceType == "BLERope") {
  608. //todo 开启跳绳模式
  609. this.B_OpenRopeSkipping();
  610. this._createActionJumpOnBoxingPostHit();
  611. //监听蓝牙回调
  612. uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
  613. }
  614. } else if (temp.funName == "unbindHitBoxingPost") {
  615. if (this.ConnectBindingDevice) {
  616. uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
  617. this.gStopSimulateBLEUpdate();
  618. return;
  619. }
  620. if (this.BLEConnectDevice && this.BLEConnectDevice.deviceType == "BLEHandle") {
  621. //开启设备回调 3/4关闭
  622. this.onWriteBLEConnectionValue({
  623. value: "4"
  624. });
  625. uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
  626. } else if (this.BLEConnectDevice && this.BLEConnectDevice.deviceType == "BLERope") {
  627. console.warn("unbindHitBoxingPost 还没设置关闭跳绳模式")
  628. this.onClearData();
  629. this.B_CloseRopeSkipping();
  630. uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
  631. } else {
  632. uni.$off('watchAcceleration', this.gWatchHitBoxingAcc);
  633. uni.$emit("unBindAcc", this.globalAcc);
  634. this.$store.state.globalAcc = null;
  635. }
  636. } else if (temp.funName == "closeGame") {
  637. uni.getCurrentSubNVue().hide('auto');
  638. } else if (temp.funName == "addQuitModal") {
  639. this.gameQuitListener = true;
  640. this.sendMessage("onQuitModalListener", {
  641. bListener: this.gameQuitListener
  642. });
  643. } else if (temp.funName == "removeQuitModal") {
  644. this.gameQuitListener = false;
  645. this.sendMessage("onQuitModalListener", {
  646. bListener: this.gameQuitListener
  647. });
  648. } else if (temp.funName == "writeBLEConnectionValue") {
  649. if (!gameData.value || gameData.value == "") return;
  650. if (!this.BLEConnectDevice) return;
  651. //蓝牙写入数据
  652. this.onWriteBLEConnectionValue(gameData);
  653. } else if (temp.funName == "log") {
  654. console.log(gameData);
  655. } else if (temp.funName == "addDeviceUpdateListener") {
  656. uni.$on('updateBLEDeviceData', this.BLECallback);
  657. } else if (temp.funName == "closeDeviceUpdateListener") {
  658. uni.$off('updateBLEDeviceData', this.BLECallback);
  659. } else if (temp.funName == "addDeviceJsonUpdateListener") {
  660. uni.$on('updateBLEDeviceJson', this.BLEJsonCallback);
  661. } else if (temp.funName == "closeDeviceJsonUpdateListener") {
  662. uni.$off('updateBLEDeviceJson', this.BLEJsonCallback);
  663. }
  664. //获取手机原始陀螺仪和加速计数据
  665. else if (temp.funName == "onStartAccAndGyro") {
  666. this.bMyAttitudeListen = true;
  667. this.gStartSimulateBLEUpdate();
  668. //监听蓝牙回调
  669. uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
  670. } else if (temp.funName == "onStopAccAndGyro") {
  671. this.bMyAttitudeListen = false;
  672. this.gStopSimulateBLEUpdate();
  673. //监听蓝牙回调
  674. uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
  675. }
  676. },
  677. onPageStart: function(e) {
  678. // 监听页面加载成功
  679. this.PageStart = true;
  680. console.log("onPageStart==", e);
  681. setTimeout(() => {
  682. //加载成功后,显示
  683. uni.getCurrentSubNVue().show('fade-in', 250, () => {});
  684. }, 100)
  685. },
  686. onPageFinish: function(e) {
  687. console.log("onPageFinish==", e);
  688. },
  689. onError: function(e) {
  690. // 监听页面加载错误
  691. // this.error = this.url;
  692. console.error(e);
  693. },
  694. gWatchAcceleration: function(a) {
  695. this.sendMessage("onWatchAccelerometer", a);
  696. return;
  697. if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
  698. this.sendMessage("onWatchAccelerometer", a);
  699. } else if (this.BLEConnectDevice && this.cIndex != -1) {
  700. this.sendMessage("onWatchAccelerometer", a);
  701. }
  702. },
  703. gWatchOrientation: function(o) {
  704. this.sendMessage("onWatchOrientation", o);
  705. return;
  706. if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
  707. this.sendMessage("onWatchOrientation", o);
  708. } else if (this.BLEConnectDevice && this.cIndex != -1) {
  709. this.sendMessage("onWatchOrientation", o);
  710. }
  711. },
  712. //监听返回计算好的puch
  713. gWatchBoxingAcc: function(a) {
  714. if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
  715. //计算返回 puch leftPunch rightPunch
  716. this.updateHitData(a);
  717. } else if (this.BLEConnectDevice && this.cIndex != -1) {
  718. this.updateHitData(a);
  719. }
  720. },
  721. //只返回一个hit状态
  722. gWatchHitBoxingAcc: function(a) {
  723. if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
  724. //计算返回 puch leftPunch rightPunch
  725. this.EquipmentActionObj.updateAcc({
  726. xA: a.xAxis,
  727. zA: a.yAxis,
  728. yA: a.zAxis
  729. })
  730. } else if (this.cIndex != -1 && this.BLEConnectDevice != null) {
  731. if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
  732. this.EquipmentActionObj.updateAcc({
  733. xA: a.xAxis,
  734. zA: a.yAxis,
  735. yA: a.zAxis,
  736. bLimitRebound: false
  737. })
  738. } else if (this.BLEConnectDevice.usageMode == "hotman") {
  739. //hotman 沙袋情景 todo
  740. //后面处理手机加速计的数据
  741. }
  742. }
  743. },
  744. gWatchBLEUpdate: function(data) {
  745. //如果是模块外面触发,需要离线打包
  746. if (this.bMyAttitudeListen) {
  747. this.sendMessage("updateAccAndGyro", data);
  748. return;
  749. }
  750. if (this.ConnectBindingDevice) {
  751. //hotman 沙袋情景 todo
  752. this.gUpdateSandbagAlgorithm({
  753. data: data,
  754. callback: (res) => {
  755. // console.log(res);
  756. if (res.type == 'hit') {
  757. // console.log('gUpdateFilter callback:',res)
  758. let temp = {
  759. direction: res.direction,
  760. angle: res.angle,
  761. name: res.name,
  762. ename: res.ename,
  763. value: res.hit,
  764. mass: 10, //质量
  765. hitPower: res.hit //计算的力
  766. }
  767. this.sendMessage("onBoxingPostHit", temp);
  768. }
  769. }
  770. });
  771. return;
  772. }
  773. if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
  774. //手机情景或者自由模式
  775. let {
  776. ax,
  777. ay,
  778. az
  779. } = data.acc;
  780. //this.BLEConnectDevice.limitType == "rebound"
  781. //这里是监听 _createEquipmentBasedOnBoxingPostHit 回调
  782. this.EquipmentActionObj.updateTriaxialAcc({
  783. xA: ax * 9.80665,
  784. zA: ay * 9.80665,
  785. yA: az * 9.80665,
  786. bLimitRebound: false
  787. })
  788. } else if (this.BLEConnectDevice.usageMode == "hotman") {
  789. //hotman 沙袋情景 todo
  790. this.gUpdateFilter({
  791. data: data,
  792. callback: (res) => {
  793. // console.log(res);
  794. if (res.type == 'hit') {
  795. // console.log('gUpdateFilter callback:',res)
  796. let temp = {
  797. direction: res.direction,
  798. angle: res.angle,
  799. name: res.name,
  800. ename: res.ename,
  801. value: res.hit,
  802. mass: 10, //质量
  803. hitPower: res.hit //计算的力
  804. }
  805. this.sendMessage("onBoxingPostHit", temp);
  806. }
  807. }
  808. });
  809. } else if (this.BLEConnectDevice.usageMode == "ropeSkipping") {
  810. //跳绳模式场景,简单更新触发
  811. //看看是否反馈一个角度,180 ,360
  812. // let temp = {
  813. // direction: "all",
  814. // angle: 0,
  815. // name: "击中", // this.BLEConnectDevice.name,
  816. // ename: "hit", //this.BLEConnectDevice.ename,
  817. // value: 10,
  818. // mass: 10, //质量
  819. // hitPower: 10 //计算的力
  820. // }
  821. // this.sendMessage("onBoxingPostHit", temp);
  822. this.onConvertDeviceData({
  823. data: data,
  824. callback: (outData) => {
  825. data.acc = outData.convertAcc;
  826. data.gyro = outData.convertGyro;
  827. //跳绳蓝牙反馈
  828. this.onBLERopeUpdate(data);
  829. }
  830. });
  831. }
  832. },
  833. updateHitData(a) {
  834. this.xA = a.xAxis;
  835. this.yA = a.yAxis;
  836. this.zA = a.zAxis;
  837. if (Math.abs(this.xA) > 8 && this.oldxA != this.xA && !this.bCalculation) {
  838. this.xAccArray.push(this.xA);
  839. this.oldxA = this.xA;
  840. if (this.calTimeout == null) {
  841. this.calTimeout = setTimeout(() => {
  842. this.bCalculation = true;
  843. for (let i = 0; i < this.xAccArray.length; i++) {
  844. if (this.xAccArray[i] < 0 && this.xAccArray[i] < this.xAccArray[this.xMin]) {
  845. this.xMin = i;
  846. } else if (this.xAccArray[i] > 0 && this.xAccArray[i] > this.xAccArray[this
  847. .xMax]) {
  848. this.xMax = i;
  849. }
  850. }
  851. console.log(this.xAccArray, "==", this.xMin, "==", this.xMax);
  852. if (this.xAccArray[this.xMin] < 0 && this.xAccArray[this.xMax] > 0) {
  853. if (this.xMin > this.xMax)
  854. this.onHit("xRCount", "左勾拳", "leftPunch", this.xAccArray[this.xMin], Math.ceil(
  855. Math.abs(this.xAccArray[this.xMin]) *
  856. puchConfig.BOXING_MASS));
  857. else if (this.xMin < this.xMax)
  858. this.onHit("xLCount", "右勾拳", "rightPunch", this.xAccArray[this.xMax], Math
  859. .ceil(Math.abs(this.xAccArray[this
  860. .xMax]) * puchConfig.BOXING_MASS));
  861. } else if (this.xAccArray[this.xMin] < 0) {
  862. this.onHit("xLCount", "右勾拳", "rightPunch", this.xAccArray[this.xMin], Math.ceil(
  863. Math.abs(this.xAccArray[this.xMin]) *
  864. puchConfig.BOXING_MASS));
  865. } else if (this.xAccArray[this.xMax] > 0) {
  866. this.onHit("xRCount", "左勾拳", "leftPunch", this.xAccArray[this.xMax], Math.ceil(Math
  867. .abs(this.xAccArray[this.xMax]) *
  868. puchConfig.BOXING_MASS));
  869. }
  870. setTimeout(() => {
  871. this.onResetCal();
  872. }, 100);
  873. this.calTimeout = null;
  874. }, 200);
  875. }
  876. } else if (this.zA < -10 && this.oldzA != this.zA && this.xAccArray.length == 0) {
  877. console.log("this.zA:", this.zA);
  878. this.oldzA = this.zA;
  879. setTimeout(() => {
  880. this.onResetCal();
  881. }, 200);
  882. this.onHit("zLCount", "直拳", "punch", this.zA, Math.ceil(Math.abs(this.zA) * puchConfig.BOXING_MASS));
  883. }
  884. },
  885. onHit(direction, name, ename, direValue, power) {
  886. // console.log(direction, direValue, power);
  887. let temp = {
  888. direction: direction,
  889. angle: 0,
  890. name: name,
  891. ename: ename,
  892. value: direValue,
  893. mass: this.mass, //质量
  894. hitPower: power //计算的力
  895. }
  896. this.sendMessage("onBoxingPostHit", temp);
  897. },
  898. onResetCal() {
  899. this.xAccArray = [];
  900. this.xMax = 0;
  901. this.xMin = 0;
  902. this.bCalculation = false;
  903. this.oldxA = 0;
  904. this.oldzA = 0;
  905. this.calTimeout = null;
  906. },
  907. //创建一个 打击对象
  908. _createEquipmentBasedOnBoxingPostHit() {
  909. this.EquipmentActionObj = new EquipmentAction();
  910. this.EquipmentActionObj.addEventListener("resultantHit", (e) => {
  911. console.log(e);
  912. let temp = {
  913. direction: "allCount",
  914. angle: 0,
  915. name: "击中",
  916. ename: "hit",
  917. value: e.acc,
  918. mass: e.mass, //质量
  919. hitPower: e.power //计算的力
  920. }
  921. this.sendMessage("onBoxingPostHit", temp);
  922. })
  923. },
  924. //创建一个 跳识别对象
  925. _createActionJumpOnBoxingPostHit() {
  926. this.actionJumpObj = new ActionJump();
  927. this.actionJumpObj.addEventListener('resultant', (e) => {
  928. let temp = {
  929. direction: "all",
  930. angle: 0,
  931. name: "击中", // this.BLEConnectDevice.name,
  932. ename: "hit", //this.BLEConnectDevice.ename,
  933. value: 10,
  934. mass: 10, //质量
  935. hitPower: 10 //计算的力
  936. }
  937. if (e.type == 'stateDataOfJump') {
  938. console.log("game stateDataOfJump");
  939. this.sendMessage("onBoxingPostHit", temp);
  940. } else if (e.type == 'stop') {
  941. console.log("game stop");
  942. this.onClearData();
  943. // this.sendMessage("onBoxingPostHit", temp);
  944. }
  945. })
  946. },
  947. /**
  948. * @param {Object} gameData
  949. * 识别跳部分数据处理
  950. */
  951. onBLERopeUpdate(gameData) {
  952. //********陀螺仪角速度********
  953. let {
  954. gx,
  955. gy,
  956. gz
  957. } = gameData.gyro;
  958. let {
  959. min,
  960. s,
  961. ms
  962. } = gameData;
  963. //-gameData.acc.ax * 10;
  964. let _ax = gameData.acc.ax * 10;
  965. let _ay = gameData.acc.ay * 10;
  966. let _az = gameData.acc.az * 10;
  967. //低通滤波分离重力
  968. let alpha = 0.8;
  969. this.xA = alpha * this.xA + (1 - alpha) * _ax;
  970. this.yA = alpha * this.yA + (1 - alpha) * _ay;
  971. this.zA = alpha * this.zA + (1 - alpha) * _az;
  972. //高通滤波获取线性速度
  973. let linear_acceleration_x = _ax - this.xA;
  974. let linear_acceleration_y = _az - this.zA;
  975. let linear_acceleration_z = _ay - this.yA;
  976. let _temp = {
  977. linearAcc: {
  978. lAccX: linear_acceleration_x,
  979. lAccY: linear_acceleration_y,
  980. lAccZ: linear_acceleration_z
  981. }, //gameData.acc,
  982. oriAcc: {
  983. oAccX: _ax,
  984. oAccY: _ay,
  985. oAccZ: _az
  986. },
  987. gravityAcc: {
  988. gravityX: this.xA,
  989. gravityY: this.yA,
  990. gravityZ: this.zA
  991. },
  992. bLimitRebound: false,
  993. resultant: Math.sqrt(_ax * _ax +
  994. _ay * _ay + _az * _az),
  995. runIndex: this.BLEAccIndex,
  996. //陀螺仪
  997. oriGyro: {
  998. oGyroX: gx,
  999. oGyroY: gy,
  1000. oGyroZ: gz
  1001. },
  1002. //输入当前轴
  1003. bYAxis: true,
  1004. };
  1005. this.actionJumpObj.updateJump(_temp);
  1006. this.BLEAccIndex++;
  1007. },
  1008. onClearData() {
  1009. this.BLEAccIndex = 0;
  1010. },
  1011. }
  1012. }
  1013. </script>
  1014. <style>
  1015. /* #ifdef APP-PLUS */
  1016. .web-view {
  1017. flex: 1;
  1018. flex-direction: column;
  1019. /* background-color: #007AFF; */
  1020. }
  1021. .web-view-child {
  1022. width: 750rpx;
  1023. flex: 1;
  1024. }
  1025. /* #endif */
  1026. /* #ifdef H5 */
  1027. .web-view {
  1028. display: flex;
  1029. flex-direction: column;
  1030. position: absolute;
  1031. bottom: 0;
  1032. top: 0;
  1033. left: 0;
  1034. right: 0;
  1035. }
  1036. .web-view-child {
  1037. position: relative;
  1038. width: 100%;
  1039. height: 100%;
  1040. }
  1041. /* #endif */
  1042. .sendMessage {
  1043. width: 300rpx;
  1044. position: fixed;
  1045. bottom: 100rpx;
  1046. left: 50rpx;
  1047. }
  1048. .web-back {
  1049. position: fixed;
  1050. top: 40px;
  1051. right: 20px;
  1052. width: 160rpx;
  1053. height: 80rpx;
  1054. border-radius: 45px;
  1055. /* border: 1px solid #FFFFFF; */
  1056. /* box-shadow: 0px 0px 1px #FFFFFF; */
  1057. background-color: rgba(0, 0, 0, 1);
  1058. opacity: 0.5;
  1059. /* #ifndef APP-PLUS-NVUE */
  1060. /* z-Index: 999; */
  1061. display: flex;
  1062. /* #endif */
  1063. justify-content: center;
  1064. align-items: center;
  1065. }
  1066. </style>