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 相关文章推荐
打开超链需要“确认”对话框的方法
Mar 08 Javascript
jQuery Ajax提交表单查询获得数据实例代码
Sep 19 Javascript
js 字符串转换成数字的三种方法
Mar 23 Javascript
javascript与有限状态机详解
May 08 Javascript
jQuery中mouseover事件用法实例
Dec 26 Javascript
javascript结合fileReader 实现上传图片
Jan 30 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
Oct 31 Javascript
jQuery插件开发汇总
May 15 Javascript
基于JavaScript实现回到页面顶部动画代码
May 24 Javascript
新闻上下滚动jquery 超简洁(必看篇)
Jan 21 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
Jan 23 Javascript
React Ant Design树形表格的复杂增删改操作
Nov 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
PHP 中文处理技巧
2010/04/25 PHP
深入php函数file_get_contents超时处理的方法详解
2013/06/03 PHP
解析PHP将对象转换成数组的方法(兼容多维数组类型)
2013/06/21 PHP
Javascript 原型和继承(Prototypes and Inheritance)
2009/04/01 Javascript
js分页代码分享
2014/04/28 Javascript
jquery实现类似淘宝星星评分功能有截图
2014/09/15 Javascript
简单解析JavaScript中的__proto__属性
2016/05/10 Javascript
AngularJs实现分页功能不带省略号的代码
2016/05/30 Javascript
javascript实现简易计算器的代码
2016/05/31 Javascript
深入理解node exports和module.exports区别
2016/06/01 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
JS阻止事件冒泡行为和闭包的方法
2016/06/16 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
react.js CMS 删除功能的实现方法
2017/04/17 Javascript
vue+iview写个弹框的示例代码
2017/12/05 Javascript
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
django manage.py扩展自定义命令方法
2018/05/27 Python
Python实现定期检查源目录与备份目录的差异并进行备份功能示例
2019/02/27 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
节日快乐! Python画一棵圣诞树送给你
2019/12/24 Python
Python字符串hashlib加密模块使用案例
2020/03/10 Python
TensorFlow keras卷积神经网络 添加L2正则化方式
2020/05/22 Python
python爬虫要用到的库总结
2020/07/28 Python
python switch 实现多分支选择功能
2020/12/21 Python
python接口自动化框架实战
2020/12/23 Python
美国网上花店:JustFlowers
2017/02/12 全球购物
德国50岁以上交友网站:Lebensfreunde
2020/03/18 全球购物
高级人员简历的自我评价分享
2013/11/03 职场文书
爱心捐书活动总结
2014/07/05 职场文书
国富论读书笔记
2015/06/26 职场文书
工作简报格式范文
2015/07/21 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书
2007年老电脑安装win11会怎么样? 网友实测win11在老电脑运行良好
2021/11/21 数码科技
科学家测试在太空中培育人造肉,用于未来太空旅行
2022/04/29 数码科技