欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

前端小游戏2048(一步步详解附带源代码,源码上传到csdn,可以免费下载)

程序员文章站 2022-06-22 11:46:42
前端开发2048小游戏,纯html+css+js,欢迎大家阅读交流,如果代码有什么不足,希望大家指正...

2048小游戏

2048是前端开发必经的一个小游戏,2048小游戏包含了HTML,CSS和JavaScript。

简介

《2048》,是一款益智小游戏,这款游戏是由年仅19岁的意大利程序员加布里勒希鲁尼(Gabriele Cirulli)开发出来的,官方版本只能在网页上或通过其移动网站运行。 2048游戏共有16个格子,初始时会有两个格子上安放了两个数字2,每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方随即出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。系统给予的数字方块不是2就是4,玩家要想办法在这小小的16格范围中凑出“2048”这个数字方块。

效果图

前端小游戏2048(一步步详解附带源代码,源码上传到csdn,可以免费下载)
游戏结束弹出遮罩层显示
前端小游戏2048(一步步详解附带源代码,源码上传到csdn,可以免费下载)

代码部分

首先是html部分

<p class="grade">分数:<span id="score01">999999999</span> </p>
    <div class="all">
        <div class="cell n2" id="c00">2</div>
        <div class="cell n4" id="c01">4</div>
        <div class="cell n8" id="c02">8</div>
        <div class="cell n16" id="c03">16</div>
        <div class="cell n32" id="c10">32</div>
        <div class="cell n64" id="c11">64</div>
        <div class="cell n128" id="c12">128</div>
        <div class="cell n256" id="c13">256</div>
        <div class="cell n512" id="c20">512</div>
        <div class="cell n1024" id="c21">1024</div>
        <div class="cell n2048" id="c22">2048</div>
        <div class="cell n4096" id="c23">4096</div>
        <div class="cell n8192" id="c30">8192</div>
        <div class="cell" id="c31"></div>
        <div class="cell" id="c32"></div>
        <div class="cell" id="c33"></div>

    </div>
    <div class="gameover">
        <p>
            游戏结束!<br> 分数:<span id="score02">999999999</span> <br>
            <a href="">再来一次</a>
        </p>
    </div>

html样式部分代码

* {
    padding: 0;
    margin: 0;
    font-family: Arial;
    text-decoration: none;
}

body {
    background-color: #FAF8EF;
}

.grade {
    width: 500px;
    margin: 0 auto;
    margin-top: 50px;
    font-size: 40px;
    text-align: center;
    font-weight: bold;
    color: #776E65;
}

.all {
    width: 500px;
    height: 500px;
    margin: auto;
    background-color: #BBADA0;
    border-radius: 10px;
}

.cell {
    width: 100px;
    height: 100px;
    margin-top: 20px;
    margin-left: 20px;
    background-color: #ccc0b3;
    float: left;
    border-radius: 5px;
    font-size: 24px;
    font-weight: bold;
    color: #776E65;
    line-height: 100px;
    text-align: center;
}

.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;
}

.gameover {
    display: none;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.3);
}

.gameover p {
    width: 400px;
    height: 300px;
    background-color: white;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -150px;
    margin-left: -200px;
    border: solid 1px black;
    border-radius: 10px;
    font-size: 40px;
    line-height: 100px;
    text-align: center;
}

.gameover p a {
    background-color: #8F7A66;
    border-radius: 5px;
    padding: 15px;
    color: white;
}

下面是2048核心js代码了

var game = {
    data: [], //存放数据
    score: 0, //分数
    status: 0, //当前状态,时刻的监听,时刻的需要改变      游戏运行中的状态,结束的状态
    gameover: 0,
    gamerunning: 1,
    start: function() {}
    randomNum: function() {}
    dataView: function() {}
    isgameover: function() {}
    moveLeft: function() {}
    moveLeftInRow: function(r) {} //单独处理每一行的逻辑
    getNextInRow: function(r, c) {}
    moveRight: function() {}
    moveRightInRow: function(r) { }//单独处理每一行的逻辑
    getNextInRowa: function(r, c) {}
    moveTop: function() {}
    moveTopInRow: function(c) {}
    getNextInRowaa: function(r, c) {}
    moveButtom: function() {}
    moveButtomInRow: function(c) {}
    getNextInRowaaa: function(r, c) {}
    }

