vue制作3*3拼图
自从上次发布了vue制作抓娃娃机经验之后,好多朋友来私信我让我多分享一些小游戏的经验。(看来友友们对这种小游戏还是挺感兴趣哦捂脸笑)
好了,回归正题。今天给大家带来一个比较简单的小游戏——拼图。想必大家平时或多或少都玩过拼图游戏吧,我记得小时候经常偷偷用我爸爸的手机玩上面的拼图小游戏,简单的有2×2,3×3甚至有4×4、5×5等等复杂的难关。作为玩者我们是在研究如何过关,而对于我们程序猿来说,我们是不是应该研究研究这些游戏怎么做出来的呢。今天它来啦~~
老样子,先看效果图。
首先介绍规则:3×3的方格中,有一处是空白,点击空白周围的卡片,使其移动,直至拼成最终效果图(页面下方有成品图,这里录gif的时候没带上)。
第一步,上样式:
<div class="game"><ul class="puzzle-wrap"><liv-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
进来的朋友点点赞点点关注哦~以后会分享更多的小游戏制作经验哦 (●ˇ∀ˇ●)
您的点赞和关注,是我创作的动力之源哦(●’◡’●)
vue制作3*3拼图
自从上次发布了vue制作抓娃娃机经验之后,好多朋友来私信我让我多分享一些小游戏的经验。(看来友友们对这种小游戏还是挺感兴趣哦捂脸笑)
好了,回归正题。今天给大家带来一个比较简单的小游戏——拼图。想必大家平时或多或少都玩过拼图游戏吧,我记得小时候经常偷偷用我爸爸的手机玩上面的拼图小游戏,简单的有2×2,3×3甚至有4×4、5×5等等复杂的难关。作为玩者我们是在研究如何过关,而对于我们程序猿来说,我们是不是应该研究研究这些游戏怎么做出来的呢。今天它来啦~~
老样子,先看效果图。
首先介绍规则:3×3的方格中,有一处是空白,点击空白周围的卡片,使其移动,直至拼成最终效果图(页面下方有成品图,这里录gif的时候没带上)。
第一步,上样式:
<div class="game"><ul class="puzzle-wrap"><liv-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
进来的朋友点点赞点点关注哦~以后会分享更多的小游戏制作经验哦 (●ˇ∀ˇ●)
您的点赞和关注,是我创作的动力之源哦(●’◡’●)