一个简单的2048小游戏

2048小游戏的核心是:通过控制键盘上的“上”、“下”、“左”、“右”键来实现数字的移动、相加、以及生成新的数字。
2048页面图
上图为运行后的结果,我随便操作了几下,可以看到图片上有数字2,数字4,数字8,数字16,数字32,其中只有2和4是可以随机生成的,其他的都是根据上下左右操作获得的,下面提供2048的js代码:

var game={
    score :0,			//分数
    status :1,			//游戏处于的状态
    gameover :0,		//游戏结束
    gamerunning :1,		//游戏进行中
    data : [],
    start :function(){                  //开始
        this.status=this.gamerunning;
        this.score=0;
        this.data=[];	//生成一个数组用来存放格子里的数字
        for(var r=0;r<4;r++){
            this.data[r]=[];
            for(var c=0;c<4;c++){
               this.data[r][c]=0;	//初始化每个格子,使其值为0
            }
        }
            this.randomNum();	//在一个随机的格子上随机生成2或4
            this.randomNum();
            this.dataView();
            console.log(this.data);
    },
    randomNum:function(){                           //随机数
        var r=Math.floor(Math.random()*4);
        var c=Math.floor(Math.random()*4);
        if(this.data[r][c]==0){
            var num=Math.random() >0.2 ? 2 : 4;//三元表达式随机生成2或4
            this.data[r][c]=num;
        }else{	
        //这边我用的是else重新调用函数,也可以通过while死循环和break来实现在没有数值的格子上随机生成2或4.
            this.randomNum();
        }
    },
    dataView : function(){                         //数据可视化
        for(var r=0;r<4;r++){
            for(var c=0;c<4;c++){
                var div=document.getElementById("c"+ r + c);//通过不同的id名获取对应的div元素节点
                if(this.data[r][c]!=0){		//判断数字不为0(初始值),就将该数字显示在页面上
                    div.innerHTML=this.data[r][c];
                    div.className="cell n"+this.data[r][c];//通过修改class名来实现不同数字会有不同的样式
                }else{
                    div.innerHTML="";	//没有数值就不显示内容
                    div.className="cell";//class名为初始值
                }
            }
        }
        document.getElementById("score01").innerHTML=this.score;//把分数显示在页面上
        if(this.status==this.gameover){
            document.getElementById("score02").innerHTML=this.score;
            document.getElementById("gameover").style.display="block";
        }
        else{
            document.getElementById("gameover").style.display="none";
        }
    },//游戏结束时修改元素样式使其显现在页面上
    isGameover :function(){                             //游戏结束
        for(var r=0 ;r<4;r++){
            for(var c=0;c<4;c++){
                if(this.data[r][c]==0){	//如果还有格子的数值是0,证明游戏还没结束
                    return false;
                }
                if(c<3){	
                    if(this.data[r][c]==this.data[r][c+1]){
                        return false;
                    }
                }
                if(r<3){
                    if(this.data[r][c]==this.data[r+1][c]){
                        return false;
                    }
                } //如果有上下或左右相邻的数是一样的,那么游戏还没有结束
            }
        }
        return true;//如果以上情况都没有,返回true,游戏结束.
    },
    moveLeft:function(){                        //点击左键
        var before=String(this.data);	//一个不为0的数
        for(var r=0; r<4;r++){
            this.moveLeftRow(r);
        }
        var after =String(this.data) //同一行相邻的另一个数(可能为0(就是格子上没有数))
        if(before!=after){	
            this.randomNum();  //如果两数不相等,在随机位置生成2或4;
            if(this.isGameover()){
                this.status=this.gameover; //判断游戏是否结束
            }
            this.dataView();	//渲染页面
        }
    },
    moveLeftRow:function(r){	//单独抽出一行进行写逻辑
        for(var c=0;c<3;c++){  //最左边的不需要移动,所以遍历3次
            var nextc=this.getNextinRow(r,c);
            // 找出r行c列后面不为0的数据的位置保存至nextc中
            if(nextc !=-1){	//这一行有需要移动的
                if(this.data[r][c]==0){//一定是把所有需要移动的数据移动到靠左的位置
                    this.data[r][c]=this.data[r][nextc];
                    this.data[r][nextc]=0;
                    c--;//c留在原地继续左移
                }else if(this.data[r][c]==this.data[r][nextc]){
                    this.data[r][c]=this.data[r][c]*2;
                    this.score +=this.data[r][c];   //分数
                    this.data[r][nextc]=0;                                          
                }
            }
            else{
            // 这一行中没有需要移动的数据
                break;
            }
        }
    },
    getNextinRow: function(r,c){
        for(var i=c+1;i<4;i++){
        // 如果数据不为0,表示找到了,返回i,i对应的是当前数据的列下标
            if(this.data[r][i]!=0){
                return i;
            }
        }
        return -1;
    },
    moveUp: function(){                             //向上
        var before=String(this.data);
        for(var c=0;c<4;c++){
            this.moveUpCell(c);
        }
        var after =String(this.data)
        if(before!=after){
            this.randomNum();
            if(this.isGameover()){
                this.status=this.gameover;
            }
            this.dataView();
        }
    },
    moveUpCell:function(c){
        for(var r=0;r<3;r++){
            var nextr=this.getUpCell(r,c);
            if(nextr!=-1){
                if(this.data[r][c]==0){
                    this.data[r][c]=this.data[nextr][c];
                    this.data[nextr][c]=0;
                    r--;
                }else if(this.data[r][c]==this.data[nextr][c]){
                    this.data[r][c]=this.data[nextr][c]*2;
                    this.score +=this.data[r][c];
                    this.data[nextr][c]=0;
                }
            }
            else{
                break;
            }
        }
    },
    getUpCell :function(r,c){   //向上
        for(var i=r+1;i<4;i++){
            if(this.data[i][c]!=0){
                return i;
            }
        }
        return -1;
    },
    getRightRow :function(r,c){            //向右
        for(var i=c-1;i>=0;i--){
            if(this.data[r][i]!=0){
                return i;
            }
        }
        return -1;
    },
    moveRightRow: function(r){
        for(var c=3;c>=0;c--){	
        //c需要=3,不然移动时会移动不到最右边(别问我怎么知道的!!!)
            var nextc=this.getRightRow(r,c);
            if(nextc !=-1){
                if(this.data[r][c]==0){
                    this.data[r][c]=this.data[r][nextc];
                    this.data[r][nextc]=0;
                    c++;
                }else if(this.data[r][c]==this.data[r][nextc]){
                    this.data[r][c]=this.data[r][c]*2;
                    this.score +=this.data[r][c];   
                    this.data[r][nextc]=0;                                          
                }
            }
            else{
                break;
            }
    }
    },  
    moveRight: function(){					//向右
        var before=String(this.data);
        for(var r=3;r>=0;r--){
            this.moveRightRow(r);
        }
        var after =String(this.data)
        if(before!=after){
            this.randomNum();
            if(this.isGameover()){
                this.status=this.gameover;
            }
            this.dataView();
        }
    },
    getPreCell :function(r,c){          //向下
        for(var i=r-1;i>=0;i--){
            if(this.data[i][c]!=0){
                return i;
            }
        }
        return -1;
    },
    moveDownCell: function(c){
        for(var r=3;r>=0;r--){
            var nextr=this.getPreCell(r,c);
            if(nextr !=-1){
                if(this.data[r][c]==0){
                    this.data[r][c]=this.data[nextr][c];
                    this.data[nextr][c]=0;
                    r++;
                }else if(this.data[r][c]==this.data[nextr][c]){
                    this.data[r][c]=this.data[r][c]*2;
                    this.score +=this.data[r][c];   //分数
                    this.data[nextr][c]=0;                                          
                }
            }
            else{
                break;
            }
    }
    },  
    moveDown: function(){               //向下移动
        var before=String(this.data);
        for(var c=3;c>=0;c--){
            this.moveDownCell(c);
        }
        var after =String(this.data)
        if(before!=after){
            this.randomNum();
            if(this.isGameover()){
                this.status=this.gameover;
            }
            this.dataView();
        }
    },
}
game.start();  //调用函数,游戏开始
document.onkeydown=function(event){
    if(event.keyCode==37){
        game.moveLeft();
    }
    else if(event.keyCode==38){
        game.moveUp();
    }
    else if(event.keyCode==39){
    game.moveRight();
    }
    else if(event.keyCode==40){
        game.moveDown();
    }
}

上面把向左移动介绍的比较详细,向右,向上,向下的函数方法和向左方法差不多类似,只需要修改少量数据就行。
移动逻辑:根据需要移动的方向,从左往右,从上往下…循环来找第一个非零的数据在数组中的下标,循环查找完一行(列)中的所有数据,然后通过下标赋值来实现移动,之后判断相邻数是否相同,相同就相加,再循环操作每一行(列)的数据,判断游戏是否结束,没有就继续随机生成2或4;通过键盘按键点击事件触发对应的函数,实现2048小游戏。

快来自己写一个,看看可以玩到多少分。
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值