subGame.nvue 34 KB

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