原文链接: vue 拼数字小游戏(设置表白彩蛋)
上一篇: vue 网格 过渡 动画
下一篇: mpvue 开发小程序 流程
效果
通过点击交换空白格子与周围的格子,将整个格子还原,如果在还原过程中,5,2,1,13,14,这几个数连在一起出现,则触发彩蛋
遇到的问题:
1,数组在改变其中某一项后,并不会刷新视图,这个需要使用$set设置数组的新元素的值,告诉vue,数组已经改变了,或者创建新数组然后重新赋值
this.items = Array.from(this.items)
或者
this.$set(this.items, '' + y, t)
2,判断彩蛋是否出现,使用indexOf,或者正则表达式都可以,但在测试中发现indexOf更快
isEgg() {
return this.items.join('').indexOf('5211314') != -1
}
3,如果是微信小程序,在v-for指令中,需要获取index时,需要加括号,否则会报错
<div class="cell" v-for="(i,index) in items" :key="i" @click="click(i,index)">{{i==16?'':i}}</div>
小程序版本
<template>
<div class="game">
<transition-group name="cells" tag="div" class="grid">
<div class="cell" v-for="(i,index) in items" :key="i" @click="click(i,index)">{{i==16?'':i}}</div>
</transition-group>
<div class="egg" v-show="show">
{{egg}}
</div>
<div class="egg" v-show="isPass">
<h3>
恭喜拼图成功
</h3>
</div>
<button @click="init" class="reset">重置</button>
</div>
</template>
<script>
// import {Toast} from 'mint-ui';
// import 'mint-ui/lib/style.css'
// import 'animate.css'
export default {
name: "game-card",
data() {
return {
egg: 'hwq,你知道吗,我喜欢你很久了',
items: Array.from(Array(16)).map((_, index) => index + 1),
// items: [5, 2, 1, 13, 6, 3, 14, 7, 8, 9, 10, 11, 12, 15, 16, 4],
showEgg: false,
show: false,
}
},
watch: {
items() {
console.log('watch', this.items)
if (this.isPass) {
console.log('pass')
}
console.log(this.isEgg)
if (this.isEgg && !this.showEgg) {
this.showEgg = true
this.show = true
setTimeout(
() => this.show = false,
1000
)
}
}
},
computed: {
zero() {
return this.items.indexOf(16)
},
isPass() {
return this.items.every(
(item, index) => item == index + 1
)
},
isEgg() {
console.log(this.items.join(''))
return this.items.join('').indexOf('5211314') != -1
}
},
methods: {
// 交换x,y 位置变量
swap(x, y) {
let t = this.items[x]
this.items[x] = this.items[y]
this.items[y] = t
// this.$set(this.items, '' + y, t)
let arr = Array.from(this.items)
this.items = arr
},
// 0,1,2,3 表示上右下左,四个方向
move(dir) {
if (dir == 0 && this.zero > 3) {
console.log('up', this.zero)
this.swap(this.zero, this.zero - 4)
} else if (dir == 1 && this.zero % 4 != 3) {
console.log('right', this.zero)
this.swap(this.zero, this.zero + 1)
} else if (dir == 2 && this.zero <= 11) {
console.log('down', this.zero)
this.swap(this.zero, this.zero + 4)
} else if (dir == 3 && this.zero % 4 != 0) {
console.log('left')
this.swap(this.zero, this.zero - 1)
}
},
// 随机初始化
init() {
let num = parseInt(Math.random() * 1000)
console.log('init', num)
for (let i = 0; i < num; i++) {
let d = parseInt((Math.random() * 100)) % 4
this.move(d)
console.log(d)
}
},
click(item, index) {
console.log('click', item, index)
if (item == 16)
return
if (index + 1 < 16 && this.items[index + 1] == 16) {
console.log('click move', 3)
this.move(3)
} else if (index - 1 >= 0 && this.items[index - 1] == 16) {
this.move(1)
console.log('click move', 1)
} else if (index + 4 < 16 && this.items[index + 4] == 16) {
this.move(0)
console.log('click move', 0)
} else if (index - 4 >= 0 && this.items[index - 4] == 16) {
this.move(2)
console.log('click move', 2)
}
}
},
created() {
this.init()
},
}
</script>
<style scoped>
.grid {
position: relative;
display: grid;
grid-gap: 5px;
background-color: rgb(233, 233, 233);
width: 215px;
border: 5px rgb(233, 233, 233) solid;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
.cell {
background-color: lightskyblue;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
/*border: 5px solid white;*/
box-sizing: border-box;
}
/*过渡时间*/
.cells-move {
transition: transform 1s;
}
.cells-enter-active, .cells-leave-active {
transition: all 1s;
}
/*效果*/
.cells-enter, .cells-leave-to {
opacity: 0;
transform: translateY(30px);
}
.game {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.egg {
position: absolute;
bottom: 50px;
background: rgba(0, 0, 0, 0.5);
/*opacity: 0.8;*/
border-radius: 20px;
padding: 10px;
color: white;
}
.reset {
margin-top: 20px;
}
</style>
使用面向对象的方式,新增一个对象,然后操作对象即可
class NumGame {
// 边长
constructor(size) {
this.size = size
this.items = Array.from(Array(size * size)).map((_, index) => index + 1)
this.blank = size * size
}
// 是否完成
isPass() {
return this.items.every((item, index) => item == index)
}
// 空白块所在位置
blankPos() {
return this.items.indexOf(this.blank)
}
// 移动
move(dir) {
console.log(dir)
if (dir == 0 && this.blankPos() >= this.size) {
this.swap(this.blankPos(), this.blankPos() - this.size)
} else if (dir == 1 && this.blankPos() % this.size != (this.size - 1)) {
this.swap(this.blankPos(), this.blankPos() + 1)
} else if (dir == 2 && this.blankPos() < (this.size - 1) * this.size) {
this.swap(this.blankPos(), this.blankPos() + this.size)
} else if (dir == 3 && this.blankPos() % this.size != 0) {
this.swap(this.blankPos(), this.blankPos() - 1)
}
}
// 交换
swap(x, y) {
// console.log(x, y)
let t = this.items[xm]
this.items[x] = this.items[y]
this.items[y] = t
}
toString() {
return this.items.toString()
}
}
let ng = new NumGame(3)
ng.move(0)
console.log(ng.toString())
// 1,2,3,4,5,9,7,8,6