boxing-hit.vue 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319
  1. <template>
  2. <view style="width:100%; margin-bottom: 50rpx;">
  3. <!-- 计时器 -->
  4. <view class="hitBoxingTimer flex justify-center">
  5. <boxingCountDown ref="boxingCountDownRef" :show-day="false" :second="showSportTime" color="#9695f7" background-color="#FFFFFF"
  6. border-color="#007AFF" splitorColor="#FFFFFF" />
  7. </view>
  8. <view v-if="mode == 'pkMode'" style="height: 50rpx;"></view>
  9. <view v-else style="height: 20rpx;"></view>
  10. <view style="display: flex; flex-direction: column; justify-content: center;align-items: center;
  11. position: relative; width: 100%;">
  12. <!-- 波动 -->
  13. <view v-if="mode !== 'pkMode'" class="flex justify-around align-center" style="width: 600rpx;height: 100rpx;">
  14. <view style="height: 1rpx;width: 80rpx;background-color: #FFFFFF;"></view>
  15. <view style="display: flex; justify-content: center; align-self: center; height: 100%;">
  16. <view style="display: flex; justify-content: center; align-items: center;">
  17. <view class="wave-d-item " v-for="(item, index) in wave_d_time" :key="index" :class="wave_d_play?'hit-wave':''"
  18. :style="{'--time': item.run * wave_run_ratio,'--delay':item.delay * wave_run_ratio,'height': wave_d_play?item.sHeight+'rpx':'20rpx'}"></view>
  19. </view>
  20. <view style="display: flex; justify-content: center; align-items: center; flex-direction: row-reverse;">
  21. <view class="wave-d-item " v-for="(item, index) in wave_d_time" :key="index" :class="wave_d_play?'hit-wave':''"
  22. :style="{'--time': item.run * wave_run_ratio,'--delay':item.delay * wave_run_ratio,'height': wave_d_play?item.sHeight+'rpx':'20rpx'}"></view>
  23. </view>
  24. </view>
  25. <view style="height: 1rpx;width: 80rpx;background-color: #FFFFFF;"></view>
  26. </view>
  27. <view v-if="mode == 'pkMode'" style="height: 30rpx;"></view>
  28. <!-- 当前拳击力-->
  29. <view v-if="mode == 'pkMode'" class="flex justify-center align-center " style="margin-top: 40rpx; background-color: rgba(255,255,255,0.1); width: 420rpx; height: 90rpx;border-radius: 60rpx;">
  30. <image src="/static/modal/boxing-hit/b.png" style="width: 50rpx; height: 50rpx;" mode="aspectFit"></image>
  31. <view class="hit-current-count">
  32. {{currentHitStrength}}
  33. </view>
  34. </view>
  35. <view v-else style="position: relative; width: 100%;" :style="{'opacity': hitStrengthOpacity}">
  36. <view style="position: absolute;
  37. left: 0;
  38. top: 0;
  39. bottom: 0;
  40. right: 0;" class="flex justify-center">
  41. <view class="flex justify-center align-center " style="background-color: rgba(0,0,0,0.4); width: 300rpx; height: 90rpx;border-radius: 60rpx;">
  42. <!-- <image src="/static/modal/boxing-hit/b.png" style="width: 50rpx; height: 50rpx;" mode="aspectFit"></image> -->
  43. <view class="hit-current-count-power">力量</view>
  44. <view class="hit-current-count">
  45. {{currentHitStrength}}
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. <view v-if="mode == 'pkMode'" style="height: 80rpx;"></view>
  51. <!-- 控制按钮 -->
  52. <view class="flex justify-center " :class="mode == 'pkMode'?'big':''" style="margin-top: 40rpx;" @tap="onControlPlay">
  53. <view style="position: relative; width: 260rpx; height: 260rpx;">
  54. <image style="width: 100%; height: 100%;" src="/static/modal/boxing-hit/hit-button-bg.png"></image>
  55. <image class="hit-button-rotate " :class="bRingAnimation?'hit-button-bg-play':'hit-button-bg-paused'" style="position: absolute;top: 10%;left: 10%;bottom: 0;right: 0;width: 80%; height: 80%;"
  56. src="/static/modal/boxing-hit/hit-button-ef.png"></image>
  57. <view style="position: absolute;top: 0;left: 0;bottom: 0;right: 0;width: 100%; height: 100%; display: flex;justify-content: center; align-items: center;">
  58. <image style="width: 50rpx; height: 50rpx; transform: scale(-1,1);" :src="bControlRun?'/static/modal/boxing-hit/hit-pause.png':'/static/modal/boxing-hit/hit-play.png'"></image>
  59. </view>
  60. </view>
  61. </view>
  62. <view v-if="mode == 'pkMode'" style="height: 80rpx;"></view>
  63. <!-- 模式按钮 -->
  64. <view class="flex justify-center " style="margin-top: 40rpx;" @tap="onChangeMode">
  65. <view style="position: relative; width: 310rpx; height: 90rpx;background-color: #FFFFFF; display: flex;flex-direction: row;justify-content: center;align-items: center; border-radius: 50rpx;">
  66. <image style="width: 45rpx; height: 45rpx;" src="/static/personal/switch.png"></image>
  67. <view style="margin-left: 20rpx;color:#9797FF; font-weight: bold;font-size: 17px;">{{mode=="pkMode"?'健身模式':'PK模式'}}
  68. </view>
  69. </view>
  70. </view>
  71. <view v-if="mode == 'pkMode'" style="height: 20rpx;"></view>
  72. <view v-if="mode == 'pkMode'" class="hit-vertical-container" :style="{'top': mode == 'pkMode'?'-50rpx':'-300rpx'}">
  73. <view class="hit-vertical-bar">
  74. <view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
  75. <view :class="25-aiShowCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
  76. <view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+1}}</view>
  77. </view>
  78. </view>
  79. <view class="hit-vertical-bar">
  80. <view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
  81. <view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+1}}</view>
  82. <view :class="25-myShowCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
  83. </view>
  84. </view>
  85. </view>
  86. <view v-else class="hit-vertical-container" :style="{'top': mode == 'pkMode'?'-50rpx':'-300rpx'}">
  87. <view class="hit-vertical-bar">
  88. <view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
  89. <view :class="showCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
  90. <view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+1}}</view>
  91. </view>
  92. </view>
  93. <view class="hit-vertical-bar">
  94. <view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
  95. <view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+26}}</view>
  96. <view :class="showCount>=index+26? 'hit-vertical-active':'hit-vertical-inactive'"></view>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. <!-- <button style="margin-top: 100rpx;" @tap="onTestHit('left')">击中</button> -->
  102. <!-- 显示数据 -->
  103. <view class="flex justify-around " style="margin: 60rpx 15rpx;">
  104. <view class="boxing-item-bg">
  105. <image src="/static/modal/boxing-hit/f.png" class="boxing-hit-png " mode="aspectFit"></image>
  106. <view class="text-white text-13px" style="margin: 10rpx 0;">最大力量</view>
  107. <view class="hit-count">
  108. {{mode == 'pkMode'?PKMaxStrength:maxStrength}}
  109. </view>
  110. </view>
  111. <view class="boxing-item-bg">
  112. <image src="/static/modal/boxing-hit/b.png" class="boxing-hit-png " mode="aspectFit"></image>
  113. <view class="text-white text-13px" style="margin: 10rpx 0;">平均力量</view>
  114. <view class="hit-count">
  115. {{mode == 'pkMode'?PKAverageStrength:averageStrength}}
  116. </view>
  117. </view>
  118. <view class="boxing-item-bg">
  119. <image src="/static/modal/boxing-hit/e.png" class="boxing-hit-png " mode="aspectFit"></image>
  120. <view class="text-white text-13px" style="margin: 10rpx 0;">平均速度</view>
  121. <view class="hit-count">
  122. {{mode == 'pkMode'?PKAverageSpeed:averageSpeed}}
  123. </view>
  124. </view>
  125. <view class="boxing-item-bg">
  126. <image src="/static/modal/boxing-hit/n.png" class="boxing-hit-png " mode="aspectFit"></image>
  127. <view class="text-white text-13px" style="margin: 10rpx 0;">击打数</view>
  128. <view class="hit-count">
  129. {{mode == 'pkMode'?PKAllShowHitCount:allShowHitCount}}
  130. </view>
  131. </view>
  132. </view>
  133. </view>
  134. </template>
  135. <script>
  136. import boxingCountDown from '@/components/uni-count-down/uni-count-down.vue'
  137. import hitCharts from '@/components/u-charts/u-charts.js';
  138. import puchConfig from "@/util/util-js/puchConfig.js"
  139. import EquipmentAction from "@/util/util-js/EquipmentAction.js"
  140. export default {
  141. components: {
  142. boxingCountDown
  143. },
  144. props: {
  145. bUpdate: {
  146. type: Boolean,
  147. default: false
  148. },
  149. showTime: {
  150. type: Number,
  151. default: 0
  152. },
  153. //默认是防回弹更新
  154. bRebound: {
  155. type: Boolean,
  156. default: true,
  157. }
  158. },
  159. data() {
  160. return {
  161. mode: 'pkMode', //pkMode calorieMode
  162. //满格的数值是 25
  163. maxShowCount: 25,
  164. //pk模式下,两边涨的区分,自己和ai
  165. myShowCount: 0,
  166. myPowerCount: 0,
  167. aiShowCount: 0,
  168. aiPowerCount: 0,
  169. //显示的点
  170. showCount: 0,
  171. //记录打击的次数
  172. powerCount: 0,
  173. //当前打击的最大值
  174. powerMaxCount: 0,
  175. xA1: 0,
  176. yA1: 0,
  177. zA1: 0,
  178. xA: 0,
  179. yA: 0,
  180. zA: 0,
  181. xO: 0,
  182. yO: 0,
  183. zO: 0,
  184. mass: 5,
  185. //大概消耗的卡路里
  186. calorie: 0,
  187. //与加速度相关的卡路里
  188. otherCalorie: 0,
  189. //大概消耗的卡路里
  190. PKCalorie: 0,
  191. //与加速度相关的卡路里
  192. PKOtherCalorie: 0,
  193. leftHookUrl: "/static/modal/boxing-post/left-hook.mp3",
  194. rightHookUrl: "/static/modal/boxing-post/right-hook.mp3",
  195. straightHookUrl: "/static/modal/boxing-post/straight-hook.mp3",
  196. hookAudioContext: null,
  197. //新手语音提示
  198. leftTipUrl: "/static/modal/boxing-post/tipLeft.mp3",
  199. rightTipUrl: "/static/modal/boxing-post/tipRight.mp3",
  200. straightTipUrl: "/static/modal/boxing-post/tipStraight.mp3",
  201. greatTipUrl: "/static/modal/boxing-post/tipGreat.mp3",
  202. giveGoTipUrl: "/static/modal/boxing-post/tipGiveItAGo.mp3",
  203. startTraining: "/static/modal/boxing-post/tipStartTraining.mp3",
  204. //击打状态音效
  205. hitUrl: "/static/elect/hit.mp3",
  206. missUrl: "/static/elect/miss.mp3",
  207. //是否在播放
  208. bPlay: false,
  209. //新手
  210. bGuide: false,
  211. //是否是特殊拳击
  212. bGuideEF: false,
  213. //运动时间
  214. showSportTime: this.showTime,
  215. sportTimeInterval: null,
  216. //拳击数据判断对象
  217. EquipmentActionObj: null,
  218. wave_array: [{
  219. wPlay: false
  220. },
  221. {
  222. wPlay: false
  223. },
  224. {
  225. wPlay: false
  226. },
  227. {
  228. wPlay: false
  229. },
  230. ],
  231. wave_run_array: [],
  232. wave_time: [{
  233. run: 0.5,
  234. delay: 3,
  235. height: 20
  236. },
  237. {
  238. run: 1,
  239. delay: 3,
  240. height: 30
  241. },
  242. {
  243. run: 2,
  244. delay: 3,
  245. height: 80
  246. },
  247. {
  248. run: 0.5,
  249. delay: 2,
  250. height: 50
  251. },
  252. {
  253. run: 1,
  254. delay: 2,
  255. height: 35
  256. },
  257. {
  258. run: 2,
  259. delay: 2,
  260. height: 20
  261. }
  262. ],
  263. wave_d_play: false,
  264. wave_d_timeout: null,
  265. wave_run_ratio: 0.4,
  266. wave_d_time: [{
  267. run: 1,
  268. delay: 1.1,
  269. height: 20,
  270. sHeight: 20,
  271. play: false
  272. },
  273. {
  274. run: 1,
  275. delay: 1,
  276. height: 30,
  277. sHeight: 20,
  278. play: true
  279. },
  280. {
  281. run: 1,
  282. delay: 0.9,
  283. height: 15,
  284. sHeight: 20,
  285. play: true
  286. },
  287. {
  288. run: 1,
  289. delay: 0.8,
  290. height: 50,
  291. sHeight: 20,
  292. play: true
  293. },
  294. {
  295. run: 1.3,
  296. delay: 0.7,
  297. height: 35,
  298. sHeight: 20,
  299. play: true
  300. },
  301. {
  302. run: 1.4,
  303. delay: 0.6,
  304. height: 20,
  305. sHeight: 20,
  306. play: true
  307. },
  308. {
  309. run: 1.5,
  310. delay: 0.5,
  311. height: 25,
  312. sHeight: 20,
  313. play: true
  314. },
  315. {
  316. run: 1.6,
  317. delay: 0.4,
  318. height: 40,
  319. sHeight: 20,
  320. play: true
  321. },
  322. {
  323. run: 1.7,
  324. delay: 0.3,
  325. height: 60,
  326. sHeight: 20,
  327. play: true
  328. },
  329. {
  330. run: 1.8,
  331. delay: 0.2,
  332. height: 50,
  333. sHeight: 20,
  334. play: true
  335. },
  336. {
  337. run: 1.9,
  338. delay: 0.1,
  339. height: 80,
  340. sHeight: 20,
  341. play: true
  342. },
  343. {
  344. run: 1.8,
  345. delay: 0,
  346. height: 70,
  347. sHeight: 20,
  348. play: true
  349. }
  350. ],
  351. bControlRun: false,
  352. bRingAnimation: false,
  353. maxStrength: 0,
  354. averageStrength: 0,
  355. allStrength: 0,
  356. averageSpeed: 0,
  357. averageSpeedInterval: null,
  358. tempHitCount: 0,
  359. allTempHitCount: 0,
  360. allShowHitCount: 0,
  361. currentHitStrength: 0,
  362. // testHitInterval: null,
  363. aiHitInterval: null,
  364. //击打时候动画对象
  365. hitStrengthOpacityInterval: null,
  366. hitStrengthOpacity: 0,
  367. //pk 模式下的数据
  368. PKMaxStrength: 0,
  369. PKAverageStrength: 0,
  370. PKAllStrength: 0,
  371. PKAverageSpeed: 0,
  372. PKAverageSpeedInterval: null,
  373. PKTempHitCount: 0,
  374. PKAllTempHitCount: 0,
  375. PKAllShowHitCount: 0,
  376. BLENum: 0,
  377. BLEACX: 0,
  378. BLEACYL: 0,
  379. }
  380. },
  381. watch: {
  382. bUpdate(val) {
  383. },
  384. showTime(val) {
  385. this.showSportTime = val;
  386. }
  387. },
  388. created() {
  389. let _self = this;
  390. _self.hookAudioContext = uni.createInnerAudioContext();
  391. _self.hookAudioContext.autoplay = false;
  392. _self.hookAudioContext.src = _self.straightHookUrl;
  393. _self.hookAudioContext.volume = 0.5;
  394. console.log(" ***** boxing-post created ******");
  395. _self.onBindAcc();
  396. _self.EquipmentActionObj = new EquipmentAction();
  397. _self.EquipmentActionObj.addEventListener("resultantHit", (e) => {
  398. // console.log("acc:",this.xA,this.yA,this.zA);
  399. // console.log("data:", this.xA1, this.yA1, this.zA1);
  400. if (this.mode == "pkMode") {
  401. this._pkHitOnly(e.acc, e.power);
  402. } else {
  403. this._HitOnly(e.acc, e.power);
  404. }
  405. })
  406. if (this.averageSpeedInterval) {
  407. clearInterval(this.averageSpeedInterval);
  408. this.averageSpeedInterval = null;
  409. }
  410. //计算平均速度
  411. this.averageSpeedInterval = setInterval(() => {
  412. if (this.mode == 'PKMode') {
  413. this.PKAverageSpeed = this.PKTempHitCount;
  414. this.PKTempHitCount = 0;
  415. } else {
  416. this.averageSpeed = this.tempHitCount;
  417. this.tempHitCount = 0;
  418. }
  419. }, 10000)
  420. },
  421. beforeDestroy() {
  422. console.log(" ***** boxing-post destroyed ******");
  423. this.onUnbindAcc();
  424. // this.onUnbindOri();
  425. let _self = this;
  426. if (_self.hookAudioContext)
  427. _self.hookAudioContext.destroy();
  428. if (_self.sportTimeInterval) {
  429. clearInterval(_self.sportTimeInterval);
  430. _self.sportTimeInterval = null;
  431. }
  432. if (_self.averageSpeedInterval) {
  433. clearInterval(_self.averageSpeedInterval);
  434. _self.averageSpeedInterval = null;
  435. }
  436. // if (_self.testHitInterval) {
  437. // clearInterval(_self.testHitInterval);
  438. // _self.testHitInterval = null;
  439. // }
  440. if (this.aiHitInterval) {
  441. clearInterval(this.aiHitInterval);
  442. this.aiHitInterval = null;
  443. }
  444. },
  445. methods: {
  446. onSetRingAnimation(booleanValue) {
  447. this.bRingAnimation = booleanValue;
  448. },
  449. moveBoxingHandle() {
  450. return;
  451. },
  452. //测试打击
  453. onTestHit(data) {
  454. let _self = this;
  455. let maxPower = Math.floor(Math.random() * 13);
  456. // console.log("maxPower:", maxPower);
  457. if (this.mode == "pkMode") {
  458. this._pkHitOnly(maxPower, maxPower * 10);
  459. } else {
  460. this._HitOnly(maxPower, maxPower * 10);
  461. }
  462. },
  463. //平时击打的力量槽动画播放
  464. onPlayPowerAnimation(bGreat) {
  465. if (bGreat) {
  466. this.hookAudioContext.stop();
  467. this.hookAudioContext.src = this.greatTipUrl;
  468. this.hookAudioContext.play();
  469. } else {
  470. this.hookAudioContext.stop();
  471. this.hookAudioContext.src = this.hitUrl;
  472. this.hookAudioContext.play();
  473. }
  474. let _self = this;
  475. if (_self.powerInterval) {
  476. clearInterval(_self.powerInterval);
  477. _self.powerInterval = null;
  478. }
  479. let bAdd = true;
  480. let _oldPowerCount = _self.powerCount;
  481. let _currentMaxCount = _oldPowerCount + 10;
  482. let _duraciotn = 300 / _currentMaxCount;
  483. _self.powerInterval = setInterval(function() {
  484. if (_self.showCount >= _currentMaxCount) {
  485. bAdd = false;
  486. } else if (_self.showCount <= _oldPowerCount && !bAdd) {
  487. _self.showCount = _self.powerCount;
  488. clearInterval(_self.powerInterval);
  489. _self.powerInterval = null;
  490. return;
  491. }
  492. if (bAdd)
  493. _self.showCount++;
  494. else
  495. _self.showCount--;
  496. }, _duraciotn); //300ms/40格
  497. },
  498. //pk模式击打的力量槽动画播放
  499. onPKModePlayPowerAnimation(bGreat) {
  500. if (bGreat) {
  501. this.hookAudioContext.stop();
  502. this.hookAudioContext.src = this.greatTipUrl;
  503. this.hookAudioContext.play();
  504. } else {
  505. this.hookAudioContext.stop();
  506. this.hookAudioContext.src = this.hitUrl;
  507. this.hookAudioContext.play();
  508. }
  509. let _self = this;
  510. _self.myShowCount = _self.myPowerCount;
  511. // if (_self.powerInterval) {
  512. // clearInterval(_self.powerInterval);
  513. // _self.powerInterval = null;
  514. // }
  515. // let bAdd = true;
  516. // let _oldPowerCount = _self.myPowerCount;
  517. // let _currentMaxCount = _oldPowerCount + 10;
  518. // let _duraciotn = 300 / _currentMaxCount;
  519. // _self.powerInterval = setInterval(function() {
  520. // if (_self.myShowCount >= _currentMaxCount) {
  521. // bAdd = false;
  522. // } else if (_self.myShowCount <= _oldPowerCount && !bAdd) {
  523. // _self.myShowCount = _self.myPowerCount;
  524. // clearInterval(_self.powerInterval);
  525. // _self.powerInterval = null;
  526. // return;
  527. // }
  528. // if (bAdd)
  529. // _self.myShowCount++;
  530. // else
  531. // _self.myShowCount--;
  532. // }, _duraciotn); //300ms/40格
  533. },
  534. onBindAcc(globalAcc) {
  535. uni.$on('watchAcceleration', this.updateAcc);
  536. },
  537. onUnbindAcc() {
  538. uni.$off('watchAcceleration', this.updateAcc);
  539. },
  540. onBindOri(globalOri) {
  541. uni.$on('watchOrientation', this.updateOri);
  542. },
  543. onUnbindOri() {
  544. uni.$off('watchOrientation', this.updateOri);
  545. },
  546. updateAcc(acc) {
  547. // console.log("acc:" ,acc.xAxis,acc.yAxis,acc.zAxis);
  548. this.xA = acc.xAxis;
  549. this.yA = acc.yAxis;
  550. this.zA = acc.zAxis;
  551. // return;
  552. if (!this.bUpdate || !this.bPlay) return;
  553. this.EquipmentActionObj.updateAcc({
  554. xA: acc.xAxis,
  555. zA: acc.yAxis,
  556. yA: acc.zAxis,
  557. bLimitRebound: this.bRebound
  558. })
  559. },
  560. //旧的蓝牙模块更新数据
  561. onBLEUpdate(data) {
  562. if (!this.bPlay) return;
  563. if (data.num)
  564. this.BLENum = data.num;
  565. if (data.acx)
  566. this.BLEACX = data.acx;
  567. if (data.acy) {
  568. this.BLEACYL = data.acy;
  569. // let acc = Math.ceil((Math.abs(this.BLEACX) + Math.abs(this.BLEACYL))*0.0005);
  570. let _abs = (Math.abs(this.BLEACX) + Math.abs(this.BLEACYL));
  571. let _ratioAbs = _abs > 65000 ? 1 : _abs / 65000;
  572. // console.log("当前值:",(Math.abs(this.BLEACX) + Math.abs(this.BLEACYL)),acc,this._onReducedBlood(acc),_ratioAbs,Math.ceil(_ratioAbs*30));
  573. let acc = Math.ceil(_ratioAbs * 30);
  574. if (this.mode == "pkMode") {
  575. this._pkHitOnly(acc, acc * 10);
  576. } else {
  577. this._HitOnly(acc, acc * 10);
  578. }
  579. }
  580. },
  581. //hotman 情景下刷新
  582. onBLEHotmanUpdate(data) {
  583. if (!this.bUpdate || !this.bPlay) return;
  584. let {
  585. hit
  586. } = data;
  587. let power = parseInt(hit);
  588. let acc = power*0.1;
  589. if (this.mode == "pkMode") {
  590. this._pkHitOnly(acc, power);
  591. } else {
  592. this._HitOnly(acc, power);
  593. }
  594. },
  595. //蓝牙更新数据
  596. onBLEHandleUpdate(data) {
  597. if (!this.bUpdate || !this.bPlay) return;
  598. let {
  599. ax,
  600. ay,
  601. az
  602. } = data.acc;
  603. let xA = ax * 9.80665;
  604. let yA = ay * 9.80665;
  605. let zA = az * 9.80665;
  606. this.xA1 = xA;
  607. this.yA1 = yA;
  608. this.zA1 = zA;
  609. // console.log("data:" ,xA,yA,zA);
  610. // updateAcc updateTriaxialAcc
  611. this.EquipmentActionObj.updateTriaxialAcc({
  612. xA: xA,
  613. zA: yA,
  614. yA: zA,
  615. bLimitRebound: true
  616. })
  617. },
  618. updateOri(ori) {
  619. this.xO = ori.beta;
  620. this.zO = ori.alpha;
  621. this.yO = ori.gamma;
  622. },
  623. onControlPlay() {
  624. this._customControlPlay({
  625. bControlRun: this.bControlRun
  626. });
  627. },
  628. onCloseDevices() {
  629. let _self = this;
  630. if(!_self.bPlay)return;
  631. if (_self.sportTimeInterval) {
  632. clearInterval(_self.sportTimeInterval);
  633. _self.sportTimeInterval = null;
  634. }
  635. if (_self.aiHitInterval) {
  636. clearInterval(_self.aiHitInterval);
  637. _self.aiHitInterval = null;
  638. }
  639. _self.bPlay = false;
  640. _self.bControlRun = false;
  641. //如果是新手教程,也直接停掉
  642. _self.bGuide = false;
  643. _self.bGuideEF = false;
  644. if (_self.mode == "pkMode") {
  645. _self.myShowCount = 0;
  646. _self.myPowerCount = 0;
  647. _self.aiShowCount = 0;
  648. _self.aiPowerCount = 0;
  649. }
  650. _self.$emit("closeBoxingControl");
  651. },
  652. onHitPlay(bPlaying) {
  653. if (bPlaying) {
  654. this.bControlRun = bPlaying;
  655. } else {
  656. this.bControlRun = !this.bControlRun;
  657. }
  658. },
  659. _customControlPlay(data) {
  660. let _self = this;
  661. //1.检查是否符合要求,再进行训练
  662. if (data.bControlRun) {
  663. if (_self.sportTimeInterval) {
  664. clearInterval(_self.sportTimeInterval);
  665. _self.sportTimeInterval = null;
  666. }
  667. this.bPlay = false;
  668. // this.$refs.customControlButtons.onPlay();
  669. this.onHitPlay();
  670. //如果是新手教程,也直接停掉
  671. this.bGuide = false;
  672. this.bGuideEF = false;
  673. // if (this.testHitInterval) {
  674. // clearInterval(this.testHitInterval);
  675. // this.testHitInterval = null;
  676. // }
  677. if (this.mode == "pkMode") {
  678. this.myShowCount = 0;
  679. this.myPowerCount = 0;
  680. this.aiShowCount = 0;
  681. this.aiPowerCount = 0;
  682. }
  683. if (this.aiHitInterval) {
  684. clearInterval(this.aiHitInterval);
  685. this.aiHitInterval = null;
  686. }
  687. this.$emit("boxingPostControlPlay", false);
  688. } else {
  689. this.$emit("boxingPostCheck");
  690. }
  691. },
  692. _PKOver(data) {
  693. let _self = this;
  694. //1.检查是否符合要求,再进行训练
  695. if (_self.sportTimeInterval) {
  696. clearInterval(_self.sportTimeInterval);
  697. _self.sportTimeInterval = null;
  698. }
  699. this.bPlay = false;
  700. this.onHitPlay();
  701. //如果是新手教程,也直接停掉
  702. this.bGuide = false;
  703. this.bGuideEF = false;
  704. if (this.aiHitInterval) {
  705. clearInterval(this.aiHitInterval);
  706. this.aiHitInterval = null;
  707. }
  708. },
  709. //新手引导
  710. onGuideBoxingPostPlay() {
  711. console.log("onGuideBoxingPostPlay");
  712. let _self = this;
  713. _self.bPlay = true;
  714. //
  715. _self.bGuide = true;
  716. // 按钮事件
  717. // _self.$refs.customControlButtons.onPlay();
  718. _self.onHitPlay();
  719. },
  720. //训练退出时候,重新信息
  721. onBoxingPostStop() {
  722. },
  723. //调用播放
  724. onBoxingPostPlay(bPlaying) {
  725. let _self = this;
  726. //判断是否是pk模式,如果是pk模式,则用pk模式播放
  727. if (bPlaying) {
  728. _self.bPlay = true;
  729. // 按钮事件
  730. // _self.$refs.customControlButtons.onPlay(true);
  731. _self.onHitPlay(true);
  732. // if (_self.testHitInterval) {
  733. // clearInterval(_self.testHitInterval);
  734. // _self.testHitInterval = null;
  735. // }
  736. // _self.testHitInterval = setInterval(() => {
  737. // this.onTestHit();
  738. // }, 300)
  739. if (_self.sportTimeInterval) {
  740. clearInterval(_self.sportTimeInterval);
  741. _self.sportTimeInterval = null;
  742. }
  743. if (this.mode == 'pkMode') {
  744. if (this.aiHitInterval) {
  745. clearInterval(this.aiHitInterval);
  746. this.aiHitInterval = null;
  747. }
  748. this.aiHitInterval = setInterval(() => {
  749. let _random = Math.floor(Math.random() * 10);
  750. if (_random < 5) {
  751. this.onAiHitEvent();
  752. }
  753. }, 500)
  754. }
  755. //play true 时候,开启时间计算
  756. _self.sportTimeInterval = setInterval(() => {
  757. _self.showSportTime++;
  758. if (_self.showSportTime >= 20 && _self.showSportTime % 20 == 0) {
  759. _self.$emit("updateSportTime", _self.showSportTime);
  760. }
  761. }, 1000)
  762. }
  763. },
  764. //自由模式下的打击
  765. _HitOnly(acc, power) {
  766. //动画的高度
  767. let _ratio = acc / 10;
  768. if (_ratio > 1) _ratio = 1;
  769. if (_ratio < 0.5) _ratio = 0.5;
  770. for (let i = 0; i < this.wave_d_time.length; i++) {
  771. this.wave_d_time[i].sHeight = this.wave_d_time[i].height * _ratio;
  772. }
  773. this.onPlayPowerAnimation();
  774. this.allTempHitCount++;
  775. this.allShowHitCount++;
  776. this.tempHitCount++;
  777. this.currentHitStrength = power;
  778. if (this.maxStrength < power) {
  779. this.maxStrength = power;
  780. }
  781. this.allStrength += power;
  782. this.averageStrength = (this.allStrength / this.allShowHitCount).toFixed(1);
  783. //击打次数一个卡路里,就是基础卡路里
  784. this.calorie = puchConfig.getBoxingCalorie(this.allTempHitCount);
  785. //击打的加速度添加的卡路里,是额外计算的卡路里
  786. this.otherCalorie += puchConfig.getAccCalorie(acc);
  787. // console.log( puchConfig.getAccCalorie(acc),this.calorie);
  788. let _all = this.calorie.add(this.otherCalorie);
  789. //10 大卡,为一个周期 分50份
  790. this.powerCount = parseInt(_all * 5);
  791. if (this.powerCount >= 50) {
  792. console.log("同步卡路里");
  793. console.log("this.calorie:", this.calorie, this.otherCalorie, _all);
  794. this.$emit('updateCalorie', _all);
  795. this.allTempHitCount = 0;
  796. this.powerCount = 0;
  797. this.otherCalorie = 0;
  798. }
  799. if (!this.wave_d_play) {
  800. if (this.wave_d_timeout) {
  801. clearTimeout(this.wave_d_timeout);
  802. this.wave_d_timeout = null;
  803. }
  804. this.wave_d_play = true;
  805. this.wave_d_timeout = setTimeout(() => {
  806. this.wave_d_play = false;
  807. }, 1000 * this.wave_run_ratio)
  808. }
  809. if (this.hitStrengthOpacityInterval) {
  810. clearTimeout(this.hitStrengthOpacityInterval);
  811. this.hitStrengthOpacityInterval = null;
  812. }
  813. this.hitStrengthOpacity = 1;
  814. this.hitStrengthOpacityInterval = setTimeout(() => {
  815. this.hitStrengthOpacity = 0;
  816. }, 1000)
  817. },
  818. //pk模式下的打击
  819. _pkHitOnly(acc, power) {
  820. this.onPKModePlayPowerAnimation();
  821. this.PKAllTempHitCount++;
  822. this.PKAllShowHitCount++;
  823. this.PKTempHitCount++;
  824. this.currentHitStrength = power;
  825. if (this.PKMaxStrength < power) {
  826. this.PKMaxStrength = power;
  827. }
  828. this.PKAllStrength += power;
  829. this.PKAverageStrength = (this.PKAllStrength / this.PKAllShowHitCount).toFixed(1);
  830. //击打次数一个卡路里,就是基础卡路里
  831. this.PKCalorie = puchConfig.getBoxingCalorie(this.PKAllTempHitCount);
  832. //击打的加速度添加的卡路里,是额外计算的卡路里
  833. // this.PKOtherCalorie += puchConfig.getAccCalorie(acc);
  834. // console.log( puchConfig.getAccCalorie(acc),this.calorie);
  835. let _all = this.PKCalorie; // this.PKCalorie.add(this.PKOtherCalorie);
  836. //10 大卡,为一个周期 分25份
  837. // this.myPowerCount = parseInt(_all * 2.5 * 20);
  838. //中一个小拳头扣一滴血,中一个中拳头去2滴血,中一个大拳头去3滴血。
  839. let _myBloodPoint = this._onReducedBlood(acc);
  840. this.myPowerCount += _myBloodPoint;
  841. //用户打击完成
  842. if (this.myPowerCount >= this.maxShowCount) {
  843. console.log("this.calorie:", this.PKCalorie, this.PKOtherCalorie, _all);
  844. this.$emit('updateCalorie', _all);
  845. this.PKAllTempHitCount = 0;
  846. this.myPowerCount = 0;
  847. this.myShowCount = 0;
  848. this.PKOtherCalorie = 0;
  849. //通知结果
  850. this.$emit('gameOver', {
  851. myWin: true
  852. });
  853. this._PKOver();
  854. this.aiPowerCount = 0;
  855. this.aiShowCount = 0;
  856. }
  857. this.$emit('hitEvent', _myBloodPoint);
  858. },
  859. onAiHitEvent() {
  860. let _acc = Math.ceil(Math.random() * 30);
  861. let _aiBloodPoint = this._onReducedBlood(_acc);
  862. this.aiPowerCount += _aiBloodPoint;
  863. // this.aiPowerCount += 20;
  864. this.$emit('aiHitEvent', _aiBloodPoint);
  865. this.aiShowCount = this.aiPowerCount; // parseInt(this.aiPowerCount / 10);
  866. if (this.aiShowCount >= this.maxShowCount) {
  867. this.$emit('gameOver', {
  868. myWin: false
  869. });
  870. this._PKOver();
  871. this.aiPowerCount = 0;
  872. this.aiShowCount = 0;
  873. this.myPowerCount = 0;
  874. this.myShowCount = 0;
  875. }
  876. },
  877. //根据加速度计算血量
  878. _onReducedBlood(acc) {
  879. let _ratio = acc > 30 ? 1 : acc / 30;
  880. // console.log("_ratio:", _ratio);
  881. if (_ratio > 0.9) {
  882. //大拳头
  883. return 3;
  884. } else if (_ratio > 0.7) {
  885. //中拳头
  886. return 2;
  887. } else {
  888. //小拳头
  889. return 1;
  890. }
  891. },
  892. onChangeMode() {
  893. //todo 切换模式时候,停止当前运行状态
  894. if (this.bControlRun) {
  895. uni.showToast({
  896. title: '先停止,再切换模式',
  897. mask: true,
  898. icon: 'none',
  899. duration: 2000,
  900. })
  901. return;
  902. }
  903. //当前的拳击力设置为0
  904. this.currentHitStrength = 0;
  905. let _name = 'pk模式';
  906. if (this.mode == 'pkMode') {
  907. this.mode = 'calorieMode';
  908. _name = '健身模式';
  909. } else if (this.mode == 'calorieMode') {
  910. this.mode = 'pkMode';
  911. _name = 'pk模式';
  912. }
  913. let _data = {
  914. mode: this.mode,
  915. name: _name
  916. }
  917. this.$emit('modeEvent', _data);
  918. }
  919. }
  920. }
  921. </script>
  922. <style>
  923. /* Loader Bar */
  924. .hit-vertical-container {
  925. position: absolute;
  926. top: -50rpx;
  927. left: 0;
  928. right: 0;
  929. display: flex;
  930. justify-content: space-between;
  931. /* border: 1rpx solid #000000; */
  932. pointer-events: none;
  933. }
  934. .hit-vertical-bar {
  935. display: flex;
  936. flex-direction: column-reverse;
  937. }
  938. .hit-vertical-child {
  939. /* position: relative; */
  940. width: 70rpx;
  941. height: 20rpx;
  942. margin: 14rpx 24rpx 0 24rpx;
  943. display: flex;
  944. /* align-content: center; */
  945. justify-content: space-between;
  946. }
  947. .hit-vertical-text {
  948. color: #FFFFFF;
  949. font-size: 8px;
  950. }
  951. .hit-text-hidden {
  952. visibility: hidden;
  953. }
  954. .hit-vertical-active {
  955. background-color: #FFFFFF;
  956. width: 30rpx;
  957. height: 100%;
  958. }
  959. .hit-vertical-inactive {
  960. width: 30rpx;
  961. height: 100%;
  962. background: rgba(144, 141, 246, 1);
  963. }
  964. .boxing-item-bg {
  965. border-radius: 15rpx;
  966. background-color: rgba(255, 255, 255, 0.1);
  967. display: flex;
  968. flex-direction: column;
  969. align-items: center;
  970. /* width: 160rpx; */
  971. }
  972. .hit-count {
  973. width: 160rpx;
  974. height: 60rpx;
  975. font-size: 22px;
  976. font-weight: bold;
  977. color: #FFFFFF;
  978. line-height: 60rpx;
  979. }
  980. .hit-current-count-power {
  981. /* margin: 0 5rpx; */
  982. font-size: 19px;
  983. line-height: 60rpx;
  984. /* font-weight: bold; */
  985. color: #FFFFFF;
  986. }
  987. .hit-current-count {
  988. /* width: 160rpx; */
  989. /* height: 100rpx; */
  990. margin: 0 30rpx;
  991. font-size: 22px;
  992. line-height: 60rpx;
  993. font-weight: bold;
  994. color: #FFFFFF;
  995. /* line-height: 22px; */
  996. }
  997. #loadbar {
  998. list-style: none;
  999. width: 400rpx;
  1000. margin: 0 20rpx;
  1001. }
  1002. #loadbar-child {
  1003. float: left;
  1004. position: relative;
  1005. width: 60rpx;
  1006. height: 10rpx;
  1007. margin-left: 1px;
  1008. background: rgba(255, 255, 255, 0.5);
  1009. }
  1010. #loadbar-child:first-child {
  1011. margin-left: 0;
  1012. }
  1013. .bar {
  1014. background-color: #FFFFFF;
  1015. width: 60rpx;
  1016. height: 10rpx;
  1017. }
  1018. .show-png {
  1019. width: 78rpx;
  1020. height: 78rpx;
  1021. margin: 0 10px;
  1022. }
  1023. .boxing-hit-png {
  1024. margin-top: 40rpx;
  1025. width: 50rpx;
  1026. height: 50rpx;
  1027. transition: transform 0.15s;
  1028. }
  1029. .boxing-change {
  1030. transform: scale(1.58);
  1031. }
  1032. .hitBoxingTimer {
  1033. position: absolute;
  1034. top: -60rpx;
  1035. left: 0;
  1036. right: 0;
  1037. }
  1038. .wave-item {
  1039. width: 8rpx;
  1040. height: 20rpx;
  1041. margin: 5rpx;
  1042. background-color: #FFFFFF;
  1043. border-radius: 10rpx;
  1044. transition: height 0.5s;
  1045. }
  1046. .wave-d-item {
  1047. width: 8rpx;
  1048. height: 20rpx;
  1049. margin: 5rpx;
  1050. background-color: #FFFFFF;
  1051. border-radius: 10rpx;
  1052. transition: height 0.5s;
  1053. }
  1054. .hit-wave {
  1055. animation: hit-d-scale calc(var(--time) * 0.5s) linear calc(var(--delay) * 1s) 1 alternate;
  1056. }
  1057. .wave-play {
  1058. animation-play-state: running;
  1059. }
  1060. .wave-pause {
  1061. animation-play-state: paused;
  1062. }
  1063. @keyframes hit-scale {
  1064. 0% {
  1065. transform: scale(1, 1);
  1066. /* background-color: #999; */
  1067. }
  1068. 100% {
  1069. transform: scale(1, 3);
  1070. /* background-color: #333; */
  1071. }
  1072. }
  1073. @keyframes hit-d-scale {
  1074. 0% {
  1075. transform: scale(1, 1);
  1076. }
  1077. 25% {
  1078. transform: scale(1, 3);
  1079. }
  1080. 50% {
  1081. transform: scale(1, 1);
  1082. }
  1083. 75% {
  1084. transform: scale(1, 3);
  1085. }
  1086. 100% {
  1087. transform: scale(1, 1);
  1088. }
  1089. }
  1090. .hit-button-rotate {
  1091. animation: hit-rotate 2s steps(16, end) infinite;
  1092. }
  1093. .hit-button-bg-play {
  1094. animation-play-state: running;
  1095. }
  1096. .hit-button-bg-paused {
  1097. animation-play-state: paused;
  1098. }
  1099. @keyframes hit-rotate {
  1100. from {
  1101. transform: rotate(0deg);
  1102. }
  1103. to {
  1104. transform: rotate(360deg);
  1105. }
  1106. }
  1107. .big {
  1108. transform: scale(1.2);
  1109. }
  1110. </style>