JavaScript实现2048小游戏

首先要明白该游戏怎么玩,即

在 4*4 的16宫格中,您可以选择上、下、左、右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合并,组成更大的数字,每次移动或合并后会自动增加一个数字。当16宫格中没有空格子,且四个方向都无法操作时,游戏结束。

 

首先,把16宫格看成是矩阵的形式

游戏开始时,随机生成两个数字,2或者4,出现在矩阵中任意位置

这部分是通过类名emptyItemnonEmptyItem来实现的。

步骤:

① 随机生成一个数字2或者4

② 获取所有空元素(类名emptyItem

③ 随机选择一个空元素,将生成的数字填充到空元素中,并将类名emptyItem移除,添加类名nonEmptyItem,即非空元素

④ 重复①、②、③步,再随机生成一个数字填充到随机的位置。

游戏的核心在于移动

移动有四个方向:上、下、左、右。实现思路如下:

如果触发向左移动
  遍历所有非空元素
    如果当前元素在第一个位置
           不动
    如果当前元素不在第一个位置
      如果当前元素左侧是空元素    
              向左移动
      如果当前元素左侧是非空元素    
        如果左侧元素和当前元素的内容不同    
                  不动
        如果左侧元素和当前元素的内容相同    
                  向左合并
 

如果触发向右移动
  遍历所有非空元素
    如果当前元素在最后一个位置     
           不动
    如果当前元素不在最后一个位置
      如果当前元素右侧是空元素   
              向右移动
      如果当前元素右侧是非空元素    
        如果右侧元素和当前元素的内容不同    
                  不动
        如果右侧元素和当前元素的内容相同    
                  向右合并

向上移动 和 向下移动的思路同上。

判断游戏是否结束

获取所有元素
获取所有非空元素
如果所有元素的个数 == 所有非空元素的个数
  循环遍历所有非空元素
    上面元素存在 && (当前元素的内容 == 上面元素的内容)   return
    下面元素存在 && (当前元素的内容 == 下面元素的内容)   return
    左边元素存在 && (当前元素的内容 == 左边元素的内容)   return
    右边元素存在 && (当前元素的内容 == 右边元素的内容)   return
   以上条件都不满足,Game Over! 

 

来看效果图

可以看到,游戏框上方是一些文字描述,游戏框外面是一个大的灰色的div,里面设定有4行,每行有4个单元格,一共是16个单元格。使用bootstrap的栅栏布局可以写成div.container>div.main>h2.title+h3.highestScore+h3.currentScore+div.panel.col-md-6>(div.row>(div.item.emptyItem)*4)*4,其中panel样式的div就是表示游戏框,row样式表示每一行,row里的每一行用小div来充当单元格,辅助说明的样式使用item表示单元格,emptyItem样式表示空单元格,nonEmptyItem表示非空单元格,然后根据矩阵中单元格的位置,再给各自的单元格添加样式,如x0y0,x1y0......根据这些样式,单独给每个单元格自定义一个x属性和y属性,x=“0”,y=“0”......具体作用在JS中体现。

html代码

		

2048小游戏

最高得分:

当前得分:

请通过键盘方向键进行操作

在css代码中首先进行css初始化,然后根据效果图,自行配置。

在js文件中,首先进入游戏初始化函数gameInit(),

gameInit()中先将分数初始化,然后给“刷新”按钮绑定监听事件指向gameRefresh()函数,然后调用两次newItem函数添加两个随机元素(2或4),然后调用refreColor()函数遍历单元格,根据单元格文本值刷新背景色。

newItem()函数中,根据一个包含2和4的数组,随机选出一个,然后遍历所有空白单元格(有样式emptyItem的)然后随机选择一个,添加样式nonEmptyItem,删除样式emptyItem,然后修改文本值为2或4的随机数。

refreshColor()函数中,根据样式item,将所有单元格依据文本值进行背景颜色的修改。

全局添加键盘响应事件,根据keyCode的值,选择方向键的不同事件,先将isNewRndItem=false;表明每次移动之前将产生新元素的标记置为false,调用move函数和isGameOver()函数。

move()函数中,首先遍历所有非空的单元格(有nonEmptyItem样式),根据传入的方向direction参数,决定正反向遍历,其中正向遍历为左和上,反向遍历为右和下。

对于左移动和上移动,需要正向遍历有数值的单元格,当需要移动的时候,下标小的元素可以先往上移动或往左移动,
反之,对于右移动和下移动,需要反向遍历单元格,让下标大的单元格先移动,如果下标小的先移动,如果同一行有单元格的话,小的单元格会被大单元格挡住。在遍历的每个单元格中,调用moveItem()函数。

moveItem()函数中,首先调用getSideItem()函数,得到其旁边元素的信息(有或无,有值或空),根据旁边元素的样式和文本值,进行操作(移动,合并等)。

其余函数自行查看。

window.onload=function(){
	var isNewRndItem=false;//是否产生新元素
	var score=0;//初始分数
	var maxScore=0//最高分数
	if(localStorage.maxScore){//如果保存了最高分数
		maxScore=localStorage.maxScore-0;
	}
	else{
		maxScore=0;
	}
	//初始化游戏
	gameInit();
	
	
	//初始化设置
	function gameInit(){
		//初始化分数
		document.getElementById('score').innerHTML=score;
		
		//初始化最高分数
		document.getElementById('highestScore').innerHTML=maxScore;
		
		//为刷新按钮绑定刷新事件
		document.getElementById('refreshButton').onclick=gameRefresh;
		
		//初始化随机添加两个元素
		newItem();
		newItem();
		
		//刷新颜色
		refreshColor();
		
	}
	
	
	//重新开始游戏
	function gameRefresh(){
		
		//将所有单元格的nonEmptyItem样式清除并且数值清空
		var items=document.getElementsByClassName('item');
		for(var i=0;i=0;i--){//反向遍历
				var currentItem=nonEmptyItems[i];
				moveItem(currentItem,direction);				
			}
		}		
		
		if(isNewRndItem){//遍历完一遍后产生新的元素并刷新颜色
			newItem();
			refreshColor();
		}
	}


	//判断游戏是否结束,即遍历所有元素,
	function isGameOver(){
		var nonEmptyItems=document.getElementsByClassName('nonEmptyItem');
		var allItems=document.getElementsByClassName('item');
		if(nonEmptyItems.length==allItems.length){//所有单元格铺满,检查是否有可以合并的两个单元格
			for(var i=0;i

参考地址:https://github.com/nnngu/js_game_2048

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(JavaScript)