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异步编程:异步数据收集的具体方法
Aug 19 Javascript
JS正则表达式大全(整理详细且实用)
Nov 14 Javascript
JS使用oumousemove和oumouseout动态改变图片显示的方法
Mar 31 Javascript
JS如何生成一个不重复的ID的函数
Dec 25 Javascript
AngularJS框架的ng-app指令与自动加载实现方法分析
Jan 04 Javascript
利用prop-types第三方库对组件的props中的变量进行类型检测
May 02 Javascript
weex slider实现滑动底部导航功能
Aug 28 Javascript
微信小程序通过保存图片分享到朋友圈功能
May 24 Javascript
了解前端理论:rscss和rsjs
May 23 Javascript
js类的继承定义与用法分析
Jun 21 Javascript
Vue事件修饰符native、self示例详解
Jul 09 Javascript
Vue父组件向子组件传值以及data和props的区别详解
Mar 02 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
PHPLog php 程序调试追踪工具
2009/09/09 PHP
用javascript getComputedStyle获取和设置style的原理
2008/10/10 Javascript
JavaScript对象和字串之间的转换实例探讨
2013/04/21 Javascript
jquery validate在ie8下的bug解决方法
2013/11/13 Javascript
js跑步算法的实现代码
2013/12/04 Javascript
node.js中的buffer.write方法使用说明
2014/12/10 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
2016/01/18 Javascript
详解Javascript ES6中的箭头函数(Arrow Functions)
2016/08/24 Javascript
详解VueJS应用中管理用户权限
2018/02/02 Javascript
Nodejs对postgresql基本操作的封装方法
2019/02/20 NodeJs
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
微信小程序按钮点击跳转页面详解
2019/05/06 Javascript
vue列表数据发生变化指令没有更新问题及解决方法
2020/01/16 Javascript
jQuery实现评论模块
2020/08/19 jQuery
javascript中闭包closure的深入讲解
2021/03/03 Javascript
[01:08]DOTA2次级职业联赛 - Shield战队宣传片
2014/12/01 DOTA
Python使用django搭建web开发环境
2017/06/09 Python
Django 实现下载文件功能的示例
2018/03/06 Python
python创造虚拟环境方法总结
2019/03/04 Python
Pandas分组与排序的实现
2019/07/23 Python
Django对models里的objects的使用详解
2019/08/17 Python
Django自带的用户验证系统实现
2020/12/18 Python
使用CSS实现弹性视频html5案例实践
2012/12/26 HTML / CSS
美国最大的香水连锁店官网:Perfumania
2016/08/15 全球购物
新西兰领先的内衣店:Bendon Lingerie新西兰
2018/07/11 全球购物
元宵节晚会主持人串词
2014/03/25 职场文书
群众路线教育实践活动心得体会(四风)
2014/11/03 职场文书
民主评议党员个人自我评价
2015/03/03 职场文书
乡镇科协工作总结2015
2015/05/19 职场文书
十二月早安励志心语大全
2019/12/03 职场文书
导游词之永泰公主墓
2019/12/04 职场文书
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL
JS函数式编程实现XDM一
2022/06/16 Javascript