之前做过一个算法题,算法哀求便是写一个愉快消消乐的逻辑算法,当时也是考虑了一段韶光才做出来。
后来想了想,既然核心算法都有了,能不能实现一个愉快消消乐的小游戏呢,于是花了两天韶光做了一个小游戏出来。

效果展示#

先在这里放一个终极实现的效果,还是一个比较低级的版本,大家有什么想法欢迎评论哦

游戏规则:

消消乐php源码教你用Vue写一个高兴消消乐附源码 React

初始时会给玩家十分的初始分,每拖动一次就减一分,每肃清一个方块就加一分,直到末了分数为0游戏结束任意两个方块都可以拖动界面设计#

页面的布局比较大略,格子的数据是一个二维数组的形式,说到这里大家该当已经明白界面是怎么做的了。

<div v-for=\"大众(item, index) in squareData\"大众 :key=\"大众index\"大众 class=\公众row\公众> <div v-for=\"大众(_item, _index) in item\"大众 :key=\公众_index\"大众 class=\"大众square\公众 :class=\"大众_item\公众 @mousedown=\"大众dragStart(index, _index)\公众 @mouseup=\"大众dragEnd\"大众> {{_item}} </div></div>

大家该当把稳到了 :class=\"大众_item\"大众 的写法,动态命名class,使得其每个种类的方块的颜色都不同,末了可以按照同色肃清的玩法就行操作。

.square.A{ background-color: #8D98CA;}.square.S{ background-color: #A9A2F6;}/别的操作相同/

同时在玩家点击方块的时候方块会旁边摆动以表示选中了此方块,还可以提升游戏的灵动性。
关于HTML动画的实现办法有很多,在这里我们利用CSS animation进行操作,代码如下:

@keyframes jitter { from, 50%, to { transform: rotate(0deg); } 10%, 30% { transform: rotate(10deg); } 20% { transform: rotate(20deg); } 60%, 80% { transform: rotate(-10deg); } 70% { transform: rotate(-20deg); }}/ 只假如用户点击不动,动画就不会停滞 /.square:active{ animation-name: jitter; animation-duration: 0.5s; animation-iteration-count: infinite;}核心算法#

肃清算法

上面提到我之前是做过一道题是判断一个二维数组中有没有可消的元素,有的话是多少个。

在这里我们可以这样想,最开始遍历一全体二维数组,每次定义一个 X0 , X1 , Y0, Y1, 然后每次打算其高下旁边连续相同方块的位置,在这个过程中要把稳边界问题,然后我们记录下这四个变量,只要 |X0-X1|+1>=3 或者 |Y0-Y1|+1>=3,我们就可以将这个方块的坐标加入到 del数组中。

遍历完一全体二维数组之后,我们就可以将 del数组中对应坐标位置的方块内容变为 '0', 由于我们没有对 0 定义样式,以是在没有实行着落算法之前变为 0 的方块为白色。

着落算法

在我们将相应的方块白色之后,其上面的方块该当着落,在这里我的思想是这个样子的。

按照列遍历二维数组,定义一个指针 t,指向上次不为 0 的方块位置,一旦碰着方块不为 0 的格子就将其与t所指的方块就行交流,一次类推,示意图如下:

这样的话我们就可以把为空的上移到最顶层,并且不打乱顺序,然后我们在随机添补顶部的空方块就可以了。
做完添补之后我们要再做一次肃清算法,直到del数组的长度为空为止,这个道理大家该当都能想得到。

代码如下

clear(): void { const m: number = 10; const n: number = 10; while (true) { const del: any[] = []; for (let i: number = 0; i < m; i++) { for (let j: number = 0; j < n; j++) { if (this.squareData[i][j] === '0') { continue; } let x0: number = i; let x1: number = i; let y0: number = j; let y1: number = j; while (x0 >= 0 && x0 > i - 3 && this.squareData[x0][j] === this.squareData[i][j]) { --x0; } while (x1 < m && x1 < i + 3 && this.squareData[x1][j] === this.squareData[i][j]) { ++x1; } while (y0 >= 0 && y0 > j - 3 && this.squareData[i][y0] === this.squareData[i][j]) { --y0; } while (y1 < n && y1 < j + 3 && this.squareData[i][y1] === this.squareData[i][j]) { ++y1; } if (x1 - x0 > 3 || y1 - y0 > 3) { del.push([i, j]); } } } if (del.length === 0) { break; } this.score += del.length; for (const square of del) { this.$set(this.squareData[square[0]], square[1], '0'); } for (let j: number = 0; j < n; ++j) { let t: number = m - 1; for (let i: number = m - 1; i >= 0; --i) { if (this.squareData[i][j] !== '0') { [this.squareData[t][j], this.squareData[i][j]] = [this.squareData[i][j], this.squareData[t][j]]; t -= 1; } } } }},游戏结束#

分数为 0 的时候游戏结束,此时在实行一遍初始化函数,重新天生一个愉快消消乐格子,将分数初始化为10.

if (this.score <= 0) { if (confirm('分数用光了哦~~')) { this.init(); } else { this.init(); } }作者: Jacob98出处:https://www.cnblogs.com/Jacob98/p/11719156.html