• 2048小游戏


    实现的效果图

    1.游戏开始

    2.游戏结束

    HTML页面

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <link rel="stylesheet" href="2048.css" />
        </head>
        <body>
            <div class="header">
                SCORE:<span id="score1"></span><br />
            </div>
            <div id=grid>
                <!--第一行-->
                <div id="c00" class="cell"></div>
                <div id="c01" class="cell"></div>
                <div id="c02" class="cell"></div>
                <div id="c03" class="cell"></div>
                <!--第二行-->
                <div id="c10" class="cell"></div>
                <div id="c11" class="cell"></div>
                <div id="c12" class="cell"></div>
                <div id="c13" class="cell"></div>
                <!--第三行-->
                <div id="c20" class="cell"></div>
                <div id="c21" class="cell"></div>
                <div id="c22" class="cell"></div>
                <div id="c23" class="cell"></div>
                <!--第四行-->
                <div id="c30" class="cell"></div>
                <div id="c31" class="cell"></div>
                <div id="c32" class="cell"></div>
                <div id="c33" class="cell"></div>            
            </div>
            <div class="gameover" id="gameover">
                <p>
                    GAME OVER!<br />
                    SCORE:<span class="finalscore" id="final">0</span><br>
                    <a href="javascript:game.strt()" class="try">TRY AGAIN</a>
                </p>
            </div>
            <script src="2048.js"></script>
        </body>
    </html>

    CSS页面

    #grid{
         480px;
        height: 480px;
        margin: 0 auto;    
        position: relative;
        background-color: #bbada0;
        border-radius: 15px;
    }
    .cell{
         100px;
        height: 100px;
        background-color: #ccc0b3;
        position: absolute;
        text-align: center;
        font-size: 60px;
        line-height: 100px;
    }
    [id^="c0"]{top: 16px;}
    [id^="c1"]{top: 132px;}
    [id^="c2"]{top: 248px;}
    [id^="c3"]{top: 364px;}
    [id$="0"]{left: 16px;}
    [id$="1"]{left: 132px;}
    [id$="2"]{left: 248px;}
    [id$="3"]{left: 364px;}
    
    .n2{background-color:#eee3da}
    .n4{background-color:#ede0c8}
    .n8{background-color:#f2b179}
    .n16{background-color:#f59563}
    .n32{background-color:#f67c5f}
    .n64{background-color:#f65e3b}
    .n128{background-color:#edcf72}
    .n256{background-color:#edcc61}
    .n512{background-color:#9c0}
    .n1024{background-color:#33b5e5}
    .n2048{background-color:#09c}
    .n4096{background-color:#a6c}
    .n8192{background-color:#93c}
    .n8,.n16,.n32,.n64,.n128,.n256,.n512,.n1024,.n2048,.n4096,.n8192{color:#fff}
    .n1024,.n2048,.n4096,.n8192{font-size:40px}
    
    .header{    
        height: 50px;
         480px;
        color: #00000;
        margin: 0 auto;
        font-size: 40px;
        font-weight: bold;
        margin-bottom: 20px;    
    }
    
    #gameover{
        position: absolute;
        background-color: rgba(50,50,50,0.5);
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        color: #8f7b63;
    }
    .gameover>p{
         300px;
        height: 200px;
        background-color: #fff;
        border: 1px solid #edcf72;
        border-radius: 15px;
        position: absolute;
        left: 50%;
        top: 50%;
        margin-top: -100px;
        margin-left: -150px;
        font-size: 30px;
        font-weight: bold;
        text-align: center;
        line-height:1.5em;
        padding-top:50px ;
    }
    .try{
        display: block;
         200px;
        height: 50px;
        border-radius: 8px;
        background-color: #8f7b63;
        position: absolute;
        left:50px;
        color: #fff5e9;
        text-decoration: none;
    }
    .gameover>p span{
        color: #f00;
        font-size: 40px;
    }
    #score1{
        color: #f00;
        font-size:40px;
    }

    JS页面

    var game={
        date:null,//建立一个空的二维数组
        RN:4,//每一行
        CN:4,//
        score:0,//分数
        state:1,//保存运行中的状态 1表示运行中 0表示结束
        RUNNING:1,//运行中的状态
        GAMEOVER:0,//结束状态
    
        strt(){//开始游戏    
            //将遮罩层隐藏 开始游戏之前清理遮罩层
            document.getElementById("gameover").style.display="none";
            //设置游戏状态  重置游戏为运行中
            this.state=this.RUNNING;
            //游戏开始时分数清零
            this.score = 0; 
            //新建空数组date
            this.date=[];
            //r从0开始,到RN结束
            for(var r=0;r<this.RN;r++){
                this.date[r]=[];
                //c从0开始,到CN结束
                for(var c=0;c<this.CN;c++){
                    //设置date中r行c列的值为0
                    this.date[r][c]=0
                }            
            }
            this.randomNum();
            this.randomNum();
            this.updateView();
            console.log(this.date.join("
    "));    
            document.onkeydown=function(event){
                switch(event.keyCode){
                    case 37://左移                    
                        game.moveLeft();  
                        break;
                    case 38://上移                    
                        game.moveTop();                
                        break;
                    case 39://右移    
                        game.moveRight();
                        break;
                    case 40://下移
                        game.moveDown();
                        break;
                }
            }
        },    
        randomNum(){ //随机一个数字     
            while(true){
                //在0~RN-1之间生成随机数r
                r = Math.floor(Math.random() *this.RN);
                //在0~CN-1之间生成随机数c
                c = Math.floor(Math.random() *this.CN); 
                //如果
                if(this.date[r][c]==0){
                    this.date[r][c] = (Math.random() < 0.5) ? 2 : 4; 
                    //-console.log(this.date[r][c]);
                     break;
                }                               
                }
        },
        updateView(){
            //将date中数据更新到每一个div中,修改div中数字的同时,修改div样式
            for(var r=0;r<this.RN;r++ ){//遍历二维数组
                for(var c=0;c<this.CN;c++){
                    //将date中r行c列中的数字获取存储在变量n中
                    var n=this.date[r][c];
                    //找到id为'c'rc的div
                    var div=document.getElementById("c"+r+c);
                    if(n==0){//如果n等于0 div中的数字清空  恢复div的class为cell
                        div.innerHTML="";   
                        div.className="cell";
                    }else{//如果不等于0 设置div中的数字为n
                        div.innerHTML=n;
                        div.className="cell n"+n;
                    }
                }
            } //二维数组遍历结束
            //将分数显示在页面中
            //通过id找到score的span,设置其内容为score属性
            document.getElementById("score1").innerHTML = this.score;
            this.state=this.isgameover()?this.GAMEOVER:this.RUNNING;
            var div= document.getElementById("gameover");
            //根据游戏状态判断游戏是否结束,并且判断gameover是否显示
             if(this.state == this.GAMEOVER){
                 //显示gameover 找到final的span  设置内容为score
                 div.style.display="block";
                 document.getElementById("final").innerHTML=this.score;
             }else{
                 //否则隐藏gameover的div
                 div.style.display="none";
             }
        },
        isgameover(){ //判断游戏是否结束
            //遍历date
            for(var r = 0;r<this.RN;r++){
                for(var c = 0;c<this.CN;c++){
                    if(game.date[r][c] == 0){   //如果有等于零的情况,则游戏继续
                        return false;
                    }
                    if(c<this.RN-1){//检测同一行之间是否有相同
                        if(game.date[r][c] == game.date[r][c+1]){
                            return false;
                        }
                    }
                    if(r<this.CN-1){//检测同一列之间是否有相同
                        if(game.date[r][c] == game.date[r+1][c]){
                            return false;
                        }
                    }
                }
            }
            return true;//如果条件全都不满足,表示游戏结束
        },
    //左移开始
        moveLeft(){//左移所有行
            // 为数组拍照保存到before中
            var before=String(this.date);
            // r从0开始,到<RN结束
            for(var r=0;r<this.RN;r++){
                // 左移第r行  moveLeftInRow(r) ---- 可以单独完成一件事情  反复被使用
                this.moveLeftInRow(r);
            }// 循环结束                    
            // 为数组拍照保存到after中
            var after=String(this.date);
            // 如果after!=before   表示data中的数据有变化
            if(after!=before){
                // 生成随机数添加到data中去   randomNum()
                this.randomNum();
                // 更新页面 updateView()
                document.getElementById("gameover").style.display = "none";
                this.updateView();
            }
            
        },
        moveLeftInRow(r){//左移第r行
            // c从0开始,到<CN-1
            for(var c=0;c<this.CN-1;c++){
                // 查找r行c列下一个不为0的位置nextc   调用一个函数  var nextc = getNextInRow(r,c)
                var nextc =this.getNextInRow(r,c);
                // 如果nextc=-1  
                if(nextc == -1){
                    break;//没有找到  退出循环
                }else{
                    // 否则
                    if(this.date[r][c] == 0){// 如果c位置的值等于0
                        // 将r行nextc位置的值赋值给c位置
                        this.date[r][c] = this.date[r][nextc];
                        // 将nectc位置的值赋值为0
                        this.date[r][nextc]=0;
                        // 将c留在原地   看后面是否有和c位置值相等的数据
                        c--;
                    }else if(this.date[r][c] == this.date[r][nextc]){
                        // 否则,如果c位置的值等于nextc位置的值
                        // 将c位置的值*2
                        this.date[r][c]*=2;    
                        this.score += this.date[r][c];
                        // 将nextc位置的值设置为0
                        this.date[r][nextc]=0;
                    }
                }                                    
            }            
        },
        getNextInRow(r,c){
            //查找r行c列下一个不为0的位置
            // i从c+1开始,到<CN结束
            for(var i=c+1;i<this.CN;i++){            
                // 如果i位置的值不为0, return  i
                if(this.date[r][i] != 0){
                    return i;// 循环结束                
                }
            }        
            return -1;// 返回 -1 表示没有找到不为0 的位置
        },
    //左移结束
    //右移开始
        moveRight(){
            // 为数组拍照保存到before中
            var before=String(this.date);
            // r从0开始,到<RN结束
            for(var r=0;r<this.RN;r++){
                // 左移第r行  moveRightInRow(r)---- 可以单独完成一件事情  反复被使用
                this.moveRightInRow(r);
            }// 循环结束                    
            // 为数组拍照保存到after中
            var after=String(this.date);
            // 如果before!= after     表示data中的数据有变化
            if(before!= after){
                // 生成随机数添加到data中去   randomNum()
                this.randomNum();
                // 更新页面 updateView()s
                this.updateView();
            }        
        },
        moveRightInRow(r){//右移第r行
            //c从倒数第二个开始,到>0结束    反向遍历r行每一列
            for(var c=this.RN-1;c>0;c--){
                // 查询r行c列的前一个不为0的位置    等到位置prevc  调用函数 getPrevcInRow(r,c)
                    var prevc = this.getPrevcInRow(r,c)
                    //若prevc == -1
                    if (prevc == -1) {
                        break;
                    }else{
                        //如果c位置的值等于0
                            if(this.date[r][c] == 0){
                                // 将prevc位置的值赋值给c位置
                                this.date[r][c] = this.date[r][prevc];
                                    // 将prevc位置的值赋值为0
                                this.date[r][prevc] = 0;
                                    // 将c留在原地   看后面是否有和c位置值相等的数据
                                    c++;
                            }else if (this.date[r][c] == this.date[r][prevc]) {
                                // 否则,如果c位置的值等于prevc位置的值
                                // 将c位置的值*2
                                this.date[r][c] *= 2;
                                this.score += this.date[r][c];
                                // 将prevc位置的值设置为0
                                this.date[r][prevc] = 0;
                            }
                    }
            }
        },
        getPrevcInRow(r,c){//获取r行c列前一个不为0值的位置
            // i从CN-1开始,到i>=0结束
            for (var i =c-1;i>=0;i--) {
                // 如果i位置的值不为0, return  i
                    if (this.date[r][i] != 0) {
                            return i;// 循环结束                
                    }
            }
            return -1;
        },
    //右移结束
    //上移开始
        moveTop(){
            // 为数组拍照保存到before中
            var before=String(this.date);
            // c从0开始,到<RN结束
            for(var c=0;c<this.CN;c++){
                // 左移第r行  moveTopInRow(c) ---- 可以单独完成一件事情  反复被使用
                this.moveTopInRow(c);
            }// 循环结束                    
            // 为数组拍照保存到after中
            var after=String(this.date);
            // 如果after!=before   表示data中的数据有变化
            if(after!=before){
                // 生成随机数添加到data中去   randomNum()
                this.randomNum();
                // 更新页面 updateView()
                this.updateView();
            }        
        },
        moveTopInRow(c){
            for(var r= 0;r<this.RN;r++){
                // 查找c行r列下一个不为0的位置nextr   调用一个函数  var nextr =getNextrInRow(r,c);
                    var nextr = this.getNextrInRow(r,c);
                    //若nextr != -1
                    if (nextr != -1) {
                        //如果c位置的值等于0
                            if(this.date[r][c] == 0){
                                // 将nextc位置的值赋值给c位置
                                this.date[r][c] = this.date[nextr][c];
                                    // 将nextr位置的值赋值为0
                                this.date[nextr][c]= 0;
                                    // 将r留在原地   看后面是否有和c位置值相等的数据
                                    r--;
                            }else if (this.date[r][c] == this.date[nextr][c]) {
                                // 否则,如果c位置的值等于nextz位置的值
                                // 将c位置的值*2
                                this.date[r][c] *= 2;
                            this.score += this.date[r][c];
                                // 将nextz位置的值设置为0
                                this.date[nextr][c]= 0;
                            }
                    }
            }
        },
        getNextrInRow(r,c){
            //查找c行r列下一个不为0的位置
            // i从r+1开始,到i<RN结束
            for (var i = r+1;i<this.RN;i++) {
                // 如果i位置的值不为0, return  i
                    if(this.date[i][c] != 0) {
                            return i;// 循环结束                
                    }
            }
            return -1;
        },
    //上移结束
    //下移开始
        moveDown(){
            // 为数组拍照保存到before中
            var before=String(this.date);
            // c从0开始,到<RN结束
            for(var c=0;c<this.CN;c++){
                // 左移第r行  moveDownInRowSS(c) ---- 可以单独完成一件事情  反复被使用
                this.moveDownInRow(c);
            }// 循环结束                    
            // 为数组拍照保存到after中
            var after=String(this.date);
            // 如果after!=before   表示data中的数据有变化
            if(before != after){
                // 生成随机数添加到data中去   randomNum()
                this.randomNum();
                // 更新页面 updateView()
                this.updateView();
            }        
        },
        
        moveDownInRow(c){
            for(var r=this.CN-1;r>0;r--){
                // 查询r行c列的前一个不为0的位置    等到位置prevd  调用函数 getPrevdInRow(r,c)
                    var prevd = this.getPrevdInRow(r,c)
                    //若prevd = -1
                    if (prevd ==-1) {
                        break;
                    }
                    else{
                        //如果c位置的值等于0
                            if(this.date[r][c] == 0){
                                // 将prevd位置的值赋值给c位置
                                this.date[r][c] = this.date[prevd][c];
                                    // 将prevd位置的值赋值为0
                                this.date[prevd][c] = 0;
                                    // 将c留在原地   看后面是否有和c位置值相等的数据
                                    r++;
                            }else if (this.date[r][c] == this.date[prevd][c]) {
                                // 否则,如果c位置的值等于prevd位置的值
                                // 将c位置的值*2
                                this.date[r][c]*= 2;
                                this.score += this.date[r][c];
                                // 将prevd位置的值设置为0
                                this.date[prevd][c] = 0;
                            }
                    }
            }
        },
        getPrevdInRow(r,c){
            //查找c行r列下一个不为0的位置
            // i从r-1开始,到i>=0结束
            for (var i= r-1;i>=0;i--) {
                // 如果i位置的值不为0, return  i
                    if(this.date[i][c] != 0) {
                            return i;// 循环结束                
                    }
            }
            return -1;
        },
    }
    game.strt();
  • 相关阅读:
    编写登陆认证程序
    模拟实现一个ATM + 购物商城程序
    三级菜单
    12 场景制造
    11 Unity Editor界面
    3.7练习题
    Coolite 弹窗妙用
    Nginx反向代理 实现Web负载均衡
    MySQL 架构
    Lnmmp
  • 原文地址:https://www.cnblogs.com/conlover/p/10944600.html
Copyright © 2020-2023  润新知