开始写各个函数

开始游戏的方法

start: function() {
        this.score = 0;
        this.data = [
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]
        ]
        this.status = this.gamerunning;
        this.randomNum()
        this.randomNum()
        this.dataView()
    }

随机数的方法,随机生成数字

randomNum: function() {
        for (;;) {
            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;
                this.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 (this.data[r][c] != 0) {
                    div.innerHTML = this.data[r][c];
                    div.className = 'cell n' + this.data[r][c]
                } else {
                    div.innerHTML = ''
                    div.className = 'cell'
                }
            }
        }
        document.getElementById('score01').innerHTML = this.score; //设置游戏分数

        // 监测游戏状态
        if (this.status == this.gameover) {
            document.getElementById('score02').innerHTML = this.score;
            document.getElementsByClassName('gameover')[0].style.display = 'block'
        } else {
            document.getElementsByClassName('gameover')[0].style.display = 'none'
        }
    }

判断游戏是否结束的方法 游戏没结束返回false 结束返回true

isgameover: function() {
        for (var r = 0; r < 4; r++) {
            for (var c = 0; c < 4; c++) {
                // 没有结束,三种情况::1.数组中还有0 2.左右相邻的有相同的  3.上下相邻有相同的
                if (this.data[r][c] == 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; //表示游戏已经结束
    }

左移动

moveLeft: function() {
        var before = String(this.data) //移动之前
            //处理移动的逻辑

        for (var r = 0; r < 4; r++) {
            this.moveLeftInRow(r);
        }

        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;
            }
            this.dataView()
        }
    },
    moveLeftInRow: function(r) { //单独处理每一行的逻辑
        for (var c = 0; c < 3; c++) {
            var nextc = this.getNextInRow(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] *= 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++) {
            if (this.data[r][i] != 0) {
                return i
            }
        }
        return -1;
    }

右移动,上移动,下移动和左移动的代码相似

// 右移动
    moveRight: function() {
        var before = String(this.data) //移动之前
        for (var r = 3; r >= 0; r--) {
            this.moveRightInRow(r);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveRightInRow: function(r) { //单独处理每一行的逻辑
        for (var c = 3; c >= 0; c--) {
            var nextc = this.getNextInRowa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[r][nextc] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowa: function(r, c) {
        for (var i = c - 1; i >= 0; i--) {
            if (this.data[r][i] != 0) {
                return i
            }
        }
        return -1;
    },
    // 上移动
    moveTop: function() {
        var before = String(this.data) //移动之前
        for (var c = 0; c < 4; c++) {
            this.moveTopInRow(c);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveTopInRow: function(c) { //单独处理每一列的逻辑
        for (var r = 0; r < 3; r++) {
            var nextr = this.getNextInRowaa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[nextr][c] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowaa: function(r, c) {
        for (var i = r + 1; i < 4; i++) {
            if (this.data[i][c] != 0) {
                return i
            }
        }
        return -1;
    },
    // 下移动
    moveButtom: function() {
        var before = String(this.data) //移动之前
        for (var c = 3; c >= 0; c--) {
            this.moveButtomInRow(c);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveButtomInRow: function(c) { //单独处理每一列的逻辑
        for (var r = 3; r >= 0; r--) {
            var nextr = this.getNextInRowaaa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[nextr][c] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowaaa: function(r, c) {
        for (var i = r - 1; i >= 0; i--) {
            if (this.data[i][c] != 0) {
                return i
            }
        }
        return -1;
    },

}

调用开始函数

game.start()

绑定键盘上下左右事件(37,38,39,40分别对应键盘左上右下键)

document.onkeydown = function(e) {
    if (e.keyCode == 37) { 
        game.moveLeft()
    }
    if (e.keyCode == 39) {
        game.moveRight()
    }
    if (e.keyCode == 38) {
        game.moveTop()
    }
    if (e.keyCode == 40) {
        game.moveButtom()
    }
}

最后,给再来一次绑定事件

zai = function() {
    game.start()

}

以上就是2048小游戏的全部代码。希望大家也可以动手做出这个小游戏玩玩。

整体代码

html–index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/index.css">//引用代码的时候注意路径准确性
    <link rel="shortcut icon" href="https://www.2048.org/favicon.ico">//添加一个2048小图标
    <title>2048</title>
</head>

<body>
    <p class="grade">分数:<span id="score01">000</span> </p>
    <div class="all">
        <div class="cell n2" id="c00">2</div>
        <div class="cell n4" id="c01">4</div>
        <div class="cell n8" id="c02">8</div>
        <div class="cell n16" id="c03">16</div>
        <div class="cell n32" id="c10">32</div>
        <div class="cell n64" id="c11">64</div>
        <div class="cell n128" id="c12">128</div>
        <div class="cell n256" id="c13">256</div>
        <div class="cell n512" id="c20">512</div>
        <div class="cell n1024" id="c21">1024</div>
        <div class="cell n2048" id="c22">2048</div>
        <div class="cell n4096" id="c23">4096</div>
        <div class="cell n8192" id="c30">8192</div>
        <div class="cell" id="c31"></div>
        <div class="cell" id="c32"></div>
        <div class="cell" id="c33"></div>

    </div>
    <div class="gameover">
        <p>
            游戏结束!<br> 分数:<span id="score02">999999999</span> <br>
            <a href="">再来一次</a>
        </p>
    </div>
    <script src="./js/index.js"></script>//引用代码的时候注意路径准确性
</body>

</html>

css–index.css

* {
    padding: 0;
    margin: 0;
    font-family: Arial;
    text-decoration: none;
}

body {
    background-color: #FAF8EF;
}

.grade {
    width: 500px;
    margin: 0 auto;
    margin-top: 50px;
    font-size: 40px;
    text-align: center;
    font-weight: bold;
    color: #776E65;
}

.all {
    width: 500px;
    height: 500px;
    margin: auto;
    background-color: #BBADA0;
    border-radius: 10px;
}

.cell {
    width: 100px;
    height: 100px;
    margin-top: 20px;
    margin-left: 20px;
    background-color: #ccc0b3;
    float: left;
    border-radius: 5px;
    font-size: 24px;
    font-weight: bold;
    color: #776E65;
    line-height: 100px;
    text-align: center;
}

.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;
}

.gameover {
    display: none;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.3);
}

.gameover p {
    width: 400px;
    height: 300px;
    background-color: white;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -150px;
    margin-left: -200px;
    border: solid 1px black;
    border-radius: 10px;
    font-size: 40px;
    line-height: 100px;
    text-align: center;
}

.gameover p a {
    background-color: #8F7A66;
    border-radius: 5px;
    padding: 15px;
    color: white;
}

js–index.js

var game = {
    data: [], //存放数据
    score: 0, //分数
    status: 0, //当前状态,时刻的监听,时刻的需要改变      游戏运行中的状态,结束的状态
    gameover: 0,
    gamerunning: 1,


    // 开始游戏的方法
    start: function() {
        this.score = 0;
        this.data = [
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]
        ]
        this.status = this.gamerunning;
        this.randomNum()
        this.randomNum()
        this.dataView()
    },
    // 随机数的方法
    randomNum: function() {
        for (;;) {
            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;
                this.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 (this.data[r][c] != 0) {
                    div.innerHTML = this.data[r][c];
                    div.className = 'cell n' + this.data[r][c]
                } else {
                    div.innerHTML = ''
                    div.className = 'cell'
                }
            }
        }
        document.getElementById('score01').innerHTML = this.score; //设置游戏分数

        // 监测游戏状态
        if (this.status == this.gameover) {
            document.getElementById('score02').innerHTML = this.score;
            document.getElementsByClassName('gameover')[0].style.display = 'block'
        } else {
            document.getElementsByClassName('gameover')[0].style.display = 'none'
        }
    },
    // 判断游戏是否结束的方法   游戏没结束返回false 结束返回true
    isgameover: function() {
        for (var r = 0; r < 4; r++) {
            for (var c = 0; c < 4; c++) {
                // 没有结束,三种情况::1.数组中还有0 2.左右相邻的有相同的  3.上下相邻有相同的
                if (this.data[r][c] == 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; //表示游戏已经结束
    },
    // 左移动
    moveLeft: function() {
        var before = String(this.data) //移动之前
            //处理移动的逻辑

        for (var r = 0; r < 4; r++) {
            this.moveLeftInRow(r);
        }

        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;
            }
            this.dataView()
        }
    },
    moveLeftInRow: function(r) { //单独处理每一行的逻辑
        // 0200   2000
        // 0220   4000
        // 2202   4200
        // 2222   4022  4202  4220   4400
        for (var c = 0; c < 3; c++) {
            var nextc = this.getNextInRow(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] *= 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++) {
            if (this.data[r][i] != 0) {
                return i
            }
        }
        return -1;
    },

    // 右移动
    moveRight: function() {
        var before = String(this.data) //移动之前
        for (var r = 3; r >= 0; r--) {
            this.moveRightInRow(r);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveRightInRow: function(r) { //单独处理每一行的逻辑
        for (var c = 3; c >= 0; c--) {
            var nextc = this.getNextInRowa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[r][nextc] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowa: function(r, c) {
        for (var i = c - 1; i >= 0; i--) {
            if (this.data[r][i] != 0) {
                return i
            }
        }
        return -1;
    },
    // 上移动
    moveTop: function() {
        var before = String(this.data) //移动之前
        for (var c = 0; c < 4; c++) {
            this.moveTopInRow(c);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveTopInRow: function(c) { //单独处理每一列的逻辑
        for (var r = 0; r < 3; r++) {
            var nextr = this.getNextInRowaa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[nextr][c] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowaa: function(r, c) {
        for (var i = r + 1; i < 4; i++) {
            if (this.data[i][c] != 0) {
                return i
            }
        }
        return -1;
    },
    // 下移动
    moveButtom: function() {
        var before = String(this.data) //移动之前
        for (var c = 3; c >= 0; c--) {
            this.moveButtomInRow(c);
        }
        var after = String(this.data) //移动之后
        if (before != after) {
            this.randomNum()
            if (this.isgameover()) {
                this.status = this.gameover;

            }
            this.dataView()
        }
    },
    moveButtomInRow: function(c) { //单独处理每一列的逻辑
        for (var r = 3; r >= 0; r--) {
            var nextr = this.getNextInRowaaa(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] *= 2;
                    this.score += this.data[r][c]
                    this.data[nextr][c] = 0
                }
            } else {
                break;
            }
        }
    },
    getNextInRowaaa: function(r, c) {
        for (var i = r - 1; i >= 0; i--) {
            if (this.data[i][c] != 0) {
                return i
            }
        }
        return -1;
    },

}


game.start()



document.onkeydown = function(e) {
    if (e.keyCode == 37) {
        game.moveLeft()
    }
    if (e.keyCode == 39) {
        game.moveRight()
    }
    if (e.keyCode == 38) {
        game.moveTop()
    }
    if (e.keyCode == 40) {
        game.moveButtom()
    }
}
zai = function() {
    game.start()

}

本次2048小游戏的所有代码就放在这里了,2048的源码我也上传到csdn了,有需要的朋友可以免费下载,如果找不到,可以在评论区留言,我也可以直接发给大家!谢谢!如果代码有什么不足的希望大家及时交流,补充,谢谢大家!

本文地址:https://blog.csdn.net/yf19990720/article/details/107520685