js 贪吃蛇小游戏

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas {
            display: block;
            margin: 0 auto;
            background-color: #33cc99;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
        var canvas = document.getElementById('canvas')
        var ctx = canvas.getContext('2d')

        // 食物的默认位置
        var x = Math.floor(Math.random() * 20) * 30
        var y = Math.floor(Math.random() * 20) * 30

        // 蛇的默认位置
        var snake = [{ x: 3, y: 0 }, { x: 2, y: 0 }, { x: 1, y: 0 }]

        //食物是否被吃掉
        var isEated = false

        // 游戏是否结束
        var isGameOver = false

        // 蛇的方向
        var directionX = 1
        var directionY = 0

        document.addEventListener('keydown', function (e) {//监听键盘按下行为
            if (e.keyCode === 37) {//左
                directionX = -1
                directionY = 0
            } else if (e.keyCode === 38) {//上
                directionX = 0
                directionY = -1
            } else if (e.keyCode === 39) {//右
                directionX = 1
                directionY = 0
            } else if (e.keyCode === 40) {//下
                directionX = 0
                directionY = 1
            }
        })

        // 让贪吃蛇动起来,原理就是不断擦除,然后不断重绘
        setInterval(function () {
            if (isGameOver) {//游戏结束
                return
            }
            // 擦除
            ctx.clearRect(0, 0, 600, 600)

            // 随机生成食物的位置
            if (isEated) {//食物被吃掉后就重新绘制食物
                x = Math.floor(Math.random() * 20) * 30
                y = Math.floor(Math.random() * 20) * 30
            }

            // 绘制食物
            ctx.fillStyle = '#cccc00'
            ctx.fillRect(x, y, 30, 30)


            var oldHead = snake[0]
            var newHead = {
                x: oldHead.x + directionX,
                y: oldHead.y + directionY
            }
            if (
                newHead.y < 0 ||
                newHead.x < 0 ||
                newHead.x * 30 >= 600 ||
                newHead.y * 30 >= 600
            ) {//游戏结束的判断
                isGameOver = true
            } else {
                snake.unshift(newHead)
                /* 蛇吃食物的分析:当蛇头的坐标和食物的坐标重合的时候,就表示食物被吃掉了,此时应该做两件事
                    1.让isEated变为true,表示食物被吃掉
                    2.让蛇增加一节长度
                */
                // 蛇动起来分析:删除最后一节,然后在最前面添加一个新节,通过定时器不断的执行这个操作就有一个蛇动起来的效果
                if (snake[0].x * 30 === x && snake[0].y * 30 === y) {//食物被吃掉,重新生成一个食物,并在蛇头添加一个新节
                    isEated = true
                } else {//食物没有被吃掉,移除最后一节,在蛇头添加一个新节
                    isEated = false
                    snake.pop()
                }
            }

            // 绘制蛇
            for (var i = 0; i < snake.length; i++) {
                if (i === 0) {//舌头
                    ctx.fillStyle = '#ff0033'
                } else {//蛇身
                    ctx.fillStyle = '#333399'
                }
                ctx.fillRect(snake[i].x * 30, snake[i].y * 30, 30, 30)
            }

            for (var i = 1; i < 20; i++) {//绘制网格
                // 水平线
                ctx.moveTo(0, i * 30 + 0.5)
                ctx.lineTo(600, i * 30 + 0.5)

                // 垂直线
                ctx.moveTo(i * 30 + 0.5, 0)
                ctx.lineTo(i * 30 + 0.5, 600)
            }
            ctx.strokeStyle = 'white'
            ctx.stroke()

        }, 1000 / 4)
    </script>
</body>

</html> 
效果图 (直接复制代码可以看效果)

原文地址:https://www.cnblogs.com/zhangying0518/p/14633030.html