JavaScript实现的拼图算法分析


Posted in Javascript onFebruary 13, 2019

本文实例分析了JavaScript实现的拼图算法。分享给大家供大家参考,具体如下:

学了html5的拖拽事件,相信做出一款小小的拼图游戏也不难吧。就来说一下怎么用drag事件完成拼图游戏吧,当然html5的新方法在IE下是不兼容的。这里我把这个拼图游戏封装成一个小插件,感兴趣的话可以直接copy来用,使用方法很简单。

HTML,3个div里面什么都不用写,分别是用来放拼图,参照图,拼图面吧的。

<div id="selectpanel"></div>
<div id="orginalimg"></div>
<div id="mathpanel"></div>

CSS,这里CSS基本不用写,要写的话可以把margin和padding归0,最好还是写一下。

*{margin: 0;padding: 0;}

重点javascript脚本(封装部分)

function Puzzle(imgWidth,imgHeight,cuttingoffX,cuttingoffY,img){
  var selectPanel=document.getElementById("selectpanel");//拼图面板
  var mathPanel=document.getElementById("mathpanel");//拼图匹配面板
  var orginalImg=document.getElementById("orginalimg");//参照图面板
  selectPanel.style.cssText='width: auto;height: auto;border: 2px solid black;overflow: hidden;float: left;margin: 10px;';
  mathPanel.style.cssText='width: auto;height: auto;border: 2px solid black;overflow: hidden;float: right;margin: 10px;';
  var amount=(imgWidth/cuttingoffX)*(imgHeight/cuttingoffY);//根据自定义每块拼图的宽高,计算拼图的总数量
  var jsonPosition=[];
  for(var i=0;i<amount;i++){//一个数组模拟成一个二维矩阵,用json来存这个矩阵,并且每个位置给它一个匹配值M
    jsonPosition[i]={X:i%(imgWidth/cuttingoffX),Y:parseInt(i/(imgHeight/cuttingoffY)),M:i};
  }
  for(var c=0;c<amount;c++){//随机生成拼图位置
    var divImg=document.createElement("div");
    divImg.style.width=cuttingoffX+"px";
    divImg.style.height=cuttingoffY+"px";
    divImg.style.backgroundImage="url(img/"+img+")";
    divImg.style.backgroundRepeat="no-repeat";
    divImg.style.border="1px dashed gray";
    divImg.style.float="left";
    divImg.style.cursor="pointer";
    if(c%(imgWidth/cuttingoffX)==0&&c!=0)
    divImg.style.clear="left";
    var rendomPositon=jsonPosition.splice(Math.floor(Math.random()*jsonPosition.length),1)[0];
    divImg.style.backgroundPosition=rendomPositon['X']*(-cuttingoffX)+'px'+' '+rendomPositon['Y']*(-cuttingoffY)+'px';
    divImg.draggable="true";
    divImg.maths=rendomPositon["M"];
    selectPanel.appendChild(divImg);
  }
  for(var c=0;c<amount;c++){//生成拼图匹配面板
    var divEmpty=document.createElement("div");
    divEmpty.style.width=cuttingoffX+"px";
    divEmpty.style.height=cuttingoffY+"px";
    divEmpty.style.border="1px solid gray";
    divEmpty.style.float="left";
    if(c%(imgWidth/cuttingoffX)==0&&c!=0)
    divEmpty.style.clear="left";
    divEmpty.maths=c;
    mathPanel.appendChild(divEmpty);
  }
  var orginalImgWidth=document.body.clientWidth-(selectPanel.offsetWidth+selectPanel.offsetLeft+10)*2;
  orginalImg.style.cssText="width: "+orginalImgWidth+"px;height:"+orginalImgWidth+"px;position:absolute;left:50%;margin-left:"+(-orginalImgWidth/2)+"px;top:10px;";
  orginalImg.style.background="url(img/"+img+") no-repeat 0 0";
  orginalImg.style.backgroundSize=orginalImgWidth+"px "+orginalImgWidth+"px";
  var divImgs=selectPanel.getElementsByTagName("div");
  var divEmptys=mathPanel.getElementsByTagName("div");
  for(var e=0;e<divImgs.length;e++){
    divImgs[e].ondragstart=function(event){//鼠标开始拖拽拼图,并且拿到它的匹配值maths
      var event=event||window.event;
      event.dataTransfer.setData("math",this.maths);
    }
    divImgs[e].ondrag=function(){
    }
    divImgs[e].ondragend=function(){
    }
    divEmptys[e].ondragenter=function(){
      this.style.backgroundColor="red";
    }
    divEmptys[e].ondragover=function(event){//取消在拼图匹配面板的默认事件,否则ondrop无效
      return false;
    }
    divEmptys[e].ondragleave=function(){
      this.style.backgroundColor="transparent";
    }
    divEmptys[e].ondrop=function(event){//拖拽的拼图在匹配面板放下时执行函数
      var event=event||window.event;
      this.style.backgroundColor="transparent";
      if(event.dataTransfer.getData("math")==this.maths){//判断拼图传过来的maths匹配值是否和匹配面板的maths一样,如果是则匹配成功
        for(var i=0;i<divImgs.length;i++){
          if(divImgs[i].maths==this.maths){
            this.style.backgroundImage=divImgs[i].style.backgroundImage;
            this.style.backgroundRepeat=divImgs[i].style.backgroundRepeat;
            this.style.backgroundPosition=divImgs[i].style.backgroundPosition;
            divImgs[i].setAttribute("draggable","false");
            divImgs[i].style.background="none";
          }
        }
      }
    }
  }
}
//浏览器窗口发生变化时的图片处理
window.onresize=function(){
  var selectPanel=document.getElementById("selectpanel");
  var orginalImg=document.getElementById("orginalimg");
  var orginalImgWidth=document.body.clientWidth-(selectPanel.offsetWidth+selectPanel.offsetLeft+10)*2;
  orginalImg.style.width=orginalImg.style.height=orginalImgWidth+"px";
  orginalImg.style.marginLeft=-orginalImgWidth/2+"px";
  orginalImg.style.backgroundSize=orginalImgWidth+"px "+orginalImgWidth+"px";
}

