JavaScript实现的拼图算法分析
本文实例分析了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,当然这个参数是可以改的,每个小拼图的宽高越小,它切出来的图就越多。
为了凸显这个函数的灵活性,下面再换种参数进行调用。
window.onload=function(){ //图的原始宽度(原图宽),图的原始高度(原图高),自定每块拼图的宽度(能被原图宽整除),自定每块拼图的高度(能被原图高整除),图片名(需放在img下) Puzzle(500,500,100,100,"beauty.jpg"); }
换成了一张500x500的美女图,切割宽高为100x100
试玩一波游戏先:(为了展示效果降低游戏难度)
PS:这里给大家推荐一款相似的在线工具供大家参考:
在线美女拼图游戏:
http://tools.jb51.net/games/pintu
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》
希望本文所述对大家JavaScript程序设计有所帮助。