javaScript 快速实现简单的贪吃蛇小游戏

134 阅读3分钟

我正在参加掘金社区游戏创意投稿大赛个人赛,详情请看:游戏创意投稿大赛

前言

贪吃蛇并不难,思路如下:

  • 建一个小蛇可以移动的棋盘;
  • 游戏开始后,棋盘中任何格子都可以作为小蛇身体的一部分或小方块;
  • 使用定时器来连续地让小蛇移动;
  • 判断小蛇的头部位置如果与小方块的位置一致,那么小方块被吃掉成为小蛇身体的一部分;
  • 小方块被吃掉以后,立马随机生成下一个方块;
  • 如果小蛇的头部超出棋盘的边界位置,则提示游戏结束。

实现

HTML代码

<div class="game-title">Qiuの贪吃小蛇</div>
    <div class="game-container">
        <table id="tableLat">
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        </table>
        <div class="controller">
            <button id="startBtn" class="btnStyle">开始游戏</button>
            <button id="endBtn" class="btnStyle">结束游戏</button>
            <div id="showInfo"></div>
        </div>
    </div>

CSS代码

        /*标题*/
        .game-title {
            text-align: center;
            line-height: 80px;
            font-size: 30px;
            color: #03a9f4;
            font-weight: bold;
        }

        /* 游戏整体 */
        .game-container {
            width: 600px;
            height: 450px;
            margin: 0 auto;
            display: flex;
            flex-flow: row nowrap;
            justify-content: center;
            align-items: center;
            background-color: #ffeb3b;
        }

        table tr td {
            width: 40px;
            height: 40px;
            border: solid gray 1px;
            background-color: #fff;
        }

        /* 按钮 */
        .controller {
            width: 150px;
            height: 370px;
            margin-left: 20px;
            padding: 10px;
            box-sizing: border-box;
            background-color: #feffb1;

        }

        .btnStyle {
            width: 100%;
            height: 30px;
            margin-top: 20px;
            text-align: center;
            background-color: aquamarine;
        }

        /* 消息提示框 */
        #showInfo {
            font-size: 12px;
            margin-top: 20px;
            padding: 10px;
            height: 190px;
            overflow: auto;
            border: 2px solid black;
            background-color: aquamarine;
        }

渲染效果如下

image.png

JS代码

