Canvas实现贪吃蛇

一.演示

二.代码实现

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

<head>
    <title>贪吃蛇</title>
    <style>
        #myCanvas {
            display: block;
            margin: 0 auto;
            margin-top: 100px;
            border: 5px solid #76B947;
            background: #F0F0F0;
        }
    </style>
</head>

<body>
    <canvas id="myCanvas" width="800" height="500"></canvas>
    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');
        let foodWidth = 10;
        let foodHeight = 10;
        let snakeWidth = 10;
        let snakeHeight = 10;
        let foodX = Math.floor(Math.random() * (canvas.width / snakeWidth)) * snakeWidth;
        let foodY = Math.floor(Math.random() * (canvas.height / snakeHeight)) * snakeHeight;
        let dx = 10;
        let dy = 0;
        let score = 0;
        let snake = [
            { x: canvas.width / 2, y: canvas.height / 2 },
            { x: canvas.width / 2 - snakeWidth, y: canvas.height / 2 },
            { x: canvas.width / 2 - 2 * snakeWidth, y: canvas.height / 2 }
        ];

        document.addEventListener("keydown", keydownHandler, false);

        //定义了蛇的移动方式,并且确保了蛇不能掉头
        function keydownHandler(e) {
            if (e.key == "ArrowUp" && dy === 0) {
                dx = 0;
                dy = -snakeHeight;
            } else if (e.key == "ArrowDown" && dy === 0) {
                dx = 0;
                dy = snakeHeight;
            } else if (e.key == "ArrowLeft" && dx === 0) {
                dx = -snakeWidth;
                dy = 0;
            } else if (e.key == "ArrowRight" && dx === 0) {
                dx = snakeWidth;
                dy = 0;
            }
        }

        function drawFood() {
            ctx.beginPath();
            ctx.fillStyle = '#0095DD';
            ctx.fillRect(foodX, foodY, foodWidth, foodHeight);
        }

        function drawScore() {
            ctx.font = '16px Arial'
            ctx.fillStyle = '#0095DD'
            ctx.fillText('Score:' + score, 10, 20)
        }

        function drawSnake() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            console.log(canvas.width, canvas.height);
            drawScore();
            drawFood();
            for (let i = 0; i < snake.length; i++) {
                ctx.fillStyle = i == 0 ? 'black' : 'green';
                ctx.fillRect(snake[i].x, snake[i].y, snakeWidth, snakeHeight);
                // 添加轻微的阴影效果
                ctx.shadowBlur = 3;
                ctx.shadowColor = "gray";
            }
            ctx.shadowBlur = 0;
        }

        function moveSnake() {
            const head = { x: snake[0].x + dx, y: snake[0].y + dy };
            snake.unshift(head);
            console.log(snake.length);
            if (head.x === foodX && head.y === foodY) {
                foodX = Math.floor(Math.random() * (canvas.width / snakeWidth)) * snakeWidth;
                foodY = Math.floor(Math.random() * (canvas.height / snakeHeight)) * snakeHeight;
                score++;
            } else {
                snake.pop();
            }

            // 边界检测
            if (head.x < 0 - 10 || head.x >= canvas.width + 10 || head.y < 0 - 10 || head.y >= canvas.height + 10) {
                alert("游戏结束");
                document.location.reload();
            }

            // 检测蛇是否咬到自己
            for (let i = 4; i < snake.length; i++) {
                if (head.x == snake[i].x && head.y == snake[i].y) {
                    alert("游戏结束");
                    document.location.reload();
                }
            }
        }

        function draw() {
            drawSnake();
            moveSnake();
        }

        setInterval(draw, 100); // 每100毫秒更新一次游戏状态
    </script>
</body>

</html>

三.复盘 

        完成贪吃蛇核心的逻辑就是食物的随机生成,蛇的移动逻辑, 游戏的边界检测,蛇吃到食物身体增加等,虽然还有其它方法完成这个游戏,但我认为用画布就是最一目了然的,而且逻辑方面也很好解决,推荐使用。                                                        

 

 

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值