数字华容道
前言
此次游戏 —— 数字华容道
数字华容道是用尽量少的步数,尽量短的时间,将棋盘上的数字方块,按照从左到右、从上到下的顺序重新排列整齐
1、
<template>
<!-- 数字华容道 -->
<view class="klotski z-height flexColumn">
<!-- 当前等级 -->
<view class="klotski-status flexCenter">
<view class="klotski-status-item">
<view class="klotski-status-rope"></view>
<view class="klotski-status-level">
<view class="klotski-status-level-box">3X3</view>
</view>
</view>
</view>
<!-- 时间、步数、等级选择 -->
<view class="klotski-btns box">
<!-- <view class="klotski-btns-title z-t-c" v-if="!is_start">目标关卡</view> -->
<view class="flexBetween" style="height: 100%;">
<view class="klotski-btns-time flexCenter">时间 {{time}}</view>
<view class="klotski-btns-step flexCenter">步数 <text class="u-m-l-20">{{step}}</text></view>
<view class="klotski-btns-level flexCenter" @click="bindLevel">等级</view>
</view>
</view>
<!-- 游戏区 -->
<view class="klotski-play">
<view class="klotski-play-box">
<view class="klotski-play-tr" v-for="(item1, index1) in newList" :key="index1">
<view class="klotski-play-td" v-for="(item2, index2) in item1" :key="index2" @click="bindBlock(index1, index2)">
<view class="klotski-play-td-box" v-if="item2 !== ''">
<view class="klotski-play-td-block flexCenter">{{item2}}</view>
</view>
</view>
</view>
</view>
</view>
<!-- 开始游戏 -->
<view class="flex1 flexCenter" v-if="!is_start">
<view class="klotski-start" @click="playStart">开始游戏</view>
</view>
</view>
</template>
2、
<style>
page{background-color: rgba(241, 217, 183, 1);}
</style>
<style lang="scss" scoped>
@mixin three-dimensional{
border-top: 8rpx solid rgb(248,232,210);
border-right: 8rpx solid rgb(156,116,79);
border-bottom: 8rpx solid rgb(136,99,65);
border-left: 8rpx solid rgb(156,116,79);
}
.klotski-status{
padding: 40rpx 30rpx;
.klotski-status-level{
position: relative;border-radius: 28rpx;background-color: rgb(180, 102, 61);padding: 10rpx;box-shadow: 10rpx 14rpx 10rpx 0rpx rgba(0,0,0,.6);
.klotski-status-level-box{position: relative;width: 100%;height: 100%;padding: 10rpx 50rpx;background-color: rgb(241,241,241);border-radius: 20rpx;box-shadow: inset 2rpx 4rpx 10rpx 4rpx rgba(0,0,0,.6);font-weight: bold;font-size: 50rpx;}
}
.klotski-status-rope{
position: relative;width: 100%;
&::after{content: "";position: absolute;width: 10rpx;height: 80rpx;background-color: rgb(180, 102, 61);top: -60rpx;left: 50rpx;box-shadow: 10rpx 14rpx 10rpx 0rpx rgba(0,0,0,.6);}
&::before{content: "";position: absolute;width: 10rpx;height: 80rpx;background-color: rgb(180, 102, 61);top: -60rpx;right: 50rpx;box-shadow: 10rpx 14rpx 10rpx 0rpx rgba(0,0,0,.6);}
}
}
.klotski-btns{
height: 134rpx; padding: 0 30rpx 40rpx;
.klotski-btns-title{font-size: 70rpx;font-weight: bold;-webkit-text-stroke: 2rpx rgba(180, 102, 61,.5); background-image: linear-gradient(to bottom, rgb(254,243,201), rgb(254,235,38));-webkit-background-clip: text;color: transparent;}
.klotski-btns-time{width: 210rpx;height: 60rpx; background-color: rgb(95,94,93);color: #fff;border-radius: 100rpx;box-shadow: inset 4rpx 4rpx 10rpx rgba(0,0,0,1);font-weight: bold;font-size: 30rpx;}
.klotski-btns-step{width: 210rpx;height: 60rpx;background-color: #fff;font-weight: bold;font-size: 30rpx;border-radius: 100rpx;box-shadow: inset 4rpx 4rpx 10rpx rgba(0,0,0,.5);}
.klotski-btns-level{width: 210rpx;height: 60rpx;background-color: rgb(69, 28, 13);color: rgb(254,228,58);font-weight: bold;font-size: 30rpx;border-radius: 20rpx;box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 1);}
}
.klotski-play{
width: 100%;height: 750rpx;border-radius: 20rpx;background-color: rgb(69, 28, 13);border: 20rpx solid rgb(180, 102, 61);box-shadow: 0rpx 12rpx 15rpx 0rpx rgba(0,0,0,.6);
.klotski-play-box{width: 100%;height: 100%;display: flex;flex-direction: column;border: 4rpx solid rgb(2,0,2);}
.klotski-play-tr{display: flex;width: 100%;flex: 1;}
.klotski-play-td{flex: 1;}
.klotski-play-td-box{width: 100%;height: 100%;color: #fff;font-size: 80rpx;border: 4rpx solid rgb(2,0,2);}
.klotski-play-td-block{width: 100%;height: 100%;background-color: rgb(232,189,131);color: rgb(78,28,9);font-weight: bold;@include three-dimensional;}
}
.klotski-start{padding: 40rpx 120rpx;background-color: rgb(69, 28, 13);color: #fff;font-weight: bold;font-size: 40rpx;border-radius: 100rpx;box-shadow: 0rpx 10rpx 15rpx 0rpx rgba(0,0,0,.4);animation: btnScale 1s infinite linear;}
@keyframes btnScale{
0%{transform: scale(1);}
50%{transform: scale(1.1);}
100%{transform: scale(1);}
}
</style>
3、
<script>
export default {
data() {
return {
level: ['3X3', '4X4', '5X5'],
is_start: false,
is_over: false,
rowcol: 3,
list: [],
newList: [],
step: 0,
time: 0,
timer: null
};
},
onLoad() {
this.init()
},
onUnload() {
clearInterval(this.timer)
},
methods:{
// 一维数组转成二维数组
changeDimen(arr){
let newArr = []
while(arr.length > 0){
newArr.push(arr.splice(0, this.rowcol))
}
return newArr
},
// 初始化数组
init(){
for(let i = 0; i < this.rowcol*this.rowcol; i++){
this.list[i] = i < this.rowcol*this.rowcol - 1 ? i + 1 : ""
this.newList[i] = i < this.rowcol*this.rowcol - 1 ? i + 1 : ""
}
this.newList = this.changeDimen(this.newList)
},
// 开始游戏
playStart(){
this.is_over = false
this.is_start = true
// uview: this.$u.randomArray打乱数组 this.$u.deepClone深拷贝
this.newList = this.changeDimen(this.$u.randomArray(this.$u.deepClone(this.list)))
this.timer = setInterval(()=>{
this.time++
},1000)
},
// 点击方块
bindBlock(x, y){
// 没开始 已结束 空方块
if(!this.is_start || this.is_over || this.newList[x][y] == ''){
return
}
// 判断上下左右
if(this.newList[x - 1] && this.newList[x - 1][y] == ''){
this.newList[x - 1][y] = this.newList[x][y]
this.newList[x][y] = ""
this.step++
}
if(x + 1 < this.rowcol && this.newList[x + 1][y] == ''){
this.newList[x + 1][y] = this.newList[x][y]
this.newList[x][y] = ""
this.step++
}
if(y - 1 >= 0 && this.newList[x][y - 1] == ''){
this.newList[x][y - 1] = this.newList[x][y]
this.newList[x][y] = ""
this.step++
}
if(y + 1 < this.rowcol && this.newList[x][y + 1] == ''){
this.newList[x][y + 1] = this.newList[x][y]
this.newList[x][y] = ""
this.step++
}
this.$forceUpdate()
// 判断是否赢了
this.win()
},
// 判断是否赢了,就是把newlist数组变成一维数组,再去跟list比较是否相同
win(){
let newArr = this.newList.reduce((a, b) => { return a.concat(b) })
if(this.list.toString() == newArr.toString()){
clearInterval(this.timer)
uni.showModal({
title: "恭喜你赢了",
content: `用时:${this.time}s, 步数:${this.step}`,
showCancel: false,
success: res => {
if (res.confirm) {
this.initGame()
}
}
})
}
},
// 选择等级
bindLevel(){
uni.showActionSheet({
itemList: this.level,
success: res => {
this.rowcol = Number(this.level[res.tapIndex][0])
this.initGame()
}
})
},
// 重置游戏
initGame(){
clearInterval(this.timer)
this.is_over = false
this.is_start = false
this.step = 0
this.time = 0
this.timer = null
this.list = []
this.newList = []
this.init()
},
}
}
</script>