action-jump.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335
  1. <!-- 新版本跳区域部分文件 -->
  2. <template>
  3. <view style="width: 750rpx;">
  4. <view class="flex justify-center" style="margin-top: 68rpx;">
  5. <!-- 目前格子数量不代表数字,显示完成度而已 -460rpx;-->
  6. <view class="grid-progress-vertical-container" style="top:-376rpx;">
  7. <view class="grid-progress-vertical-bar">
  8. <view class="grid-progress-vertical-child" v-for="(item, index) in maxShowCount +1" :key="index"
  9. v-if="index!==0">
  10. <view
  11. :class="showCurCount>=index? 'grid-progress-vertical-active':'grid-progress-vertical-inactive'">
  12. </view>
  13. <view :class="(index%5 == 0||index == 1)?'':'grid-progress-text-hidden'"
  14. class="grid-progress-vertical-text" style="position: absolute;right: 0;top: -4px;">
  15. {{Math.floor(taskSignCount / 40 * index)}}
  16. </view>
  17. </view>
  18. </view>
  19. <view class="grid-progress-vertical-bar">
  20. <view class="grid-progress-vertical-child" v-for="(item, index) in maxShowCount +1" :key="index"
  21. v-if="index!==0">
  22. <view :class="(index%5 == 0||index == 1)?'':'grid-progress-text-hidden'"
  23. class="grid-progress-vertical-text" style="position: absolute;left: 0;top: -4px;">
  24. {{Math.floor(taskSignCount / 40 * index)+taskSignCount/2}}
  25. </view>
  26. <!-- 设置空位 -->
  27. <view></view>
  28. <view
  29. :class="showCurCount>=index+20? 'grid-progress-vertical-active':'grid-progress-vertical-inactive'">
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. <view class="position-relative">
  36. <image class="position-absolute-left-top" style="width: 86.12px;height:55.96px; left: 146rpx;top:-100rpx;"
  37. src="../../../static/modal/action-jump/progress-tip-add.png"></image>
  38. <canvas canvas-id="actionJumpCanvas" :style="{ width: canvasW + 'px', height: canvasH + 'px' }"></canvas>
  39. <canvas class="position-absolute-center" canvas-id="effectCanvas"
  40. :style="{ width: canvasW + 'px', height: '164px' }"></canvas>
  41. </view>
  42. <view class="flex align-center justify-center" style="font-size: 14px;">
  43. <view style="position: relative;">
  44. <image style="width: 135px;height: 75px;" src="../../../static/modal/action-jump/Fill.png"></image>
  45. <view class="mid-absolute flex flex-direction align-center justify-center text-white">
  46. <view class="flex align-center">
  47. <image style="width: 22rpx;height: 28rpx;"
  48. src="../../../static/modal/action-jump/jumpSpeed.png"></image>
  49. <view style="margin-left: 6rpx;">平均速度</view>
  50. </view>
  51. <view style="margin-top: 12rpx;">{{jumpSpeed}}</view>
  52. </view>
  53. </view>
  54. <view id="ActionJumpPlay" class="flex" style="position: relative;" @click="onControllerPlay">
  55. <image style="width: 110px;height: 110px;"
  56. src="../../../static/modal/action-jump/mid-button-orange@2x.png">
  57. </image>
  58. <image v-if="!bJumpPlay" class="mid-absolute" style="left:12rpx; width: 56rpx;height: 70rpx;"
  59. src="../../../static/play.png">
  60. </image>
  61. <image v-else class="mid-absolute" style="width: 100rpx;height: 100rpx;"
  62. src="../../../static/e-pause.png">
  63. </image>
  64. </view>
  65. <view style="position: relative;">
  66. <image style="width: 135px;height: 75px; transform: scaleX(-1);"
  67. src="../../../static/modal/action-jump/Fill.png"></image>
  68. <view class="mid-absolute flex flex-direction align-center justify-center text-white">
  69. <view class="flex align-center">
  70. <image style="width: 22rpx;height: 28rpx;"
  71. src="../../../static/modal/action-jump/jumpCalorie.png"></image>
  72. <view style="margin-left: 6rpx;">卡路里</view>
  73. </view>
  74. <view style="margin-top: 12rpx;">{{jumpCalorie}}</view>
  75. </view>
  76. </view>
  77. </view>
  78. <view class="flex align-center justify-center" style="width: 750rpx;">
  79. <view class="flex justify-center align-center" style="height: 120rpx; width: 444rpx; ">
  80. <view class="text-12px text-white text-center">
  81. {{taskDescribe}}
  82. </view>
  83. </view>
  84. </view>
  85. <!-- <view style="height: 41px;"></view> -->
  86. <!-- 测试按钮 -->
  87. <!-- <view style="display: flex;justify-content: space-between;">
  88. <view>{{isY?'Y':'X'}}</view>
  89. <button @click="onChangeY">Y为旋转轴</button>
  90. <button @click="onChangeX">X为旋转轴</button>
  91. </view> -->
  92. <!-- #ifdef H5 -->
  93. <view style="display: flex;justify-content: space-between;" class="margin-top margin-bottom">
  94. <button @click="onJumpType(0)">jump</button>
  95. <button @click="onJumpType(1)">left</button>
  96. <button @click="onJumpType(2)">right</button>
  97. <button @click="onJumpType(3)">rLeft</button>
  98. <button @click="onJumpType(4)">rRight</button>
  99. </view>
  100. <!-- #endif -->
  101. <!-- <view style="display: flex;justify-content: space-around; padding-bottom: 100rpx;">
  102. <view style="font-size: 14px;">t:{{countdown}}</view>
  103. <view style="font-size: 14px;">e:{{eliminationCount}}</view>
  104. <view style="font-size: 14px;">f:{{faultCount}}</view>
  105. </view> -->
  106. </view>
  107. </template>
  108. <script>
  109. import ActionJump from "@/util/util-js/action/jump-0.1.js"
  110. import {
  111. CONDITIONPASSED
  112. } from "@/util/util-js/enum.js"
  113. import Firework from "@/util/util-js/effect/firework.js"
  114. import {
  115. mapState,
  116. mapMutations
  117. } from 'vuex';
  118. export default {
  119. computed: mapState(['systemInfo']),
  120. components: {
  121. },
  122. props: {
  123. showTime: {
  124. type: Number,
  125. default: 0
  126. },
  127. levelData: {
  128. type: Object,
  129. default: null
  130. },
  131. currentMode: {
  132. type: String,
  133. default: ''
  134. }
  135. },
  136. data() {
  137. return {
  138. isY: true,
  139. canvasW: 0, // 画布宽
  140. canvasH: 0, // 画布高
  141. // SystemInfo: {}, // 设备信息
  142. directionJump: null,
  143. midJump: null,
  144. rotateJump: null,
  145. directionJumpWhite: null,
  146. midJumpWhite: null,
  147. rotateJumpWhite: null,
  148. //参考图片
  149. cankao: null,
  150. jumpTipImage: null,
  151. JumpTipOrange: null,
  152. jumpNormalImage: null,
  153. jumpNormalWidth: 70,
  154. jumpNormalHeight: 164,
  155. jumpProgressTip: null,
  156. jumpTypeArray: [{
  157. jumpName: 'NORMAL',
  158. jumpCode: 0,
  159. icon: 'midJump',
  160. scaleX: 1,
  161. bTrigger: false,
  162. bShow: true,
  163. }, {
  164. jumpName: 'LEFT',
  165. jumpCode: 1,
  166. icon: 'directionJump',
  167. scaleX: -1,
  168. bTrigger: false,
  169. bShow: true,
  170. }, {
  171. jumpName: 'RIGHT',
  172. jumpCode: 2,
  173. icon: 'directionJump',
  174. scaleX: 1,
  175. bTrigger: false,
  176. bShow: true,
  177. }, {
  178. jumpName: 'LEFT_ROTATE',
  179. jumpCode: 3,
  180. icon: 'rotateJump',
  181. scaleX: -1,
  182. bTrigger: false,
  183. bShow: true,
  184. }, {
  185. jumpName: 'RIGHT_ROTATE',
  186. jumpCode: 4,
  187. icon: 'rotateJump',
  188. scaleX: 1,
  189. bTrigger: false,
  190. bShow: true,
  191. }],
  192. spawnArray: [],
  193. /**
  194. * 生成的背景位置
  195. */
  196. spawnPos: [],
  197. //下一个生成是相反的方向
  198. bNextSpawnRightDirection: false,
  199. bNextSpawnRightRotateDirection: false,
  200. //生成预制的模板,用count 来判断生成哪一种
  201. template: [{ //原地
  202. count: 1,
  203. spawnList: [
  204. [0]
  205. ]
  206. }, {
  207. count: 2,
  208. spawnList: [
  209. [2, 1],
  210. [1, 2],
  211. [3, 4],
  212. [4, 3]
  213. ]
  214. }, {
  215. count: 3,
  216. spawnList: [
  217. [2, 0, 1],
  218. [1, 0, 2],
  219. [3, 0, 4],
  220. [4, 0, 3]
  221. ]
  222. }, ],
  223. //模板对象池,管理生成对象
  224. templatePool: [],
  225. levelType: 0,
  226. countdown: 60,
  227. countdownInterval: null,
  228. faultCount: 0,
  229. eliminationCount: 0,
  230. bJumpPlay: false,
  231. jumpCalorie: 1000,
  232. jumpSpeed: 1000,
  233. //硬件设备处理
  234. BLEAccIndex: 0,
  235. bJump: false,
  236. xA: 0,
  237. yA: 0,
  238. zA: 0,
  239. actionJumpObj: null,
  240. /**
  241. * 交互数据处理
  242. */
  243. //当前选择的关卡信息
  244. selfLevelData: null,
  245. // 双人模式下 数据
  246. //标记块数量
  247. taskSignCount: 0, //总数
  248. taskSignCurCount: 0, //当前计数
  249. //{"type":1,"explain":"规定时间内跳完所有标志块","limitType":1}
  250. taskConditionPassed: null,
  251. taskDescribe: '',
  252. //满格的数值是 25
  253. maxShowCount: 13,
  254. addShowCountUnit: 0,
  255. showCurCount: 0,
  256. roundingCount: 0,
  257. //游戏结束
  258. isGameOver: false,
  259. //pk模式下操作
  260. leftShowCurCount: 0,
  261. rightShowCurCount: 0,
  262. isleftPlayer: true,
  263. /**
  264. * 是否允许绘制
  265. */
  266. canOnDraw: false,
  267. /**
  268. * 是否去到下一个关卡
  269. */
  270. canGoNext: false,
  271. /**
  272. * 生成的特效
  273. */
  274. canSpawnTemp: null,
  275. onLogData: '',
  276. /**
  277. * 是否显示关卡提示
  278. */
  279. bTipLevel: false,
  280. /**
  281. * 烟花相关
  282. */
  283. // firework collection
  284. fireworks: [],
  285. fireworkImage: null,
  286. loop: null,
  287. count: 100,
  288. effectCanvas: null,
  289. effectCurrentSpawn: null,
  290. effectSpawnPosX: 0,
  291. /**
  292. * 烟花特效
  293. */
  294. bDrawBoomEffect: false
  295. }
  296. },
  297. watch: {
  298. levelData(val) {
  299. //更新数据
  300. // console.log("levelData ============>"+JSON.stringify(val));
  301. if (val) {
  302. this.taskSignCount = val.signCount;
  303. this.taskConditionPassed = val.conditionPassed;
  304. this.taskDescribe = val.describe;
  305. this.addShowCountUnit = (this.maxShowCount * 2) / this.taskSignCount;
  306. // console.log("this.addShowCountUnit:", this.addShowCountUnit, this.maxShowCount * 2, this
  307. // .taskSignCount);
  308. this.showCount = 0;
  309. //用signType 做等级类型
  310. this.levelType = val.signType;
  311. // console.log(JSON.stringify(this.taskConditionPassed));
  312. }
  313. },
  314. currentMode(val) {
  315. console.log('==========> action jump currentMode:', val);
  316. }
  317. },
  318. created() {
  319. let _self = this;
  320. this.actionJumpCanvas = uni.createCanvasContext("actionJumpCanvas", this);
  321. this.effectCanvas = uni.createCanvasContext("effectCanvas", this);
  322. // this.SystemInfo = this.systemInfo; // uni.getSystemInfoSync();
  323. this.canvasW = this.systemInfo.windowWidth; // 画布宽度
  324. this.canvasH = 147.68;
  325. this.onLoadImage();
  326. setTimeout(() => {
  327. this.onListenActionJump();
  328. }, 2000)
  329. //更新一次状态
  330. const value = uni.getStorageSync('levelButtonPrompt');
  331. if (value) {
  332. _self.bTipLevel = !value.isSelected;
  333. } else {
  334. _self.bTipLevel = true;
  335. }
  336. // console.log('==========>levelButtonPrompt:', _self.bTipLevel);
  337. },
  338. methods: {
  339. ...mapMutations(['onWriteBLEConnectionValue', 'onConvertDeviceData']),
  340. //更新新手状态提示
  341. onUpdateTipLevelValue(value) {
  342. this.bTipLevel = value;
  343. },
  344. onListenActionJump() {
  345. let _self = this;
  346. console.log("*****************onListenActionJump*****************************");
  347. _self.actionJumpObj = new ActionJump();
  348. _self.actionJumpObj.addEventListener('resultant', (e) => {
  349. if (e.type == 'jump') {
  350. // this.jumpCount++;
  351. this.bJump = true;
  352. } else if (e.type == 'stateDataOfJump') {
  353. //发送给game,在game里面处理判断
  354. this.listenStateDataOfJump(e);
  355. } else if (e.type == 'stop') {
  356. this.onClearData();
  357. this.actionJumpObj.resetAll();
  358. if (this.canOnDraw) {
  359. this.canOnDraw = false;
  360. // //这里更新特效
  361. // this.onDrawEffect(this.canSpawnTemp);
  362. this.onDraw("tipHit");
  363. }
  364. if (this.canGoNext) {
  365. this.canGoNext = false;
  366. // //这里更新特效
  367. // this.onDrawEffect(this.canSpawnTemp);
  368. //绘制新触发状态
  369. this.onDraw("normal");
  370. setTimeout(() => {
  371. this.startJumpGame();
  372. }, 500)
  373. }
  374. // console.log('stop');
  375. //这里处理生成下一个
  376. }
  377. })
  378. },
  379. //load 相关图片
  380. onLoadImage() {
  381. let _self = this;
  382. uni.getImageInfo({
  383. src: "../../../static/modal/action-jump/directionJump.png",
  384. success: function(image) {
  385. _self.directionJump = image;
  386. }
  387. });
  388. uni.getImageInfo({
  389. src: "../../../static/modal/action-jump/midJump.png",
  390. success: function(image) {
  391. _self.midJump = image;
  392. }
  393. });
  394. uni.getImageInfo({
  395. src: "../../../static/modal/action-jump/rotateJump.png",
  396. success: function(image) {
  397. _self.rotateJump = image;
  398. }
  399. });
  400. uni.getImageInfo({
  401. src: "../../../static/modal/action-jump/directionJumpWhite.png",
  402. success: function(image) {
  403. _self.directionJumpWhite = image;
  404. }
  405. });
  406. uni.getImageInfo({
  407. src: "../../../static/modal/action-jump/midJumpWhite.png",
  408. success: function(image) {
  409. _self.midJumpWhite = image;
  410. }
  411. });
  412. uni.getImageInfo({
  413. src: "../../../static/modal/action-jump/rotateJumpWhite.png",
  414. success: function(image) {
  415. _self.rotateJumpWhite = image;
  416. }
  417. });
  418. uni.getImageInfo({
  419. src: "../../../static/modal/action-jump/jumpTip.png",
  420. success: function(image) {
  421. _self.jumpTipImage = image;
  422. }
  423. });
  424. uni.getImageInfo({
  425. src: "../../../static/modal/action-jump/jump-tip-orange@2x.png",
  426. success: function(image) {
  427. _self.JumpTipOrange = image;
  428. }
  429. })
  430. uni.getImageInfo({
  431. src: "../../../static/modal/action-jump/progress-tip.png",
  432. success: function(image) {
  433. _self.jumpProgressTip = image;
  434. }
  435. })
  436. uni.getImageInfo({
  437. src: "../../../static/modal/action-jump/jumpNormal.png",
  438. success: function(image) {
  439. _self.jumpNormalImage = image;
  440. _self.onDrawBg(true);
  441. }
  442. });
  443. uni.getImageInfo({
  444. src: "../../../static/modal/action-jump/cankao.png",
  445. success: function(image) {
  446. _self.cankao = image;
  447. }
  448. });
  449. /**
  450. * 烟花照片
  451. */
  452. uni.getImageInfo({
  453. src: "../../../static/modal/action-jump/boom.png",
  454. success: function(image) {
  455. _self.fireworkImage = image;
  456. }
  457. });
  458. },
  459. /**
  460. * 重置生成数组,重置倒计时
  461. */
  462. resetJumpGame() {
  463. this.spawnArray = [];
  464. this.templatePool = [];
  465. if (this.countdownInterval) {
  466. clearInterval(this.countdownInterval);
  467. this.countdownInterval = null;
  468. }
  469. // this.resetCountdown(60);
  470. },
  471. startJumpGame() {
  472. this.isGameOver = false;
  473. this.resetJumpGame();
  474. //开始游戏
  475. this.index = 0;
  476. // this.levelType = 5;
  477. let _ranType = Math.floor(Math.random() * 2);
  478. if (this.levelType == 0) {
  479. //随便生成一组跳的数据
  480. let _spawnList = this.template[0].spawnList;
  481. for (let i = 0; i < 31; i++) {
  482. //再对象池里面生成一组对象
  483. this.addTemplatePoolFromType(0 !== i, _spawnList[0][0]);
  484. }
  485. //先生成4个
  486. for (let i = 0; i < 5; i++) {
  487. this.spawnArray.push(this.templatePool[this.index]);
  488. this.index++;
  489. }
  490. } else if (this.levelType == 1) {
  491. //生成一个占位
  492. this.addTemplatePoolFromType(false, this.template[0].spawnList[0][0]);
  493. //生成一组 左跳右跳
  494. let _spawnList = this.template[1].spawnList;
  495. for (let i = 0; i < 30; i++) {
  496. let ran = Math.floor(Math.random() * 2);
  497. for (let j = 0; j < _spawnList[ran].length; j++) {
  498. //再对象池里面生成一组对象
  499. this.addTemplatePoolFromType(true, _spawnList[ran][j]);
  500. }
  501. }
  502. //先生成5个
  503. for (let i = 0; i < 5; i++) {
  504. this.spawnArray.push(this.templatePool[this.index]);
  505. this.index++;
  506. }
  507. } else if (this.levelType == 2) {
  508. //生成一个占位
  509. this.addTemplatePoolFromType(false, this.template[0].spawnList[0][0]);
  510. //生成一组 左跳右跳原地
  511. let _spawnList = this.template[2].spawnList;
  512. for (let i = 0; i < 30; i++) {
  513. let ran = Math.floor(Math.random() * 2);
  514. for (let j = 0; j < _spawnList[ran].length; j++) {
  515. //再对象池里面生成一组对象
  516. this.addTemplatePoolFromType(true, _spawnList[ran][j]);
  517. }
  518. }
  519. //先生成5个
  520. for (let i = 0; i < 5; i++) {
  521. this.spawnArray.push(this.templatePool[this.index]);
  522. this.index++;
  523. }
  524. } else if (this.levelType == 3) {
  525. //生成一个占位
  526. this.addTemplatePoolFromType(false, this.template[0].spawnList[0][0]);
  527. //生成一组 左旋跳右旋跳
  528. let _spawnList = this.template[1].spawnList;
  529. for (let i = 0; i < 30; i++) {
  530. let ran = Math.floor(Math.random() * 2) + 2;
  531. for (let j = 0; j < _spawnList[ran].length; j++) {
  532. //再对象池里面生成一组对象
  533. this.addTemplatePoolFromType(true, _spawnList[ran][j]);
  534. }
  535. }
  536. //先生成5个
  537. for (let i = 0; i < 30; i++) {
  538. this.spawnArray.push(this.templatePool[this.index]);
  539. this.index++;
  540. }
  541. } else if (this.levelType == 4) {
  542. //生成一个占位
  543. this.addTemplatePoolFromType(false, this.template[0].spawnList[0][0]);
  544. //生成一组 左旋跳右旋跳
  545. let _spawnList = this.template[2].spawnList;
  546. for (let i = 0; i < 30; i++) {
  547. let ran = Math.floor(Math.random() * 2) + 2;
  548. for (let j = 0; j < _spawnList[ran].length; j++) {
  549. //再对象池里面生成一组对象
  550. this.addTemplatePoolFromType(true, _spawnList[ran][j]);
  551. }
  552. }
  553. //先生成5个
  554. for (let i = 0; i < 5; i++) {
  555. this.spawnArray.push(this.templatePool[this.index]);
  556. this.index++;
  557. }
  558. } else if (this.levelType == 5) {
  559. //生成一个占位
  560. this.addTemplatePoolFromType(false, this.template[0].spawnList[0][0]);
  561. for (let i = 0; i < 20; i++) {
  562. //随便生成三组数据
  563. let _newArray = [];
  564. let _spawnList2 = this.template[2].spawnList;
  565. let ran2 = Math.floor(Math.random() * 2);
  566. let ran3 = Math.floor(Math.random() * 2);
  567. if (_ranType >= 1) {
  568. ran2 += 2;
  569. ran3 += 2;
  570. }
  571. _newArray = _newArray.concat(_spawnList2[ran2]);
  572. _newArray = _newArray.concat(_spawnList2[ran3]);
  573. for (let j = 0; j < _newArray.length; j++) {
  574. this.addTemplatePoolFromType(true, _newArray[j]);
  575. }
  576. }
  577. //先生成5个
  578. for (let i = 0; i < 5; i++) {
  579. this.spawnArray.push(this.templatePool[this.index]);
  580. this.index++;
  581. }
  582. }
  583. this.onDraw("tipHit");
  584. },
  585. addTemplatePoolFromType(bShow, _jumpType) {
  586. for (let i = 0; i < this.jumpTypeArray.length; i++) {
  587. if (this.jumpTypeArray[i].jumpCode == _jumpType) {
  588. let _jumpPrefab = Object.assign({}, this.jumpTypeArray[i], {
  589. bShow: bShow
  590. });
  591. this.templatePool.push(_jumpPrefab);
  592. break;
  593. }
  594. }
  595. },
  596. //单纯的绘制八个背景
  597. onDrawBg(bDraw) {
  598. this.spawnPos = [];
  599. if (bDraw) {
  600. this.actionJumpCanvas.clearRect(0, 0, this.canvasW, this.canvasH);
  601. }
  602. let _currentBgStartX = this.canvasW / 2;
  603. let count = 5;
  604. let _currentPos = -12,
  605. _addPos = 0;
  606. this.actionJumpCanvas.drawImage(this.jumpProgressTip.path, _currentBgStartX, 5, 171, 24.66);
  607. this.actionJumpCanvas.drawImage(this.jumpProgressTip.path, _currentBgStartX, 116, 171, 24.66);
  608. for (let i = 0; i < count; i++) {
  609. if (0 !== i) {
  610. _currentPos += this.jumpNormalWidth;
  611. }
  612. if (1 === i) {
  613. this.actionJumpCanvas.drawImage(this.jumpTipImage.path, _currentPos, 0, 120, this.canvasH);
  614. this.actionJumpCanvas.drawImage(this.JumpTipOrange.path, _currentPos + 3, 7, 113, this.canvasH -
  615. 14);
  616. // this.actionJumpCanvas.drawImage(this.midJump.path, _currentPos + 30, 46, 60, 60);
  617. //添加对应生成点
  618. this.spawnPos.push({
  619. center: _currentPos + 30
  620. })
  621. _currentPos += 50;
  622. } else {
  623. this.actionJumpCanvas.drawImage(this.jumpNormalImage.path, _currentPos, 0, this.jumpNormalWidth,
  624. this.canvasH);
  625. // this.actionJumpCanvas.drawImage(this.midJump.path, _currentPos + 16, 55, 40, 40);
  626. //添加对应生成点
  627. this.spawnPos.push({
  628. center: _currentPos + 16
  629. })
  630. }
  631. }
  632. if (bDraw) {
  633. this.actionJumpCanvas.draw();
  634. }
  635. },
  636. onDraw(type) {
  637. this.actionJumpCanvas.clearRect(0, 0, this.canvasW, this.canvasH);
  638. //单纯绘制背景
  639. this.onDrawBg(false);
  640. //计算一个节点数组
  641. for (let i = 0; i < this.spawnArray.length; i++) {
  642. //默认 mid 图标
  643. let _temp = this.spawnArray[i].bTrigger ? this.midJump : this.midJumpWhite;
  644. if (this.spawnArray[i].icon == 'directionJump') {
  645. _temp = this.spawnArray[i].bTrigger ? this.directionJump : this.directionJumpWhite;
  646. } else if (this.spawnArray[i].icon == 'rotateJump') {
  647. _temp = this.spawnArray[i].bTrigger ? this.rotateJump : this.rotateJumpWhite;
  648. }
  649. //如果是相反绘制,需要加多一个自身位置偏移
  650. let _pos = this.spawnArray[i].scaleX < 0 ? i + 1 : 0;
  651. this.actionJumpCanvas.save();
  652. let _opacity = this.spawnArray[i].bTrigger ? 0.7 : 1;
  653. console.log(this.spawnArray[i].bTrigger + '==' + _opacity);
  654. this.actionJumpCanvas.globalAlpha = this.spawnArray[i].bShow ? _opacity : 0;
  655. this.actionJumpCanvas.scale(this.spawnArray[i].scaleX, 1);
  656. let _currentPos = this.spawnPos[i].center;
  657. let _currentCenterPos = 0;
  658. if (i == 1) {
  659. if (this.spawnArray[i].scaleX < 0) {
  660. _currentPos = (_currentPos * 2 - 30) * this.spawnArray[i].scaleX;
  661. //这里记录一个生成点,后面用于生成特效
  662. this.effectSpawnPosX = _currentPos - 30;
  663. } else {
  664. //这里记录一个生成点,后面用于生成特效
  665. this.effectSpawnPosX = _currentPos;
  666. }
  667. //大图
  668. this.actionJumpCanvas.drawImage(_temp.path, _currentPos, 46, 60, 60);
  669. // console.log('big:' + _currentPos);
  670. } else {
  671. //小图
  672. if (this.spawnArray[i].scaleX < 0) {
  673. _currentPos = (_currentPos + 40) * this.spawnArray[i].scaleX
  674. console.log('min:' + _currentPos);
  675. }
  676. this.actionJumpCanvas.drawImage(_temp.path, _currentPos, 55, 40, 40);
  677. }
  678. this.actionJumpCanvas.restore();
  679. }
  680. this.actionJumpCanvas.draw();
  681. },
  682. onDrawEffect(_temp) {
  683. //根据当前消除的生成一个
  684. // console.log("生成的_temp:" + JSON.stringify(_temp));
  685. let spawnTemp = this.midJump;
  686. if (_temp.icon == 'directionJump') {
  687. spawnTemp = this.directionJump;
  688. } else if (_temp.icon == 'rotateJump') {
  689. spawnTemp = this.rotateJump;
  690. }
  691. let tempFirework = new Firework(this.fireworkImage,
  692. spawnTemp, _temp.scaleX, this.effectSpawnPosX, 0, this.canvasW, 164);
  693. this.fireworks.push(tempFirework);
  694. this.bDrawBoomEffect = true;
  695. this.onInitFirework();
  696. },
  697. onClear() {
  698. this.resetJumpGame();
  699. this.onDrawBg(true);
  700. this.xA = 0;
  701. this.yA = 0;
  702. this.zA = 0;
  703. this.bJump = false;
  704. this.actionJumpObj.resetAll();
  705. },
  706. /**
  707. * 统一绘制 效果 背景,交互,烟花
  708. */
  709. onInitFirework() {
  710. if (this.loop != null) {
  711. return;
  712. }
  713. this.loop = setInterval(() => {
  714. if (!this.bDrawBoomEffect) {
  715. clearInterval(this.loop);
  716. this.loop = null;
  717. // console.log("结束绘制");
  718. this.effectCanvas.clearRect(0, 0, this.canvasW, 164);
  719. this.effectCanvas.draw();
  720. return;
  721. }
  722. this.effectCanvas.clearRect(0, 0, this.canvasW, 164);
  723. if (this.bDrawBoomEffect) {
  724. // loop over each firework, draw it, update it
  725. var i = this.fireworks.length;
  726. while (i--) {
  727. this.fireworks[i].draw(this.effectCanvas, () => {
  728. this.fireworks.splice(i, 1);
  729. if (this.fireworks.length == 0) {
  730. this.bDrawBoomEffect = false;
  731. }
  732. });
  733. }
  734. }
  735. this.effectCanvas.draw();
  736. }, 30)
  737. },
  738. onJumpType(event) {
  739. // console.log("onJumpType:", event);
  740. if (this.isGameOver || !this.bJumpPlay) return;
  741. this.eliminateJumpPrefab(event);
  742. },
  743. // update (dt) {}
  744. //模拟测试调用
  745. eliminateJumpPrefab(_jumpType) {
  746. //只触发第二个
  747. if (this.spawnArray.length < 2) {
  748. return;
  749. }
  750. let _temp = this.spawnArray[1];
  751. //如果当前的跳类型和预制目标一样
  752. if (_jumpType == _temp.jumpCode) {
  753. _temp.bTrigger = true;
  754. this.spawnArray.splice(0, 1);
  755. if (this.index < this.templatePool.length) {
  756. this.spawnArray.push(this.templatePool[this.index]);
  757. this.index++;
  758. }
  759. //这里更新特效
  760. let _endTemp = Object.assign({}, _temp);
  761. this.onDrawEffect(_endTemp);
  762. //绘制新触发状态
  763. this.onDraw('tipHit');
  764. //成功
  765. this.setEliminationCount(1);
  766. //替换数组
  767. // console.log(this.index + " == " + this.spawnArray.length);
  768. if (this.spawnArray.length < 2 && this.index > 2) {
  769. clearInterval(this.countdownInterval);
  770. this.countdownInterval = null;
  771. //绘制新触发状态
  772. this.onDraw("normal");
  773. setTimeout(() => {
  774. this.startJumpGame();
  775. }, 2000)
  776. }
  777. } else {
  778. //失误
  779. this.setFaultCount(1);
  780. }
  781. },
  782. //设置倒计时
  783. setCountdown(value) {
  784. this.countdown -= value;
  785. // this.countdownLabel.string = '倒计时:' + this.countdown;
  786. this.$emit('actionJumpCountDownUpdate', {
  787. countDown: this.countdown
  788. });
  789. },
  790. resetCountdown(value) {
  791. this.countdown = value;
  792. // this.countdownLabel.string = '倒计时:' + this.countdown;
  793. this.$emit('actionJumpCountDownUpdate', {
  794. countDown: this.countdown
  795. });
  796. },
  797. //设置ui信息
  798. setEliminationCount(value) {
  799. this.taskSignCurCount++;
  800. this.roundingCount += this.addShowCountUnit;
  801. this.eliminationCount += value;
  802. // this.eliminationLabel.string = '消除数量:' + this.eliminationCount.toString();
  803. this.$emit('actionJumpDataUpdate', {
  804. eliminationCount: this.eliminationCount,
  805. faultCount: this.faultCount
  806. });
  807. //如果是pk模式。不走下面判断
  808. if (this.currentMode == 'pkMode') return;
  809. if (CONDITIONPASSED.ENERGYBARFULL == this.taskConditionPassed.limitType) {
  810. //能量条的条件下才显示能量条动
  811. //取两位后计算Math floor,不然会有偏差值问题 Math.floor(39.9999999+ 0.1111111) = 39
  812. this.showCurCount = Math.floor(this.roundingCount.toFixed(2));
  813. //1.能量槽满的时候,说明踩中次数到达
  814. if (this.taskSignCurCount >= this.taskSignCount)
  815. this.onGameOver("energyBarFull");
  816. } else if (CONDITIONPASSED.SKIPALLFLAGWITHINTIME == this.taskConditionPassed.limitType) {
  817. //规定时间下也给显示能量条
  818. this.showCurCount = Math.floor(this.roundingCount.toFixed(2));
  819. //2.规定时间内跳完所有标志块
  820. if (this.taskSignCurCount >= this.taskSignCount)
  821. this.onGameOver("skipAllFlagWithinTime");
  822. } else if (this.taskConditionPassed.isScore) {
  823. //3.达到一定分数
  824. //如果是用分数判断
  825. //分数是 跳对的加1分,错的扣1分,0不扣分。
  826. let curScore = this.eliminationCount - this.faultCount;
  827. curScore = curScore < 0 ? 0 : curScore;
  828. //当前分数达到,胜利
  829. if (curScore >= this.taskConditionPassed.limitScore)
  830. this.onGameOver("score");
  831. }
  832. },
  833. onGameOver(type) {
  834. this.isGameOver = true;
  835. //处理参数
  836. this.onClear();
  837. this.onClearData();
  838. this.bJumpPlay = false;
  839. /**
  840. * 判断胜利和失败
  841. */
  842. let myWin = false; //默认失败
  843. //比如, 1.充满左右两边蓄能槽.2.规定时间内跳完所有标志块.
  844. if (type == "energyBarFull") {
  845. //1.能量槽满的时候,说明踩中次数到达
  846. if (this.taskSignCurCount >= this.taskSignCount) {
  847. myWin = true;
  848. }
  849. } else if (type == 'skipAllFlagWithinTime') {
  850. myWin = true;
  851. } else if (type == "timeUp") {
  852. //2.规定时间内跳完所有标志块
  853. //查看消除数量是否到达总数,未达成就是未完成
  854. if (this.taskSignCurCount >= this.taskSignCount) {
  855. myWin = true;
  856. }
  857. } else if (type == "score") {
  858. myWin = true;
  859. }
  860. console.log(type, {
  861. myWin: myWin
  862. });
  863. this.$emit('gameOver', {
  864. myWin: myWin,
  865. type: 'calorieMode',
  866. isOffEvent: true
  867. });
  868. },
  869. //pk模式下结束游戏关卡
  870. onPKModeGameOver(type) {
  871. this.isGameOver = true;
  872. //处理参数
  873. this.onClear();
  874. this.onClearData();
  875. this.bJumpPlay = false;
  876. this.$emit('gameOver', {
  877. type: 'pkMode',
  878. isOffEvent: true
  879. });
  880. },
  881. setFaultCount(value) {
  882. this.faultCount += value;
  883. // this.faultLabel.string = '失误:' + this.faultCount;
  884. this.$emit('actionJumpDataUpdate', {
  885. eliminationCount: this.eliminationCount,
  886. faultCount: this.faultCount
  887. });
  888. },
  889. //控制播放
  890. onControllerPlay() {
  891. if (this.bJumpPlay) {
  892. //仅仅暂停,没有清空数据
  893. this._changePlay(false);
  894. this.$emit("actionJumpControllerPlay", false);
  895. } else {
  896. this.$emit("actionJumpCheck");
  897. }
  898. },
  899. onContinueGame() {
  900. this._changePlay(true);
  901. },
  902. onClearActionJumpData() {
  903. console.log("onClearActionJumpData");
  904. this.onClear();
  905. this.onClearData();
  906. },
  907. //修改状态
  908. _changePlay(bPlaying) {
  909. if (bPlaying) {
  910. this.bJumpPlay = bPlaying;
  911. } else {
  912. this.bJumpPlay = !this.bJumpPlay;
  913. }
  914. },
  915. onActionJumpPlay() {
  916. this.onClear();
  917. this.onClearData();
  918. this.startJumpGame();
  919. this._changePlay(true);
  920. //reset 对应计算数据
  921. this.taskSignCurCount = 0;
  922. this.showCurCount = 0;
  923. this.roundingCount = 0;
  924. this.faultCount = 0;
  925. this.eliminationCount = 0;
  926. },
  927. getCurrentJumpType() {
  928. let _temp = this.spawnArray[1];
  929. return _temp.jumpCode;
  930. },
  931. //监听跳的状态数据
  932. listenStateDataOfJump(data) {
  933. if (this.isGameOver || !this.bJumpPlay) return;
  934. if (this.spawnArray.length < 2) return;
  935. let _jumpType = this.getCurrentJumpType();
  936. //初始全部默认状态
  937. let _tempState = [{
  938. jumpName: 'NORMAL',
  939. jumpCode: 0,
  940. bTrigger: true,
  941. describe: '正常跳'
  942. },
  943. {
  944. jumpName: 'LEFT',
  945. jumpCode: 1,
  946. bTrigger: false,
  947. describe: '左直跳'
  948. },
  949. {
  950. jumpName: 'RIGHT',
  951. jumpCode: 2,
  952. bTrigger: false,
  953. describe: '右直跳'
  954. },
  955. {
  956. jumpName: 'LEFT_ROTATE',
  957. jumpCode: 3,
  958. bTrigger: false,
  959. describe: '左旋转跳'
  960. },
  961. {
  962. jumpName: 'RIGHT_ROTATE',
  963. jumpCode: 4,
  964. bTrigger: false,
  965. describe: '右旋转跳'
  966. }
  967. ];
  968. let {
  969. currentMaxValue,
  970. oGyroValue,
  971. peakOfWaveMaxValue,
  972. valleyOfWaveMinValue
  973. } = data
  974. // console.log('stateDataOfJump:');
  975. // console.log(JSON.stringify(data));
  976. this.onLogData = data;
  977. let _rotateLimit = 4;
  978. let _jumpLimit = 8;
  979. switch (_jumpType) {
  980. case 0:
  981. //JumpType.NORMAL = 0
  982. _tempState[0].bTrigger = true;
  983. this.eliminateJumpPrefabFormTemp(_tempState);
  984. break;
  985. case 1:
  986. if (currentMaxValue < -_jumpLimit || valleyOfWaveMinValue < -20) {
  987. //left jump
  988. _tempState[1].bTrigger = true;
  989. }
  990. this.eliminateJumpPrefabFormTemp(_tempState);
  991. break;
  992. case 2:
  993. if (currentMaxValue > _jumpLimit || peakOfWaveMaxValue > 20) {
  994. //right jump
  995. _tempState[2].bTrigger = true;
  996. }
  997. this.eliminateJumpPrefabFormTemp(_tempState);
  998. break;
  999. case 4:
  1000. if (oGyroValue > _rotateLimit) {
  1001. _tempState[4].bTrigger = true;
  1002. }
  1003. this.eliminateJumpPrefabFormTemp(_tempState);
  1004. break;
  1005. case 3:
  1006. if (oGyroValue < -_rotateLimit) {
  1007. _tempState[3].bTrigger = true;
  1008. }
  1009. this.eliminateJumpPrefabFormTemp(_tempState);
  1010. break;
  1011. default:
  1012. console.log('没有对应的_jumpType', _jumpType);
  1013. break;
  1014. }
  1015. // if (currentMaxValue == 0) {
  1016. // } else {
  1017. // // console.log('2====', data);
  1018. // if (this.isY) {
  1019. // //如果是检测到旋转跳
  1020. // if (oGyroValue > _rotateLimit) {
  1021. // // console.log('y right:', oGyroValue);
  1022. // _tempState[4].bTrigger = true;
  1023. // } else if (oGyroValue < -_rotateLimit) {
  1024. // // console.log('y left:', oGyroValue);
  1025. // _tempState[3].bTrigger = true;
  1026. // }
  1027. // if (valleyOfWaveMinValue < -_jumpLimit) {
  1028. // //left jump
  1029. // _tempState[1].bTrigger = true;
  1030. // } else if (peakOfWaveMaxValue > _jumpLimit) {
  1031. // //right jump
  1032. // _tempState[2].bTrigger = true;
  1033. // }
  1034. // } else {
  1035. // //如果是检测到旋转跳
  1036. // if (oGyroValue < -5) {
  1037. // // console.log('x right:', oGyroValue);
  1038. // _tempState[4].bTrigger = true;
  1039. // } else if (oGyroValue > 5) {
  1040. // // console.log('x left:', oGyroValue);
  1041. // _tempState[3].bTrigger = true;
  1042. // }
  1043. // if (valleyOfWaveMinValue < -_jumpLimit) {
  1044. // //left jump
  1045. // _tempState[1].bTrigger = true;
  1046. // } else if (peakOfWaveMaxValue > _jumpLimit) {
  1047. // //right jump
  1048. // _tempState[2].bTrigger = true;
  1049. // }
  1050. // }
  1051. // this.eliminateJumpPrefabFormTemp(_tempState);
  1052. // }
  1053. },
  1054. eliminateJumpPrefabFormTemp(_tempState) {
  1055. //只触发第二个
  1056. if (this.spawnArray.length < 2) {
  1057. return;
  1058. }
  1059. let _temp = this.spawnArray[1];
  1060. let bSuccess = false;
  1061. for (let i = 0; i < _tempState.length; i++) {
  1062. let _state = _tempState[i];
  1063. if (_state.bTrigger)
  1064. console.log(JSON.stringify(_state) + JSON.stringify(this.onLogData));
  1065. //如果当前的跳类型和预制目标一样
  1066. if (_state.jumpCode == _temp.jumpCode && _state.bTrigger) {
  1067. //成功
  1068. bSuccess = true;
  1069. break;
  1070. }
  1071. }
  1072. //如果存在其中一个为true
  1073. if (bSuccess) {
  1074. _temp.bTrigger = true;
  1075. this.canSpawnTemp = _temp;
  1076. setTimeout(() => {
  1077. //这里更新特效
  1078. this.onDrawEffect(this.canSpawnTemp);
  1079. }, 150);
  1080. this.spawnArray.splice(0, 1);
  1081. if (this.index < this.templatePool.length) {
  1082. this.spawnArray.push(this.templatePool[this.index]);
  1083. this.index++;
  1084. }
  1085. //成功
  1086. this.setEliminationCount(1);
  1087. //替换数组
  1088. // console.log(this.index + " == " + this.spawnArray.length);
  1089. if (this.spawnArray.length < 2 && this.index > 2) {
  1090. clearInterval(this.countdownInterval);
  1091. this.countdownInterval = null;
  1092. //绘制新触发状态
  1093. this.canGoNext = true;
  1094. }else {
  1095. //绘制新触发状态
  1096. this.canOnDraw = true;
  1097. }
  1098. } else {
  1099. //失误
  1100. this.setFaultCount(1);
  1101. }
  1102. },
  1103. /**
  1104. * @param {Object} gameData
  1105. * 识别跳部分数据处理
  1106. */
  1107. onBLERopeUpdate(gameData) {
  1108. if (!this.bJumpPlay || this.isGameOver) return;
  1109. //********陀螺仪角速度********
  1110. let {
  1111. gx,
  1112. gy,
  1113. gz
  1114. } = gameData.gyro;
  1115. let {
  1116. min,
  1117. s,
  1118. ms
  1119. } = gameData;
  1120. //-gameData.acc.ax * 10;
  1121. let _ax = gameData.acc.ax * 10;
  1122. let _ay = gameData.acc.ay * 10;
  1123. let _az = gameData.acc.az * 10;
  1124. //低通滤波分离重力
  1125. let alpha = 0.8;
  1126. this.xA = alpha * this.xA + (1 - alpha) * _ax;
  1127. this.yA = alpha * this.yA + (1 - alpha) * _ay;
  1128. this.zA = alpha * this.zA + (1 - alpha) * _az;
  1129. //高通滤波获取线性速度
  1130. let linear_acceleration_x = _ax - this.xA;
  1131. let linear_acceleration_y = _az - this.zA;
  1132. let linear_acceleration_z = _ay - this.yA;
  1133. let _temp = {
  1134. linearAcc: {
  1135. lAccX: linear_acceleration_x,
  1136. lAccY: linear_acceleration_y,
  1137. lAccZ: linear_acceleration_z
  1138. }, //gameData.acc,
  1139. oriAcc: {
  1140. oAccX: _ax,
  1141. oAccY: _ay,
  1142. oAccZ: _az
  1143. },
  1144. gravityAcc: {
  1145. gravityX: this.xA,
  1146. gravityY: this.yA,
  1147. gravityZ: this.zA
  1148. },
  1149. bLimitRebound: false,
  1150. resultant: Math.sqrt(_ax * _ax +
  1151. _ay * _ay + _az * _az),
  1152. runIndex: this.BLEAccIndex,
  1153. //陀螺仪
  1154. oriGyro: {
  1155. oGyroX: gx,
  1156. oGyroY: gy,
  1157. oGyroZ: gz
  1158. },
  1159. //输入当前轴
  1160. bYAxis: true,
  1161. };
  1162. this.actionJumpObj.updateJump(_temp);
  1163. // if (this.BLEAccIndex > 150) {
  1164. // this.onClearData();
  1165. // this.bJump = false;
  1166. // return;
  1167. // }
  1168. this.BLEAccIndex++;
  1169. },
  1170. onClearData() {
  1171. this.BLEAccIndex = 0;
  1172. },
  1173. onChangeY() {
  1174. this.isY = true;
  1175. },
  1176. onChangeX() {
  1177. this.isY = false;
  1178. },
  1179. onGetActionJumpPlayView(callback) {
  1180. let view = uni.createSelectorQuery().select('#ActionJumpPlay');
  1181. view.boundingClientRect(data => {
  1182. if (callback)
  1183. callback(data);
  1184. }).exec();
  1185. },
  1186. onTipLevel() {
  1187. this.$emit("tipLevel", {
  1188. hiddenType: 'normal'
  1189. });
  1190. console.log("**************22");
  1191. }
  1192. }
  1193. }
  1194. </script>
  1195. <style lang="scss">
  1196. .mid-absolute {
  1197. position: absolute;
  1198. top: 0;
  1199. bottom: 0;
  1200. right: 0;
  1201. left: 0;
  1202. margin: auto;
  1203. }
  1204. .action-jump-timer {
  1205. position: absolute;
  1206. top: -150rpx;
  1207. }
  1208. .grid-progress-vertical-container {
  1209. min-height: 376rpx;
  1210. }
  1211. .grid-progress-vertical-bar {
  1212. max-height: 376rpx;
  1213. }
  1214. .grid-progress-vertical-child {
  1215. width: 35px;
  1216. height: 7.36px;
  1217. margin: 7.36px 0 0 0;
  1218. position: relative;
  1219. }
  1220. .grid-progress-vertical-active {
  1221. width: 28rpx;
  1222. }
  1223. .grid-progress-vertical-inactive {
  1224. width: 28rpx;
  1225. }
  1226. </style>