2048游戏的实现,如果不考虑数字滑动的动画效果,就很简单了。稍难的是数字滑动的动画效果。
2048游戏规则简单,一共个6个格子,可以4个方向滑动,相同的数字相遇就合并,一个数字翻倍,一个数字清0,清0的腾出一个格子。
当没有空白格子,用来出现新的数字时,游戏结束。
分析2018游戏的数字移动规则,4行(列),4个方向的移动,其实逻辑都一样,不一样的是要移动的方向和,要移动的数字。
我把16个数字放一个数组,索引0-15。0 表示UI不显示,表示没有数字。
4个方向,每个方向4行(列)的数字移动逻辑一样,只需要对一个方向,一行的移动做分析就可以了。其他的逻辑一致。
一个方向,一行就最多只有4个数字。我用从右到左,第一行来分析。
从右到左,第一行的4个数字索引:0,1,2,3
我把0当作初始索引index,他不用动,其他的3个数字向他移动,其他3个数字的索引递增值n,写一个函数处理一个方向,一行的数字合并及移动。
我用的方法比较笨,用了一个临时数组保存合并后的数字及合并前的索引。
再根据合并后的索引和合并前的索引来计算每个数字应该移动的格子数。
应该有更好的方法来实现,不需要3个循环,或许一个循环就OK。好在每个循环最多4次。性能影响不大。
game.line=function(index,n) { var tmp=[]; for(var i=index,c=0;c<4;i+=n,c++) { if(game.nums[i]) tmp.push({"index":i,"v":game.nums[i]}); } for(var c=0;c<tmp.length-1;c++) { if(tmp[c].v==tmp[c+1].v && tmp[c].v>0 ){ tmp[c].v*=2; tmp[c+1].v=-1; game.nums[tmp[c].index] = tmp[c].v; game.nums[tmp[c+1].index]=tmp[c].v; game.curScore+=10; } } var count=0; for(var c=0;c<tmp.length;c++){ if(game.nums[tmp[c].index]) { if(tmp[c].v<0){count++;} setTimeout(( function(e,to){ return function (){game.move(e.index, to);}; })(tmp[c],index+n*(c-count)),1); } } };
有了每个方向,每一行的处理,其他的就简单了,定义一个数组配置 初始索引index和下一个数子索引递增值x,下一行初始索引递增值y,就可以循环处理所有4个方向,4行的处理了。
// fx 左0 上1 右2 下3 // x: 同一行下一个数子索引递增值x, index +x 后为此行的下一个元素, // 下一行初始索引递增值y, index +y 后为下一行的第一个元素, var p=[{index:0,x:1,y:4},{index:0,x:4,y:1}, {index:3,x:-1,y:4},{index:12,x:-4,y:1}][fx]; for(var i=0;i<4 ;i++) {
//p.index+i*p.y 一个指定方向的4行的初始索引 game.line(p.index+i*p.y,p.x);//}
核心代码就这些了,数字移动用css3动画。游戏不设置2048的上限。增加道具炸弹,一个炸弹一次可以炸掉任意一个数字。
手机上面,实现滑屏操作,宽度自适应。
试玩及源码: