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 相关文章推荐
js编码之encodeURIComponent使用介绍(asp,php)
Mar 01 Javascript
Javascript Boolean、Nnumber、String 强制类型转换的区别详细介绍
Dec 13 Javascript
JavaScript分析、压缩工具JavaScript Analyser
Dec 31 Javascript
js简单抽奖代码
Jan 16 Javascript
vue项目中引入noVNC远程桌面的方法
Mar 05 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
Sep 10 Javascript
在Angular中使用JWT认证方法示例
Sep 10 Javascript
在vue中安装使用vux的教程详解
Sep 16 Javascript
Vue 实现前端权限控制的示例代码
Jul 09 Javascript
解决layui checkbox 提交多个值的问题
Sep 02 Javascript
js实现适配移动端的拖动效果
Jan 13 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
May 17 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版(1)
2006/10/09 PHP
PHP 字符串 小常识
2009/06/05 PHP
PHP 简单数组排序实现代码
2009/08/05 PHP
php xml 入门学习资料
2011/01/01 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
PHP时间戳格式全部汇总 (获取时间、时间戳)
2016/06/13 PHP
PHP提取字符串中的手机号正则表达式怎么写
2017/07/17 PHP
php通过header发送自定义数据方法
2018/01/18 PHP
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
2011/12/12 Javascript
使用javascript创建快捷方式的简单实例
2013/08/09 Javascript
一个js导致的jquery失效问题的解决方法
2013/11/27 Javascript
用jquery仿做发微博功能示例
2014/04/18 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
2015/11/13 Javascript
全面解析Bootstrap表单使用方法(表单控件)
2015/11/24 Javascript
分享javascript计算时间差的示例代码
2020/03/19 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
微信小程序微信支付接入开发实例详解
2017/04/12 Javascript
vue实现全选和反选功能
2017/08/31 Javascript
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
2017/12/24 jQuery
[54:51]Ti4 冒泡赛第二轮LGD vs C9 3
2014/07/14 DOTA
Python3+Appium安装使用教程
2019/07/05 Python
Python文件读写w+和r+区别解析
2020/03/26 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
Tensorflow使用Anaconda、pycharm安装记录
2020/07/29 Python
使用CSS3的背景渐变Text Gradient 创建文字颜色渐变
2014/08/19 HTML / CSS
大学生毕业求职自荐书范文
2014/02/04 职场文书
党委书记个人对照检查材料
2014/09/15 职场文书
镇党委书记群众路线整改措施思想汇报
2014/10/13 职场文书
音乐教师个人工作总结
2015/02/06 职场文书
休假证明书
2015/06/24 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
Go 语言结构实例分析
2021/07/04 Golang
JavaScript分页组件使用方法详解
2021/07/26 Javascript
css如何把元素固定在容器底部的四种方式
2022/06/16 HTML / CSS