javascript脚本(调用方法)

window.onload=function(){
  //图的原始宽度(原图宽),图的原始高度(原图高),自定每块拼图的宽度(能被原图宽整除),自定每块拼图的高度(能被原图高整除),图片名(需放在img下)
  Puzzle(500,500,125,125,"haqi.jpg");
}

这里直接调用Puzzle这个函数哦,要注意的是,前面两个参数一定要为图片原始的宽高,而且为了效果更好的横屏拼图展示,这个图片的宽度啊最好小于屏幕横分辨率的1/2,多出来的话用photoshop调一下图片尺寸也是可以的。还有一个最重要的是,自定义每块小拼图的宽高一定是能被原始图片宽高整除的。说白了就是,第3个参数能被第1个参数整除,第4个参数能被第2个参数整除。最后一个参数就是图片名了,而且这个图片是放在img下的。

下面就来看看初始化拼图游戏的效果,而且每次刷新页面,拼图面板的小图都是随机排列的。这个狗狗的图大小是500x500,每个小图切割宽高为125x125,所以拼图排列是500/125*500/125=16,就是四行四列吧=>4x4,当然这个参数是可以改的,每个小拼图的宽高越小,它切出来的图就越多。

JavaScript实现的拼图算法分析

为了凸显这个函数的灵活性,下面再换种参数进行调用。

window.onload=function(){
  //图的原始宽度(原图宽),图的原始高度(原图高),自定每块拼图的宽度(能被原图宽整除),自定每块拼图的高度(能被原图高整除),图片名(需放在img下)
  Puzzle(500,500,100,100,"beauty.jpg");
}

换成了一张500x500的美女图,切割宽高为100x100

JavaScript实现的拼图算法分析

试玩一波游戏先:(为了展示效果降低游戏难度)

JavaScript实现的拼图算法分析

Javascript 相关文章推荐
JavaScript入门教程(12) js对象化编程
Jan 31 Javascript
js实现页面转发功能示例代码
Aug 05 Javascript
jquery next nextAll nextUntil siblings的区别介绍
Oct 05 Javascript
js输入框邮箱自动提示功能代码实现
Dec 10 Javascript
JavaScript中的迭代器和生成器详解
Oct 29 Javascript
javascript中eval函数用法分析
Apr 25 Javascript
使用Sticky组件实现带sticky效果的tab导航和滚动导航的方法
Mar 22 Javascript
vue动态绑定class选中当前列表变色的方法示例
Dec 19 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
Aug 22 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 Javascript
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
Feb 03 Javascript
VueQuillEditor富文本上传图片(非base64)
Jun 03 Javascript
推荐15个最好用的JavaScript代码压缩工具
Feb 13 #Javascript
Vue中CSS动画原理的实现
Feb 13 #Javascript
Vue中JS动画与Velocity.js的结合使用
Feb 13 #Javascript
JavaScript中.min.js和.js文件的区别讲解
Feb 13 #Javascript
node.js微信小程序配置消息推送的实现
Feb 13 #Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 #Javascript
Jquery实现无缝向上循环滚动列表的特效
Feb 13 #jQuery
You might like
php强大的时间转换函数strtotime
2016/02/18 PHP
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
js常用代码段整理
2011/11/30 Javascript
JS构建页面的DOM节点结构的实现代码
2011/12/09 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
Nodejs抓取html页面内容(推荐)
2016/08/11 NodeJs
微信小程序 简单教程实例详解
2017/01/13 Javascript
JS中cookie的使用及缺点讲解
2017/05/13 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
在knockoutjs 上自己实现的flux(实例讲解)
2017/12/18 Javascript
JS中原始值和引用值的储存方式示例详解
2018/03/23 Javascript
layui表格内放置图片,并点击放大的实例
2019/09/10 Javascript
如何修改Vue打包后文件的接口地址配置的方法
2020/04/22 Javascript
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
2020/05/19 jQuery
Jquery使用each函数实现遍历及数组处理
2020/07/14 jQuery
vue 导航菜单刷新状态不消失,显示对应的路由界面操作
2020/08/06 Javascript
详解使用python的logging模块在stdout输出的两种方法
2017/05/17 Python
python中将一个全部为int的list 转化为str的list方法
2018/04/09 Python
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
Python实现微信好友的数据分析
2019/12/16 Python
ansible动态Inventory主机清单配置遇到的坑
2020/01/19 Python
python super用法及原理详解
2020/01/20 Python
Python中的xlrd模块使用原理解析
2020/05/21 Python
python中if及if-else如何使用
2020/06/02 Python
keras 使用Lambda 快速新建层 添加多个参数操作
2020/06/10 Python
JustFab加拿大:女鞋、靴子、手袋和服装在线
2018/05/18 全球购物
公司门卫管理制度
2014/02/01 职场文书
学生安全承诺书
2014/05/22 职场文书
危货运输企业安全生产责任书
2014/07/28 职场文书
党的群众路线教育实践活动对照检查材料思想汇报
2014/09/19 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
革命电影观后感
2015/06/18 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书