通过Canvas实现贪吃蛇

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Canvas02_贪吃蛇</title>
</head>
<style type="text/css">
#ca {
    border: 1px solid red;
    display: block;
    margin: 20px auto;
}
</style>

<body>
    <canvas id="ca" width="600" height="600"></canvas>
    <script type="text/javascript">
    //1.获取canvas标签
    var canvasE = document.getElementById("ca");

    //2.通过canvas标签获取2D渲染对象(画笔)
    var pen = canvasE.getContext("2d");

    //声明一个变量记录分数
    let score = 0;

    //声明一个产生随机数的函数
    function randomNum(x, y) {
        return Math.floor(Math.random() * (y - x + 1) + x);
    }

    //声明一个方块类
    class Block {
        //列
        col;
        //行
        row;
        //尺寸
        size;
        //绘制方块
        draw() {
            pen.fillRect(this.col * this.size, this.row * this.size, this.size, this.size);
        }
        //构造方法
        constructor(col, row, size) {
            this.col = col;
            this.row = row;
            this.size = size;
        }
    }

    //声明食物类
    class Food {
        //列
        col;
        //行
        row;
        //尺寸
        fSize;
        //初始化食物
        constructor() {
            //调用食物的赋值方法
            this.initFood();
        }
        initFood() {
            this.col = Math.floor(Math.random() * 60);
            this.row = Math.floor(Math.random() * 60);
            this.fSize = 5;
        }
        draw() {
            //设置食物颜色
            pen.fillStyle = "red";
            //画食物
            pen.beginPath();
            pen.arc(this.col * this.fSize * 2 + this.fSize, this.row * this.fSize * 2 + this.fSize, this.fSize, 0, Math.PI * 2, false);
            pen.fill();
            //把颜色改回来
            pen.fillStyle = "black";
        }

    }

    //声明🐍类
    class Snake {
        //身体
        body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
        //初始方向
        direction = "up";
        //食物
        food;
        //初始化蛇
        constructor(food) {
            this.food = food;
        }

        //绘制🐍身体的方法
        draw() {
            //循环绘制每一个小块
            for (var i = 0; i < this.body.length; i++) {
                this.body[i].draw();
            }
        }
        //移动方法
        move() {
            //新建蛇头,新蛇头由当前方向和当前蛇头的位置共同决定
            let oldHead = this.body[0];
            let newHead;
            //判断移动的方向(WASD)
            switch (this.direction) {
                case "up":
                    {
                        newHead = new Block(oldHead.col, oldHead.row - 1, oldHead.size);
                        break;
                    }

                case "down":
                    {
                        newHead = new Block(oldHead.col, oldHead.row + 1, oldHead.size);
                        break;
                    }

                case "left":
                    {
                        newHead = new Block(oldHead.col - 1, oldHead.row, oldHead.size);
                        break;
                    }
                case "right":
                    {
                        newHead = new Block(oldHead.col + 1, oldHead.row, oldHead.size);
                        break;
                    }
            }
            //新的头部放进数组的第一位
            this.body.unshift(newHead);

            //判断是否吃到食物
            if (newHead.col == this.food.col && newHead.row == this.food.row) {
                while (true) {
                    this.food.initFood();
                    //判断生成的食物是否在蛇的身体上
                    for (var i = 0; i < this.body.length; i++) {
                        if (this.food.col == this.body[i].col && this.food.row == this.body[i].row) {
                            //如果真的在蛇身上,重新生成食物
                            this.food.initFood();
                        }
                    }
                    //结束循环
                    break;
                }
                //吃一个加一分
                score++;
            } else {
                //移除数组里的最后一个值
                this.body.pop();
            }
        }
        //碰撞检测
        snakeDeath() {
            //获取蛇头
            let snakeHead = this.body[0];
            //判断是否碰壁
            if (snakeHead.col < 0 || snakeHead.col > 59 || snakeHead.row < 0 || snakeHead.row > 59) {
                alert("你无了.");
                //重新开始游戏
                score = 0;
                this.body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
            }
            //判断蛇头是否碰到自己
            for (let i = 1; i < this.body.length; i++) {
                if (snakeHead.col == this.body[i].col && snakeHead.row == this.body[i].row) {
                    alert("游戏结束!");
                    //重新开始游戏
                    score = 0;
                    this.body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
                }
            }
        }
    }

    let food = new Food();
    let snake = new Snake(food);

    //开始游戏
    var count = 0;
    startGame();

    function startGame(argument) {
        count++;
        pen.clearRect(0, 0, canvasE.width, canvasE.height);
        //绘制分数
        pen.font = "normal 30px 黑体";
        pen.fillText("分数" + score, 10, 40);;
        snake.draw();
        food.draw();
        snake.snakeDeath();
        if (count == 3) {
            snake.move();
            count = 0;
        }
        requestAnimationFrame(startGame);
    }

    //绑定键盘事件
    window.onkeydown = function(e) {
        var even = e || event;
        switch (even.keyCode) {
            case 65:
                {
                    //左
                    if (snake.direction != "right") {
                        snake.direction = "left";
                    }
                    break;
                }
            case 87:
                {
                    //上
                    if (snake.direction != "down") {
                        snake.direction = "up";
                    }
                    break;
                }
            case 68:
                {
                    //右
                    if (snake.direction != "left") {
                        snake.direction = "right";
                    }
                    break;
                }
            case 83:
                {
                    //下
                    if (snake.direction != "up") {
                        snake.direction = "down";
                    }
                    break;
                }
        }
    }
    </script>
</body>

</html>
posted @ 2021-01-06 14:48  伯驹  阅读(84)  评论(0编辑  收藏  举报