js实现2048小游戏

2048 小游戏

2048小游戏效果图


这里写图片描述

1. 2048游戏基本布局的搭建

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>2048小游戏</title>
        //引入css样式
        <link rel="stylesheet" type="text/css"  href="css/2048.css" />
    </head>
    <body>
         //2048小游戏计分
        <p class="score">SCORE:<span id="score">0</span></p>
        <div class="gamebox">
             //2048小游戏第一行
            <div class="cell" id="c00"></div>
            <div class="cell" id="c01"></div>
            <div class="cell" id="c02"></div>
            <div class="cell" id="c03"></div>
             //2048小游戏第二行
            <div class="cell" id="c10"></div>
            <div class="cell" id="c11"></div>
            <div class="cell" id="c12"></div>
            <div class="cell" id="c13"></div>
             //2048小游戏第三行
            <div class="cell" id="c20"></div>
            <div class="cell" id="c21"></div>
            <div class="cell" id="c22"></div>
            <div class="cell" id="c23"></div>
             //2048小游戏第四行
            <div class="cell" id="c30"></div>
            <div class="cell" id="c31"></div>
            <div class="cell" id="c32"></div>
            <div class="cell" id="c33"></div>
        </div>
        //2048小游戏游戏结束的画面
        <div class="gameover" id="gameover">
            <p>
                GAME OVER!!!<br/>
                SCORE:<span id="scoreend"></span><br/>
                <a id="try">try again!</a>
            </p>
        </div>
        //引入js脚本
        <script  type="text/javascript"  src="js/2048.js" ></script>        
    </body>
</html>

2. 2048游戏游戏界面样式的设计(2048.css)

