jQuery制作拼图小游戏
源代码思路分析:
【一】如何生成图片网格,我想到两种方法:
(1)把这张大图切成16张小图,然后用img标签的src
(2)只有一张大图,然后每个元素的背景图用css的background-position进行切割定位,这样就需要16个数组[0,0],[-150,0],[-300,0]..........(我采用这种)
【二】图片背景定位数组与布局定位数组
在选择了使用CSS定位切图,就需要生成数据。
需要的css背景定位数组为:[0,0],[-150,0],[-300,0],[-450,0],
[0,-150],[-150,-150],[-300,-150],[-450,-150],
[0,-300],[-150,-300],[-300,-300],[-450,-300],
[0,-450],[-150,-450],[-300,-450],[-450,-450]
它们当中都用到了[0,-150,-300,-450]其中的值(就是我定义图片高,宽150的倍数值),所以就利用这个值通过for(){}自动生成数组
//this.nCol在这里是4---因为我的拼图是4*4 //this.nArea是150,是每张图片的宽,高(600px/4)--大图是600*600 varl=[], p=[]; for(varn=0;n<this.nCol;n++){ l.push(n*(this.nArea+1)); //生成[0,151,302,453]网格的布局定位数组,因为我的效果需要边框(图中的绿色边框),所以与css背景定位数组就不一样了 p.push(-n*this.nArea); //生成了[0,-150,-300,-450]就是上面说的,CSS背景定位值 } for(vari=0;i<this.nLen;i++){ //this.nLen是为16 vart=parseInt(i/this.nCol), k=i-this.nCol*t, aP=[], aL=[]; aP.push(p[k],p[t],i);//这里我给css背景定位数组额外加了i,是为第3步判断用的,不需要拿来设置css属性的,我把它设置为标签的属性里[bg-i] aL.push(l[k],l[t]); this.aBgp[i]=aP; this.aLayout[i]=aL; }
【三】判断是否完成
第二个元素(div)应用了css背景定位 this.aBgp[1](值为[-150,0,1]),而随机分配的布局定位假如是this.aLayout[3](这里的3是随机生成的)(值为[453,0]),那么left:453px,top:0;
挪动这个元素,改变的是它的letf,top值,而不是本身结构的顺序,获取这个元素的left,top的值(假如是挪到left:151px,top:0),然后拿来与this.aLayout[1]的值[151,0](里面的1索引,就是本身标签属性的[bg-i]=1也是this.aBgp[1]的索引)判断,相等就说明这个元素挪动后的位置是正确。
详细代码:
/* version:2.0 */ functionGyPuzzleGame(option){ this.target=$(option.target); this.data=option.data;//图片数据 this.opt=option; this.nLen=option.count;//多少张拼图 this.aColLayout=option.aColLayout||[0,151,302,453];//布局横向数组 this.aRowLayout=option.aRowLayout||[0,151];//布局竖向数组 this.aColBgp=option.aColBgp||[0,-150,-300,-450];//布局横向数组 this.aRowBgp=option.aRowBgp||[0,-150];//布局竖向数组 this.nCol=this.aColLayout.length; this.nRow=this.aRowLayout.length; this.aLayout=[];//布局数组 this.aBgp=[];//css背景定位数组 this.init(); } GyPuzzleGame.prototype={ getRand:function(a,r){ vararry=a.slice(0), newArry=[]; for(varn=0;n<r;n++){ varnR=parseInt(Math.random()*arry.length); newArry.push(arry[nR]); arry.splice(nR,1); } returnnewArry; }, setPos:function(){ for(vari=0;i<this.nLen;i++){ vart=parseInt(i/this.nCol), l=i-this.nCol*t, aP=[], aL=[]; aP.push(this.aColBgp[l],this.aRowBgp[t],i); aL.push(this.aColLayout[l],this.aRowLayout[t]); this.aBgp[i]=aP; this.aLayout[i]=aL; } }, isPass:function(item){ var_that=this, is=0; item.each(function(){ varl=parseInt($(this).css('left')), t=parseInt($(this).css('top')), i=parseInt($(this).attr('data-bgi')); if(l==_that.aLayout[i][0]&&t==_that.aLayout[i][1]){ is++; } }); returnis; }, createDom:function(){ varlayout=this.getRand(this.aLayout,this.nLen); //console.log(layout); for(varn=0;n<this.nLen;n++){ vart=parseInt(n/this.nCol), l=n-this.nCol*t; varhtml=$('<divdata-bgi="'+this.aBgp[n][2]+'"class="puzzle_list"></div>'). css({'left':layout[n][0]+'px', 'top':layout[n][1]+'px', 'background-image':'url('+this.data+')', 'background-position':this.aBgp[n][0]+'px'+''+this.aBgp[n][1]+'px' }); this.target.append(html); } }, move:function(){ var$div=this.target.find('.puzzle_list'), _that=this; var hasElem=function(){ vart=false; $div.each(function(){ if($(this).hasClass("on")){ t=true; } }); returnt; }; //click $div.click(function(){ var$this=$(this); if(hasElem()&&!$this.hasClass("on")){ varindex=$('.on').index(); if($div.eq(index).is(':animated')||$this.is(':animated')){ returnfalse; } varl=$div.eq(index).position().left, t=$div.eq(index).position().top, myl=$this.position().left, myt=$this.position().top; $(this).animate({'left':l,'top':t}); $div.eq(index).css({'z-index':'1'}).animate({'left':myl,'top':myt},function(){ $(this).removeClass("on"); $(this).find('span').remove(); $(this).css({'z-index':'0'}); if(_that.isPass($div)==_that.nLen){ if(typeof_that.opt.success=='function'){ _that.opt.success({target:_that.target}); } } }); } else{ if($this.hasClass("on")){ $this.removeClass("on"); $this.find('span').remove(); } else{ $this.addClass("on").append("<span></span>"); } } }); }, init:function(){ //设置CSS背景定位与元素布局数组 this.setPos(); //创建元素 this.createDom(); //挪动图片 this.move(); } } //实例调用 newGyPuzzleGame({ 'data':'images/03.jpg', 'target':'#pA', 'count':8, 'success':function(opt){ opt.target.append('<divclass="puzzle_mask"></div><divclass="puzzle_pass">恭喜过关</div>'); } });