subGame.nvue 33 KB

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