自从上次发布了vue制作抓娃娃机经验之后,好多朋友来私信我让我多分享一些小游戏的经验。(看来友友们对这种小游戏还是挺感兴趣哦捂脸笑)
好了,回归正题。今天给大家带来一个比较简单的小游戏——拼图。想必大家平时或多或少都玩过拼图游戏吧,我记得小时候经常偷偷用我爸爸的手机玩上面的拼图小游戏,简单的有2×2,3×3甚至有4×4、5×5等等复杂的难关。作为玩者我们是在研究如何过关,而对于我们程序猿来说,我们是不是应该研究研究这些游戏怎么做出来的呢。今天它来啦~~
老样子,先看效果图。
首先介绍规则:3×3的方格中,有一处是空白,点击空白周围的卡片,使其移动,直至拼成最终效果图(页面下方有成品图,这里录gif的时候没带上)。
第一步,上样式:
<div class="game">
<ul class="puzzle-wrap">
<li
v-for="(puzzle, index) in puzzles"
:key="puzzle.id"
:class="{'puzzle': true, 'puzzle-empty': !puzzle}"
@click="move(puzzle,index)"
>
<img :src="puzzle.url" alt="error" width="100%" height="100%" />
</li>
</ul>
</div>
.game {
width: 560px;
height: 560px;
margin-top: 30px;
background-image: url("./../assets/img/bgsmall.png");
background-size: 100%;
.puzzle-wrap {
background-image: url("./../assets/img/dot1.png");
width: 560px;
height: 560px;
overflow: hidden;
background-size: 100%;
list-style: none;
padding: 19px 20px 0 21px;
border-radius: 40px;
animation: puzzle-wrap infinite 0.6s;
.puzzle {
float: left;
width: 173px;
height: 173px;
font-size: 20px;
background: #f90;
text-align: center;
line-height: 100px;
border: 1px solid #ccc;
box-shadow: 1px 1px 4px;
text-shadow: 1px 1px 1px #b9b4b4;
cursor: pointer;
img {
height: 100%;
width: 100%;
}
&.puzzle-empty {
background: #ccc;
box-shadow: inset 2px 2px 18px;
}
}
}
@keyframes puzzle-wrap { // 此动画是用来装饰游戏边框的动画(可忽略)
form {
background-image: url("./../assets/img/dot1.png");
}
to {
background-image: url("./../assets/img/dot2.png");
}
}
}
样式没什么问题,咱来看如何实现点击拼图。
首先准备好卡片资源,并随机设置生成卡片序列
data() {
return {
puzzles: [ // 可以在data中向这样引入,也可单独写个js文件来引入,看自己习惯。(其中有一张空白图片,并将其多设置一个参数,如:empty。用来后面判断是否拼图成功)
{
id: 0,
url: require("./../assets/img/pintu/pintu_01.png")
},
{
id: 1,
url: require("./../assets/img/pintu/pintu_02.png")
},
{
id: 2,
url: require("./../assets/img/pintu/pintu_03.png")
},
{
id: 3,
url: require("./../assets/img/pintu/pintu_04.png")
},
{
id: 4,
url: require("./../assets/img/pintu/pintu_05.png")
},
{
id: 5,
url: require("./../assets/img/pintu/pintu_06.png")
},
{
id: 6,
url: require("./../assets/img/pintu/pintu_07.png")
},
{
id: 7,
url: require("./../assets/img/pintu/pintu_08.png")
},
{
empty: true,
id: 8,
url: require("./../assets/img/pintu/pintu_09.jpg")
}
],
};
},
mounted() {
this.randomRender();
},
methods: {
// 随机生成方块序列
randomRender() {
let puzzles = this.puzzles,
results = []; // 用拿到的卡片数据随机排序生成新的数组赋值,
results = puzzles.sort(() => {
return Math.random() > 0.5 ? -1 : 1;
});
this.puzzles = results;
},
}
这样卡片的随机排序就生成好了,在页面初始mouted去调用以及拼图成功或失败之后再次调用来初始数据。
接下来就是点击卡片让其移动并判断是否达到最终效果图。
// 点击方块
move(puzzle, index) {
let puzzles = this.puzzles;
// 获取点击位置及其上下左右的值
let curNum = puzzles[index],
leftNum = puzzles[index - 1],
rightNum = puzzles[index + 1],
topNum = puzzles[index - 3],
bottomNum = puzzles[index + 3];
let emptyObj = {
empty: true,
id: 8,
url: require("./../assets/img/pintu/pintu_09.jpg")
};
// 和为空的位置交换数值
if (leftNum && leftNum.empty && index % 3) {
this.$set(puzzles, index - 1, curNum);
this.$set(puzzles, index, emptyObj);
} else if (rightNum && rightNum.empty && 2 !== index % 3) {
this.$set(puzzles, index + 1, curNum);
this.$set(puzzles, index, emptyObj);
} else if (topNum && topNum.empty) {
this.$set(puzzles, index - 3, curNum);
this.$set(puzzles, index, emptyObj);
} else if (bottomNum && bottomNum.empty) {
this.$set(puzzles, index + 3, curNum);
this.$set(puzzles, index, emptyObj);
}
this.$nextTick(() => {
this.passChecked();
});
},
passChecked() {
const puzzles = this.puzzles;
if (puzzles[8]["empty"]) {
const isPass = puzzles.every((x, y) => x.id === y); 该方法的用法
if (isPass) {
console.log('成功啦~~');
// return true;
}
}
return false;
},
当每次点击卡片时,获取该卡片的位置以及其上下左右四张卡片的值。然后定义空卡片的值,判断空卡片在点击卡片的方位,然后进行交换数值替换位置。
接下来用刚开始定义空卡片的empty值去判断当前数组的最后一张卡片该值是否存在,若存在再使用every()依次去判断当前数组每个数据的id是否等于对应的索引值。若返回为true则证明拼图成功。
这样再看游戏是不是觉得很简单呢,玩着自己制作的小游戏是不是有点小成就感呢~~
有不懂的或者我的讲解哪里存在问题的可以在下方评论交流哦O(∩_∩)O
进来的朋友点点赞点点关注哦~以后会分享更多的小游戏制作经验哦 (●ˇ∀ˇ●)