// 各节点参数
        var lattices = document.getElementById('tableLat').children[0];//格子合集
        var startBtn = document.getElementById('startBtn');//开始游戏按钮
        var endBtn = document.getElementById('endBtn');//结束游戏按钮
        var rowsLen = document.getElementById('tableLat').children[0].rows.length;//行数
        var cellsLen = document.getElementById('tableLat').children[0].rows[0].cells.length;//每行格子数
        var showInfo = document.getElementById('showInfo')//提示面板

        var timer = null;//定时器
        var message = '小蛇撞到墙了,游戏结束!请点击“开始游戏”按钮重新开始游戏!'

        //小蛇
        const Snake = {
            //蛇身位置
            snakeBody: [
                { sbX: 0, sbY: 0 },
            ],
            //蛇移动方向(默认向下)
            direction: 'down',
            //蛇头位置
            snakeHeadX: 0,
            snakeHeadY: 0,
            //是否继续移动
            moveContinue: true,

            //小蛇移动
            snakeMove: function () {
                //判断蛇移动方向
                switch (Snake.direction) {
                    case 'left':
                        // 判断是否超出棋盘边界,超出结束游戏并提示,没有超出则继续移动
                        if (Snake.snakeHeadX <= 0) {
                            Snake.snakeHeadX = 0
                            Snake.moveContinue = false
                            endGame()
                            showInfo.innerHTML = message
                        } else {
                            Snake.snakeHeadX--;
                            Snake.moveContinue = true
                        }
                        break;
                    case 'up':
                        if (Snake.snakeHeadY <= 0) {
                            Snake.snakeHeadY = 0
                            Snake.moveContinue = false
                            endGame()
                            showInfo.innerHTML = message
                        } else {
                            Snake.snakeHeadY--;
                            Snake.moveContinue = true
                        }
                        break;
                    case 'right':
                        if (Snake.snakeHeadX >= 7) {
                            Snake.snakeHeadX = 7;
                            Snake.moveContinue = false
                            endGame()
                            showInfo.innerHTML = message
                        } else {
                            Snake.snakeHeadX++;
                            Snake.moveContinue = true
                        }
                        break;
                    case 'down':
                        if (Snake.snakeHeadY >= 7) {
                            Snake.snakeHeadY = 7
                            Snake.moveContinue = false
                            endGame()
                            showInfo.innerHTML = message
                        } else {
                            Snake.snakeHeadY++;
                            Snake.moveContinue = true
                        }
                        break;
                }

                if (Snake.moveContinue) {
                    //蛇身移动
                    Snake.snakeBody.push({ sbX: Snake.snakeHeadY, sbY: Snake.snakeHeadX })
                    if (lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].getAttribute('isblock') === 'y') {
                        //下一格是方块,蛇身加长,继续创建方块
                        lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].setAttribute('isblock', 'n');
                        lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].style.background = 'white';
                        Block.createBlock();
                    } else {
                        //原来蛇尾,移动一格后删除蛇尾
                        lattices.rows[Snake.snakeBody[0].sbX].cells[Snake.snakeBody[0].sbY].style.background = 'white';
                        Snake.snakeBody.splice(0, 1);
                    }

                    //蛇身位置
                    Snake.snakeBody.forEach(function (item, index, arr) {
                        lattices.rows[item.sbX].cells[item.sbY].style.background = 'green';
                    })
                }
            }
        }

        //方块
        const Block = {
            //方块的初始位置
            blockPos: { blockX: 0, blockY: 0 },
            //随机位置生成方块
            createBlock: function () {
                Block.blockPos.blockX = Math.floor(Math.random() * 8)
                Block.blockPos.blockY = Math.floor(Math.random() * 8)
                console.log(Block.blockPos.blockX, Block.blockPos.blockY)

                //判断随机位置是否在蛇身位置上
                lattices.rows[Block.blockPos.blockX].cells[Block.blockPos.blockY].setAttribute('isblock', 'y');
                lattices.rows[Block.blockPos.blockX].cells[Block.blockPos.blockY].style.background = 'red'
            }
        }

        //开始游戏
        var startGame = function () {
            // 生成小蛇
            lattices.rows[0].cells[0].style.background = 'green'
            // 移动定时器
            timer = setInterval(Snake.snakeMove, 1000)
            //生成方块
            Block.createBlock();
        }

        //结束游戏
        var endGame = function () {
            //清除定时器
            clearInterval(timer);
            //蛇头位置重置
            Snake.snakeHeadX = 0;
            Snake.snakeHeadY = 0;
            //蛇身重置
            Snake.snakeBody.splice(0, Snake.snakeBody.length, { sbX: 0, sbY: 0 })

            //重置棋盘格子背景为白色
            for (var i = 0; i < rowsLen; i++) {
                for (var j = 0; j < cellsLen; j++) {
                    lattices.rows[i].cells[j].style.background = 'white'
                }
            }
        }

        //键盘控制改变方向
        var changeDirect = function () {
            switch (event.keyCode) {
                case 37:
                    Snake.direction = 'left';
                    break;
                case 38:
                    Snake.direction = 'up';
                    break;
                case 39:
                    Snake.direction = 'right';
                    break;
                case 40:
                    Snake.direction = 'down';
                    break;
                default:
                    Snake.direction = 'right';
                    break;
            }
        }

        // 按钮点击事件
        startBtn.addEventListener('click', startGame) //开始游戏	
        endBtn.addEventListener('click', endGame)//结束游戏

        // 键盘控制方向
        document.addEventListener('keydown', changeDirect)

游戏效果如下

game.gif