subGame.nvue 35 KB

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