日期:2014-05-16  浏览次数:20426 次

[javascript]9宫格拖拽拼图游戏 puzzle



1.跨浏览器,主流浏览器都可以运行
2.纯javascript开发。
3.配置实用方便。
4.二次开发简单,易用。


传送门 在线试玩

成品预览,见附近



  用一张图片用坐标的方式生成拼图单元格,类似css sprite。大致思路是,每个单元格有对应的两个索引,由数据驱动显示。创建实例时吧0-9乱序排列,每个单元格对应两个索引,一个是真实所在位置的索引,一个是记录现在位置的索引。拖动图片的时调整记录现在位置的索引,去对比原始数组如果值相等,那么就可以确定拼图完成。
1.乱序排列[0-9]的数组生成一个新数组,来产生拼图单元格的排序。为了避免生成不符合需求的数组,比较然后递归。

indicator.fn.unordered = function (array) {  //乱序排列
      array=array || [0,1,2,3,4,5,6,7,8,9];
      if (({}).toString.call(array).indexOf('Array') === -1) return;
      var arr = [], value = array.toString();
      arr = array.sort(function () {
         return Math.random() > 0.5 ? -1 : 1;
     });
     (arr.toString() === value) && arguments.callee(array);
     return arr;
};




2.主要难点在于拖拽时实时去检测现在单元格与其他单元格的位置关系,判断拖动的单元格是不是进入其他单元格而不是在自己的占位单元格。如果不符合要求,则把拖拽元素放回原始位置。

indicator.fn.checkPosition=function(e){ //检查单元格位置,符合条件插入 不符合条件放回原处
     e=that.getEvent(e);
     var i=that.htmls.length,size=null,pointer = [e.clientX,e.clientY];
     for(;i--;){
    size=that.getClinetRect(that.htmls[i]);
    if(size.top < pointer[1] && size.bottom>pointer[1]){
        if(size.left<pointer[0] && size.right>pointer[0]){
        that.htmls[i]===indicator.currentTarget || that.replaceElement(that.htmls[i]);
        }else{
         that.restore();
        }
    }
    }
};

  
3.为了避免拖拽元素时导致单元格产生的重新排列导致的错位,所以要产生一个占位单元格,这占位的单元格克隆自拖拽单元格。

indicator.fn.createPlaceholder=function(T){
   var node=T.cloneNode(true);
   node.innerHTML='';
   node.style.display='none';
   node.className='placeholder';
   T.parentNode.insertBefore(node,T);
   that.placeholder=node;
};


4.界定拖拽单元格是否进入其他单元格,左顶点大于当前单元格的top,left但是小于当前单元格的bottom,right

indicator.fn.checkPosition=function(e){ //检查单元格位置,符合条件插入 不符合条件放回原处
    e=that.getEvent(e);
    var i=that.htmls.length,size=null,pointer = [e.clientX,e.clientY];
    for(;i--;){
          size=that.getClinetRect(that.htmls[i]);
          if(size.top < pointer[1] && size.bottom>pointer[1]){
                if(size.left<pointer[0] && size.right>pointer[0]){
                   that.htmls[i]===indicator.currentTarget || that.replaceElement(that.htmls[i]);
               }else{
                     that.restore();
               }
         }
    }
};



5.调整单元格时,要改变拖拽单元个的两个记录位置的属性,还要改变当前单元格的两个位置属性,再调整记录位置的数组
这里的处理我觉得也是最繁复最有挑战的地方,修改了很久

       indicator.fn.replaceElement=function(targetNode){ //摆放单元至正确位置
 
    var current=indicator.currentTarget,k1=that.htmls,k2=that.sn,temp,j=0,k=0,a1=[-1,-1],a2=null,a3=-1,arr=[],parent=that.parent.children[0],li;
 
    current.style.position='static';
 
    that.index=[];
 
    for(;k<k1.length;k++){
        if(targetNode===that.htmls[k]) {a1[0]=k;}
        if(current===that.htmls[k]) {a1[1]=k;}
    }
    a1.sort();
 
    a2=k1[a1[0]];
    k1[a1[0]]=k1[a1[1]];
    k1[a1[1]]=a2;
 
    a3=k2[a1[0]];
    k2[a1[0]]=k2[a1[1]];
    k2[a1[1]]=a3;
 
    parent.innerHTML='';
 
    for(;j<k1.length;j++){
        li=that.htmls[j];
        that.index.push(that.htmls[j].index);
        try{parent.appendChild(li)}catch(e){}
    }
 
};


6.在释放鼠标时,检查原始数组和记录位置数组的值十分相等,确定是不是拼图完成。

that.index.join('')===that.sn.sort().join('')

?