这个小游戏写了大概有半年了吧,现在拿出来讲一讲。源码请看github仓库
不过没有分离代码,就把所有代码都挤在一堆了…
2048游戏链接
先来分析分析2048的结构。之后再会讲到怎么用js代码实现。
上图先
注意到有12个小方格用来容纳数字,小方格的样式容易写吧,就不赘述了。而且方格数目是不变的,那么这里直接用12个div容器也未尝不可。我的布局方式是大容器包含12个方格,中等的容器包含了一行的4个方格,这样写只是为了读取的时候方便一点。
贴一份标签吧:(贴标签有点麻烦,还是上图吧)
之后就是操作按钮了(简单,就不说了),愿意的话可以尝试用js触控事件来写,这样就更接近移动端APP
刚开始写的时候,布局并不是很熟练。又不想给每个放数字的容器都规定一个位置,实在是太麻烦re…如果把每行都放在一个容器里面,操作起来就简单多了(只需对行操作,行里面的元素加margin就行)。但是!!!我虽然是这样布局div的,之后看代码才发现,我竟然用js来定位,实在不符合“结构”“表示”“行为”分离这一原则。
OK,布局就先到这了
初始化
注意到每次运行2048在16个方格中随机两个方格就会出现2或4。这里的随机用伪随机就可以了,取0~15两个不同的随机数(方格),再随机把2或4填入方格。(这个就不贴代码了)
移动逻辑
下面是数字向左移动的一段代码,先移动,再计算,再移动
i=1;n=1;
var flag=Array(6);
for(n=1;n<5;n++)
{
cellValue=cell[n-1].firstChild.nodeValue;
if(cellValue==” “){flag[i]=1;i++;}else{flag[i]=0;i++;};
//对第一行,如果方格的内容为空,相关旗帜标记为1,否则为0
}
for(count=1;count<15;count++)
for(i=1;i<5;i++)
{
if((flag[i]!=0)&&(flag[i+1]==0))
//前一个方格内容为空后一个方格有内容,则将后一个方格数字移动到前一个,并清空后一个方格内容
{
cell[i-1].firstChild.nodeValue=cell[i].firstChild.nodeValue;
cell[i].firstChild.nodeValue=” “;
flag[i+1]=1;
flag[i]=0;
}
}
for(m=1;m<4;m++)
{
if((cell[m-1].firstChild.nodeValue==cell[m].firstChild.nodeValue)&&(cell[m-1].firstChild.nodeValue!=” “)){cell[m-1].firstChild.nodeValue=cell[m-1].firstChild.nodeValue*2;cell[m].firstChild.nodeValue=” “;}
//前后方格内容相同,则前一个方格内容值加倍,后一个方格清空,且保证所有相邻数字已相加
}
i=1;n=1;
//继续移动
var flag=Array(6);
for(n=1;n<5;n++)
{
cellValue=cell[n-1].firstChild.nodeValue;
if(cellValue==” “){flag[i]=1;i++;}else{flag[i]=0;i++;};
}
for(count=1;count<15;count++)
for(i=1;i<5;i++)
{
if((flag[i]!=0)&&(flag[i+1]==0))
{
cell[i-1].firstChild.nodeValue=cell[i].firstChild.nodeValue;
cell[i].firstChild.nodeValue=” “;
flag[i+1]=1;
flag[i]=0;
}
}
对每个方向的移动做成函数,在键盘控制或触摸控制中调用就好了。
因为代码没有做优化,所以又臭又长。每个方向的移动对每一行(列)应该都可以放在一个大循环里面。不过即使是解释性语言,对这一点计算量而言,执行起来还是很快的。另外,在每次数字移动的时候还可以加上动画,这样移动就不会显得这么难看。
生成新数
每次移动后,都要在一个空方格内生成2或4。我们可以在移动完成后,遍历所有方格,找到内容为空的随机取一个方格再随机填2、4就好了。
输赢判断
遍历16个方格,2048是否出现,再看看有没有空格,相邻方格内容是否相同。这个还是比较好写的。
键值获取
window.onkeydown=function(e)
{
e=e||window.event;
var code=e.which||e.keycode;
alert(code);
}
看看alert出来的结果是什么就好了
总结
初始化→→→获取键值→→→移动→→→输赢判断→→→生成新数