Web版2048实现

2048是2014年出现的一款游戏,虽然距今已有两年时间,但是依然是让人爱的根本听不下来。我也玩过很长时间,如今网上也有各种版本(不同的语言实现)的2048。但是,我依然想自己实现一次。于是就有了今天的分享。源码地址在这里

分析

2048这个游戏在开始时,界面会出现两个为2的方块,然后玩家可以向上下左右四个方向任意方向操作来移动方块,并向界面再新增一个为2的方块,含有相同数值的方块会合并为一个方块,该方块值为二者相加,由此不断直到方块填满界面且没有可合并方块时,游戏结束。

纵观整个过程,涉及的操作有

  1. 初始化
  2. 移动方块
  3. 合并方块
  4. 插入方块
  5. 游戏是否结束? 未结束那么重复第2到第4步,否则结束游戏

现在就按照上面5个步骤开始代码实现。

定义游戏类

function game(){
    //为了不每次检查是否要合并方块都从DOM去取,所以给类定义一个map一一对应每个方格。
    this.map = [
                [
                    [],[],[],[]
                ],
                [
                    [],[],[],[]
                ],
                [
                    [],[],[],[]
                ],
                [
                    [],[],[],[]
                ]
            ];
    //方块的颜色值,以标识不同的值
    this.color = [
	 	'#99CCCC','#FFCC99','#FFCCCC',
	 	'#FFFF99','#CCCCFF','#CC9966',
	 	'#666666','#CC9999','#993333',
	 	'#CCCC00','#663366','#CC0033',
	 	'#333333','#CCCC00','#FF0033',
	 	'#333399','#999933','#333300'
	 	];
    //玩家操作方向
    this.direction = {
	 	37: 'left',
	 	38: 'up',
	 	39: 'right',
	 	40: 'down'
	 	};
    //获取所有行
    this.tr = (function(){
		    var tbody = document.querySelector('tbody');
		    return tbody.children;
		}());
    //分数
    this.score = 0;
}

初始化

初始化是向界面随意两个位置插入两个方块,位置怎么选是后面每一次操作都会遇到的问题,所以得先有一个方法来指定位置。

获取位置

game.prototype = {
    selectPosition: function(){
        
    }
}

最开始我是随机选择一行i,然后判断这行是否有空余位置(即this.map[i]中是否存在空数组),但是这样会出现问题就是肯能随机10次得到的i都是满员了,所以改作一下这种方式(也不知道这样好不好),先遍历map找出至少还有一个还有位置的行,然后在这些行里随机出一行:

getLine: function(){
			 var line = [];
				for(var i=0; i<4; ++i){
					for(var j=0; j<4; ++j){
						if(!this.map[i][j].length){
							line.push(i);
							break;
						}
					}
				}

				return line;
		},

得到行之后再从得到当前行存在几个空位,从空位中找出一个位置返回。位置得到了,现在就是将方块显示在界面中,所以需要一个插入方块的方法。但是这个方块哪里来呢?所以还需要一个制造方块的工厂。

生产方块

game.prototype.create = function(){

}

颜色选择

由于不同的值,方块颜色不同,怎么来确定选用哪个颜色呢?因为出现的值都是2的n次方,所以我打算由n来选择颜色,代码如下:

game.prototype.color = function(val){
    return Math.log(val)/Math.log(2);
}

插入方块

现在,插入方块所需的条件都已经具备了。so,去吧,皮卡丘!

game.prototype.insert = function(){
    
}

在界面中新增方块过后,需要及时更新map。接下来就是玩家操作了,我们可以在document上注册键盘事件以判断玩家操作。

game.prototype.move = function(){
    var direc = this.direction;
    document.addEventListener('keyup', function(e){
        var keycode = e.keyCode || e.which;
        keycode in direc ? self[direc[keycode]]() : '';
    },false);
}

操作

来到最后一步了,那就是上下左右的四个操作:

game.prototype.up = function(){}
game.prototype.right = function(){}
game.prototype.down = function(){}
game.prototype.left = function(){}

在做完这里之后,我觉得这四个方法可以优化合并成一个,但是没有想到怎么处理。

试玩地址:点击这里