写在前面

最近玩游戏的时候玩到游戏内置的拼图小游戏,突然唤起我对拼图游戏的热爱了,结果这内置游戏要花钱,在steam上找到的免费拼图游戏也不能自定义图片,想玩其他的图还要花钱。这让我很不爽,就索性自己写一个拼图游戏。
但是要说明的是,我做出的拼图游戏是非常简单的版本,甚至也不能算是个拼图,因为它的具体样子是这样的

这游戏的玩法是把拼图块以正确的方式放入正确的卡槽中的,拼图块还是正方形的(正在考虑如何做成真实的那种拼图块),也没有相互关联的拼图块拼成一个的时候,可以一起移动的效果。非要说跟拼图游戏有什么关系的话那就是都是以图片为线索拼接出一个完整图片。

  1. 页面结构
    页面结构很简单,左侧卡槽区,右侧拼图区,右上角缩略图区
  <div class="pintu_area"><div v-for="(part, index) in partList" :key="'part' + index" class="pintu_part"></div><div v-for="(img, index) in imgList" :key="index" :style="randomStyle(img)" class="part_img"@mousedown="moveImg($event,index)" @contextmenu.prevent="rotateImg($event, index)"></div><img class="thumb" :src="data:image"><input type="file" accept=".jpg,.png" @change="chooseImg($event)" title="点击更换图片"></div>
  1. 样式效果
  .pintu_area {display: flex;flex-wrap: wrap;width: 800px;height: 600px;background-color: rgba(0, 0, 0, 0.4);}.pintu_part {width: 100px;height: 100px;border: 1px solid #fff;}.part_img {width: 100px;height: 100px;background-size: 800px 600px;position: absolute;}.thumb,input {width: 200px;height: 150px;position: absolute;top: 0;right: 0;}input {opacity: 0;}@keyframes checked {50% {box-shadow: 0 0 20px #ffff00;}to {box-shadow: none;}}

样式很简单,还加了个动画效果用以在正确放置拼图块时对玩家进行提示

  1. 页面逻辑
    首先是基本数据结构
  el: '#app',data: {partList: [], // 卡槽imgList: [], // 拼图块rotateStatus: true, // 拼图旋转状态image: './img/bg_dog.jpg' // 拼图图片路径}

初始化拼图

 initGame() { // 游戏初始化this.imgList = []this.partList = []for (let i = 0; i < 48; i++) { // 循环遍历生成拼图数组与对应卡槽数组this.imgList.push({ // 拼图数组x: 8 - i % 8, // 第几列y: 6 - parseInt((i / 8)), // 第几行rotate: parseInt(Math.random() * 4) * 0.25 // 初始旋转角度,单位为turn})this.partList.push({ // 卡槽数组x: 8 - i % 8, // 第几列y: 6 - parseInt((i / 8)), //第几行fill: false, // 是否包含一个拼图块check: false // 是否放入正确的拼图})}this.imgList = this.imgList.sort(() => Math.random() - 0.5) // 打乱拼图数组顺序(可以不要)}

拼图的移动

  moveImg(e, index) { // 移动拼图const _this = thisif (!this.partList[index].check && e.button < 1) { // 判断当前卡片未放置到正确位置切是左键点击const el = e.targetel.style.transition = "none"el.style.zIndex = 99const sX = e.clientX - el.offsetLeftconst sY = e.clientY - el.offsetTopconst elLeft = parseInt(el.style.left) / 100const elTop = parseInt(el.style.top) / 100const elPart = _this.partList.find((elem) => elem.x == (8 - elLeft) && elem.y == (6 - elTop))if (elPart) { // 此处是判断将拼图从错误的卡槽里移除时,清除掉卡槽的填充状态const partIndex = _this.partList.indexOf(elPart)_this.partList[partIndex].fill = false}document.onmousemove = (e) => { // 拼图随鼠标移动const eX = e.clientX - sXconst eY = e.clientY - sYel.style.left = eX + 'px'el.style.top = eY + 'px'}document.onmouseup = (e) => { // 移动结束时的操作document.onmousemove = nullel.style.transition = "all 1s"el.style.zIndex = 1const left = parseInt(el.style.left) / 100const top = parseInt(el.style.top) / 100if (left < 8 && top < 6) { // 判断拼图移到了卡槽区域const toLeft = left < 7.5 ? Math.round(left) : 7const toTop = top < 5.5 ? Math.round(top) : 5const part = _this.partList.find((elem) => elem.x == (8 - toLeft) && elem.y == (6 - toTop))if (!part.fill) { // 如果卡槽是空的,将拼图移入离它最近的卡槽里并检查是否是正确的放入正确的卡槽里const partIndex = _this.partList.indexOf(part)_this.partList[partIndex].fill = trueel.style.left = toLeft * 100 + 'px'el.style.top = toTop * 100 + 'px'_this.checkImg(_this, el, index)}}}}}

拼图块的旋转

  rotateImg(e, index) { // 旋转当前拼图if (this.rotateStatus && !this.partList[index].check) { // 拼图可以旋转并且并未正确放置const el = e.targetthis.rotateStatus = falseel.style.transition = "all 1s"let angle = this.getAngle(el)if (angle < 0) { // 计算出的角度为270度时会返回-0.25,将其转为0.75以实现正确的旋转angle = 0.75}el.style.transform = `rotate(${angle + 0.25}turn)`const _this = thissetTimeout(() => {if (angle + 0.25 == 1) { // 如果旋转了360度将其重置为0度,不然再次旋转会变成逆时针旋转,然后检查该拼图是否正确的放置在正确的卡槽里el.style.transition = "none"el.style.transform = `rotate(0turn)`this.checkImg(this, el, index)}_this.rotateStatus = true}, 1000);}}

判断当前拼图块旋转角度,单位为turn

  getAngle(el) { // 判断当前元素旋转角度,此段方法是搜出来的,对搜索的结果进行了修改,获取的值以turn为角度单位const st = window.getComputedStyle(el, null)const tr = st.getPropertyValue("-webkit-transform") ||st.getPropertyValue("-moz-transform") ||st.getPropertyValue("-ms-transform") ||st.getPropertyValue("-o-transform") ||st.getPropertyValue("transform") ||"FAIL"const values = tr.split('(')[1].split(')')[0].split(',')const a = values[0]const b = values[1]return Math.round(Math.atan2(b, a) * (180 / Math.PI)) / 360}

检查拼图块是否正确放置

  checkImg(_this, el, index) { // 检查图片位置是否正确const left = parseInt(el.style.left) / 100const top = parseInt(el.style.top) / 100if (left < 8 && top < 6) { // 判断拼图移到了卡槽区域const toLeft = left < 7.5 ? Math.round(left) : 7const toTop = top < 5.5 ? Math.round(top) : 5const img = _this.imgList[index]if (img.x == (8 - toLeft) && img.y == (6 - toTop) && _this.getAngle(el) == 0) { // 拼图的x,y与当前所在卡槽的位置对应上且拼图角度是正确的_this.partList[index].check = true// _this.$refs.ding.play() // 游戏音效el.style.animation = 'checked 2s'el.style.zIndex = 0}if (_this.partList.every((elem) => elem.check)) {// _this.$refs.jubilate.play() // 游戏音效alert("已完成拼图")}}}

此时已完成了一个拼图游戏,为了增加可重复性加入自定义图片功能

  chooseImg(e) { // 点击上传图片更新图片const file = event.target.files[0]const reader = new FileReader()const _this = thisreader.readAsDataURL(file)reader.onload = function () { // 此处因this指向问题采用function声明函数,并未使用箭头函数_this.partList = []for (let i = 0; i < 48; i++) { // 循环遍历生成拼图数组与对应卡槽数组,重置卡槽,不重置的话,之前正确放置的拼图块会出现不可移动的问题_this.partList.push({ // 卡槽数组x: 8 - i % 8,y: 6 - parseInt((i / 8)),fill: false,check: false})}_this.image = this.result}}

写在后面

我为了完善游戏还加入了开始游戏与游戏介绍的界面,加入一些音效与图片来对其进行美化,并没有在此展示,大家可以自己自定义这些内容

VUE实现的简单拼图游戏相关推荐

  1. html九图拼图游戏代码,基于Vue.js实现数字拼图游戏

    先来看看效果图: 功能分析 当然玩归玩,作为一名Vue爱好者,我们理应深入游戏内部,一探代码的实现.接下来我们就先来分析一下要完成这样的一个游戏,主要需要实现哪些功能.下面我就直接将此实例的功能点罗列 ...

  2. H5原生js简单拼图游戏

    H5原生js简单拼图游戏 演示地址 效果展示 源码 index.html puzzle.css puzzle.js 源码下载 演示地址 链接: 演示地址 效果展示 源码 index.html < ...

  3. Vue.js-小demo实现简单的游戏购物车table

    Vue.js-小demo实现简单的游戏购物车table 最近通过学习vue框架,基本熟悉了其中的动态绑定属性,计算属性,监听,条件判断,循环遍历,所以通过一个小demo来巩固一下.这个小demo主要是 ...

  4. 用 JavaScript 实现简单拼图游戏

    本篇主要讲解,如何利用原生的 JavaScript 来实现一个简单的拼图小游戏. 线上体验地址:拼图 一.游戏的基础逻辑 想用一门语言来开发游戏,必须先了解如何使用这门语言来实现一些基础逻辑,比如图像 ...

  5. java 3 3数字拼图,基于Vue.js实现数字拼图游戏

    先来看看效果图: 功能分析 当然玩归玩,作为一名Vue爱好者,我们理应深入游戏内部,一探代码的实现.接下来我们就先来分析一下要完成这样的一个游戏,主要需要实现哪些功能.下面我就直接将此实例的功能点罗列 ...

  6. Qt实现简单拼图游戏

    文章目录 前言 演示图 1.ShowWidget.h 2.ShowWidget.cpp 3.MainWindow.h 4.MainWindow.cpp 前言 自己简单实现了下拼图功能.本来开始只是想显 ...

  7. Unity3d制作简单拼图游戏

    本文为原创,如需转载请注明原址:http://blog.csdn.net/cube454517408/article/details/7907247 最近一直在使用Unity,对它有了一些小的使用心得 ...

  8. 用flash制作简单拼图游戏

    简介: 可能有很多玩Flash的朋友都曾和我一样想自己动手制作一个拼图游戏,但是苦于不知道实现的方法或不了解ActionScript(以下简称AS)而心存遗憾.别急,今天盗匪就告诉你如何利用Flash ...

  9. HTML 简单拼图游戏

    先不废话,请看演示. 公司要搞这么个微信活动,可现在没有前端开发,没办法,身为打杂总监只好临时顶下这个空缺了.先找了一些 JS 代码,试用了下都不太理想,好一点的写的又太复杂,改起来有难度,干脆撸起袖 ...

最新文章

  1. 抽象类和接口的联系与区别
  2. 解决wubi安装ubuntu时要下载系统映像文件问题
  3. Oracle 11G在用EXP 导出时,空表不能导出解决
  4. shiro的会话管理:介绍
  5. Python的hasattr(),getattr(),setattr()
  6. C向Python正确传递数组的代码
  7. android 汉字 转 拼音首字母,Android开发之拼音转换工具类PinyinUtils示例
  8. Python 分词 第三方模块
  9. 12.2.1 QTcpSocket类介绍
  10. linux进程sl是什么,Linux ps state sl+是什么意思
  11. java斗地主代码花色,集合经典案例:斗地主发牌功能实现
  12. 树莓派配置https://www.raspberrypi.org/documentation/configuration/中的一个单词翻译:
  13. html中h3字体不加粗取消,css如何取消加粗
  14. ae怎么设置gpu渲染_有玩AE的吗?求教GPU渲染问题!!
  15. 基于node的智能家居
  16. IE中的看板管理在软件开发中的应用
  17. JS个性Hello文字动画js特效
  18. java 一键签到功能案例
  19. jquery 关于checked属性的添加与移除(解决.attr('checked',true)失效问题)
  20. jfinal 生成实体类

热门文章

  1. 给初学者:用VB写外挂 ———— 实战六:幽城幻剑录-幽城幻劍錄内存修改器
  2. js 区分鼠标左右键点击
  3. c语言中2UL左移16位是多少,C语言左移和右移(示例代码)
  4. IDEA导出springboot war包进tomcat服务器
  5. MySQL密码重置(Windows本地)
  6. Android权限操作之uses-permission详解
  7. linux命令--tcpdump
  8. sftp上传文件的js脚本
  9. 入手评测锐龙r5 5600g和i7 12700选哪个好
  10. @JSONField注解的使用