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
var l = [], p = []; for(var n=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(var i=0;i<this.nLen;i++){ // this.nLen 是為 16
var t = 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 */ function GyPuzzleGame(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){ var arry = a.slice(0), newArry = []; for(var n=0;n<r;n++){ var nR = parseInt(Math.random()*arry.length); newArry.push(arry[nR]); arry.splice(nR,1); } return newArry; }, setPos:function(){ for(var i=0;i<this.nLen;i++){ var t = 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(){ var l = 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 ++; } }); return is; }, createDom:function(){ var layout = this.getRand(this.aLayout,this.nLen); // console.log(layout); for(var n=0;n<this.nLen;n++){ var t = parseInt(n/this.nCol), l = n - this.nCol*t; var html = $('<div data-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(){ var t = false; $div.each(function(){ if($(this).hasClass("on")){ t = true; } }); return t; }; // click $div.click(function(){ var $this = $(this); if(hasElem()&&!$this.hasClass("on")){ var index = $('.on').index(); if($div.eq(index).is(':animated')||$this.is(':animated')){ return false; } var l = $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(); } } //實例調用 new GyPuzzleGame({ 'data':'images/03.jpg', 'target':'#pA', 'count':8, 'success':function(opt){ opt.target.append('<div class="puzzle_mask"></div><div class="puzzle_pass">恭喜過關</div>'); } });
------------------------------------------分割線------------------------------------------
jQuery權威指南 PDF版中文+配套源代碼 http://www.linuxidc.com/Linux/2013-10/91059.htm
jQuery實戰 中文PDF+源碼 http://www.linuxidc.com/Linux/2013-09/90631.htm
《jQuery即學即用(雙色)》 PDF+源代碼 http://www.linuxidc.com/Linux/2013-09/90383.htm
鋒利的jQuery(第2版) 完整版PDF+源碼 http://www.linuxidc.com/Linux/2013-10/91527.htm
jQuery完成帶復選框的表格行高亮顯示 http://www.linuxidc.com/Linux/2013-08/89406.htm
jQuery基礎教程(第4版) PDF 完整高清版+配套源碼 http://www.linuxidc.com/Linux/2014-03/98162.htm
--------------------------------------分割線 --------------------------------------
jQuery 的詳細介紹:請點這裡
jQuery 的下載地址:請點這裡