//初始化界面,设置字体的样式
*{
    margin:0;
    padding:0;
    font-family:arial;
}

 //设置2048计分界面的宽度、居中显示和其中的字体样式
 .score{
    width:480px;
    margin:100px auto 0;
    font-size:50px;
    font-weight:bold;
 }
 //设置2048的计分界面分数的颜色为红色
 .score>span{
    color:red;
 }

 .gamebox{
    width:480px;
    height:480px;
    background:#fbd5d5;
    margin:0 auto;
    border-radius:10px;
 }
 //设置2048小游戏单元格的样式
 .cell{
    width:100px;
    height:100px;
    background-color:#fbf8cd;
    float:left;
    border-radius:5px;
    margin:16px 0 0 16px;
    font-size:50px;
    font-weight:bold;
    text-align:center;
    line-height:100px;
    color:white;
 }

 //设置单元格代码数字分别是2、4、8、16、32等等的样式
 .n2{background-color:#eee3da;color:#776e65}
 .n4{background-color:#ede0c8;color:#776e65}
 .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;font-size:40px}
 .n2048{background-color:#09c;font-size:40px}
 .n4096{background-color:#a6c;font-size:40px}
 .n8192{background-color:#93c;font-size:40px}

//设置2048游戏结束的样式
 .gameover{
     position:absolute;
     left:0;
     top:0;
     bottom:0;
     right:0;
     background-color: rgba(66,66,66,.2);
     display:none;
}

.gameover>p{
    width:400px;
    height:200px;
    background:#fff;
    border:1px solid #000;
    font-size:36px;
    font-weight:bold;
    border-radius:10px;
    position:absolute;
    left:50%;
    top:50%;
    margin-left:-200px;
    margin-top:-100px;

    text-align:center;
    line-height:66px;
    font-weight:bold;
}

.gameover a{
    background-color:#9F8d77;
    padding:10px;
    border-radius:5px;
    color:white;
    text-align: none;
}

3. 2048游戏功能的实现(js实现)

//创建一个对象,这个对象记录了游戏里面所有的属性和方法
var game = {
        data: [],//创建了一个存放游戏数据的数组
        score: 0, //定义游戏的分数
        status: 1, //自己定义一个状态,时刻的去跟游戏的状态进行比较,判断游戏是否结束
        gamerunning: 1,  //游戏如果处于运行中,给个标识
        gameover: 0,//游戏如果结束,给个标识

         //开始的时候需要初始化游戏的数据
        start: function() {
            for(var r = 0; r < 4; r++) {
                game.data[r] = [];
                for(var c = 0; c < 4; c++) {
                    game.data[r][c] = 0;
                }
            }
            //开始的时候需要初始化游戏的分数
            game.scroe = 0;
             //开始的时候需要初始化游戏的状态
            game.status = game.gamerunning;

            //游戏开始的时候有两个随机数,就调用两次
            game.randomNum();
            game.randomNum();

            game.dataView();
        },

         //生成随机数的方法。生成随机数,在2或者4。想办法放到数组中去,并且只能在0的位置替换
        randomNum: function() {
            for(;;) {//无限循环,直到找到为0的位置为止
                var r = Math.floor(Math.random() * 4); //随机生成了一个行
                var c = Math.floor(Math.random() * 4); //随机生成了一个列
                if(game.data[r][c] == 0) {//只有当位置为0的时候才能生成
                    var num = Math.random() > 0.5 ? 2 : 4;//生成2或者4
                    game.data[r][c] = num; //为数组赋值
                    break;//退出循环
                }
            }
        },
         //把数组里面的数据显示到页面中
        dataView: function() {
            for(var r = 0; r < 4; r++) {
                for(var c = 0; c < 4; c++) {
                    var div = document.getElementById("c" + r + c); //找到对应的单元格
                    if(game.data[r][c] != 0) {
                        div.innerHTML = game.data[r][c];
                        div.className = "cell n" + game.data[r][c];
                    } else {
                        div.innerHTML = "";
                        div.className = "cell";
                    }
                }
            }
            //找到分数的id进行赋值
            document.getElementById("score").innerHTML = game.score;
            if(game.status == game.gameover) {
                document.getElementById("scoreend").innerHTML = game.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(game.data[r][c] == 0) {
                        return false; //表示游戏没有结束
                    }
                    if(c < 3) {//不需要比较最后一个
                        if(game.data[r][c] == game.data[r][c + 1]) {
                            return false;
                        }
                    }
                    if(r < 3) {
                        if(game.data[r][c] == game.data[r + 1][c]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        },
  }
        //向左移动
        moveLeft: function() {
            // 移动之前
            var before = game.data.toString();
            // 处理移动的逻辑
            for(var r = 0; r < 4; r++) {
                game.moveLeftInRow(r); // 只处理第r行
            }
            // 移动之后
            var after = game.data.toString();
            if(before != after) {
                game.randomNum();
                if(game.isGameOver()) {
                    game.status = game.gameover;
                }
                game.dataView();
            }
        },

        moveLeftInRow: function(r) {
            for(var c = 0; c < 3; c++) {
                var nextc = game.getNextInRow(r, c);
                if(nextc != -1) {
                    if(game.data[r][c] == 0) {
                        game.data[r][c] = game.data[r][nextc];  //用找到的位置进行替换
                        game.data[r][nextc] = 0;//把找到的位置改变成0
                        c--; //让索引值继续留在原地
                    } else if(game.data[r][c] == game.data[r][nextc]) {
                        game.data[r][c] *= 2;
                        game.score += game.data[r][c];
                        game.data[r][nextc] = 0;
                    }
                } else {
                    break;
                }
            }
        },
        getNextInRow: function(r, c) {
            for(var i = c + 1; i < 4; i++) {
                if(game.data[r][i] != 0) {
                    return i;//如果在后面找到了,直接返回索引
                }
            }
            return -1;//如果没有找到,就返回一个标识符
        },
        //向右移动 
        moveRight: function() {
            var before = game.data.toString();
            for(var r = 0; r <4; r++) {
                game.moveRightInRow(r);
            }
            var after = game.data.toString();
            if(before != after) {
                game.randomNum();
                if(game.isGameOver()) {
                    game.status = game.gameover;
                }
                game.dataView();
            }
        },

        moveRightInRow: function(r) {
            for(var c = 3; c > 0; c--) {
                var after = game.getNextrInRow(r, c);
                if(after != -1) {
                    if(game.data[r][c] == 0) {
                        game.data[r][c] = game.data[r][after];
                        game.data[r][after] = 0;
                        c++; //让索引值继续留在原地
                    } else if(game.data[r][c] == game.data[r][after]) {
                        game.data[r][c] *= 2;
                        game.score += game.data[r][c];
                        game.data[r][after] = 0;
                    }

                } else {
                    break;
                }
            }
        },
        getNextrInRow: function(r, c) {
            for(var i = c - 1; i >= 0; i--) {
                if(game.data[r][i] != 0) {
                    return i; //如果在后面找到了,直接返回索引
                }
            }
            return -1;
        },
//向上移动
moveTop: function() {
            var before = game.data.toString();
            for(var c = 0; c < 4; c++) {
                game.moveTopInRow(c);
            }
            var after = game.data.toString();
            if(before != after) {
                game.randomNum();
                if(game.isGameOver()) {
                    game.status = game.gameover;
                }
                game.dataView();
            }
        },

        moveTopInRow: function(c) {
            for(var r = 0; r < 4; r++) {
                var top = game.getNextInCol(r, c);
                if(top != -1) {
                    if(game.data[r][c] == 0) {
                        game.data[r][c] = game.data[top][c];
                        game.data[top][c] = 0;
                        r--;
                    } else if(game.data[r][c] == game.data[top][c]) {
                        game.data[r][c] *= 2;
                        game.score += game.data[r][c];
                        game.data[top][c] = 0;
                    }
                } else {
                    break;
                }
            }
        },

        //判断在某一列的数组中的元素是否有不为0的,如果有,返回该行的下标,如果没有,返回-1.
        getNextInCol: function(r, c) {
            for(var i = r + 1; i < 4; i++) {
                if(game.data[i][c] != 0) {
                    return i;//如果在后面找到了,直接返回索引
                }
            }
            return -1;
        },

        //向下移动
        moveBottom: function() {
            var before = game.data.toString();
            for(var c = 0; c < 4; c++) {
                game.moveBottomInRow(c);
            }
            var after = game.data.toString();
            if(before != after) {
                game.randomNum();
                if(game.isGameOver()) {
                    game.status = game.gameover;
                }
                game.dataView();
            }
        },

        moveBottomInRow: function(c) {
            for(var r = 3; r >= 1; r--) {
                var bottom = game.getNextsInCol(r, c);
                if(bottom != -1) {
                    if(game.data[r][c] == 0) {
                        game.data[r][c] = game.data[bottom][c];
                        game.data[bottom][c] = 0;
                        r++;
                    } else if(game.data[r][c] == game.data[bottom][c]) {
                        game.data[r][c] *= 2;
                        game.score += game.data[r][c];
                        game.data[bottom][c] = 0;
                    }
                } else {
                    break;
                }
            }
        },
        //判断在某一列的数组中的元素是否有不为0的,如果有,返回该行的下标,如果没有,返回-1.
        getNextsInCol: function(r, c) {
            for(var i = r - 1; i >= 0; i--) {
                if(game.data[i][c] != 0) {
                    return i;//如果在后面找到了,直接返回索引
                }
            }
            return -1;
        },
        //如果游戏重新开始,把分数重置为0,再开始进行游戏
        demo:function(){
            if(game.status==game.gameover)
            {
                game.score=0;
                game.start();
            }
        }
//开始游戏
game.start();
//鼠标按下上、下、左、右键,2048小游戏中的单元格里面的方块分别向上、下、左、右移动。
document.onkeydown=function(event){
    var  event=event||window.event;
      if(event.keyCode==37){
        game.moveLeft();
      }
      if(event.keyCode==39){
        game.moveRight();
      }
      if(event.keyCode==38){
        game.moveTop();
      }
      if(event.keyCode==40){
        game.moveBottom();
      }
}
//如果按下再试一次的按钮,游戏重新开始
var try1=document.getElementById("try");
try1.onclick=function(){
    game.demo(); 
}

猜你喜欢

转载自blog.csdn.net/qq_41380430/article/details/82024681