canvas Snake

Here Insert Picture Description
html code:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <style>
        body {
            text-align: center;
            padding-top: 50px;
        }
    </style>
    <canvas width="600" height="600" style="box-shadow: 0 0 10px #333;" id="canvas"></canvas>
    <script src="canvas17.js"></script>
</body>

</html>
<!-- 
    1先把蛇画出来
        蛇头和蛇的身子
    2蛇动起来
        添加键盘事件
        animate运动
    3随机投放食物
        坐标位置
        食物是否投放到了蛇头和蛇的身子上(数组排重)
    4吃食物
        碰撞检测
        将蛇的身加一
    5边缘检测
        判断游戏是否结束
-->

js code:

var canvas = document.getElementById('canvas');
if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    var isEatFood = false;
    var timer;
    function Rect(x, y, width, height, color) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.color = color;
    }
    Rect.prototype.rDraw = function () {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
        ctx.strokeRect(this.x, this.y, this.width, this.height);
        ctx.closePath();
    }
    //创建snake对象
    function Snake() {
        //蛇头
        this.head = new Rect(canvas.width / 2 - 20, canvas.height / 2 - 20, 20, 20, 'red');
        //蛇身
        this.body = new Array();
        var x = this.head.x - 20;
        var y = this.head.y;
        for (var i = 0; i < 3; i++) {
            var rect = new Rect(x, y, 20, 20, 'gray');
            this.body.push(rect);
            x -= 20;
            this.direction = 2;
        }
    }
    var snake = new Snake();
}

Snake.prototype.sDraw = function () {
    //绘制蛇头
    this.head.rDraw();
    //绘制蛇身
    for (var i = 0; i < this.body.length; i++) {
        this.body[i].rDraw();
    }
}
snake.sDraw();
//     加头去尾
Snake.prototype.move = function () {
    //加头
    var rect = new Rect(this.head.x, this.head.y, this.head.width, this.head.height, 'gray');
    this.body.splice(0, 0, rect);   //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
    //去尾
    if (isEatFood == false) {   //正常没有碰到食物
        this.body.pop();
    } else {
        isEatFood = false;
    }
    // this.body.pop();     pop() 方法用于删除并返回数组的最后一个元素。
    switch (this.direction) {
        case 0: {
            this.head.x -= this.head.width;
            break;
        }
        case 1: {
            this.head.y -= this.head.height;
            break;
        }
        case 2: {
            this.head.x += this.head.width;
            break;
        }
        case 3: {
            this.head.y += this.head.height;
            break;
        }
    }
    if (this.head.x >= canvas.width || this.head.x < 0 || this.head.y >= canvas.height || this.head.y <= 0) {
        clearInterval(timer);
        // timer = null;
        alert('Game over !!!');
    }
    for (var i = 0; i < this.body.length; i++) {
        if (isRectHit(this.head, this.body[i])) {
            clearInterval(timer);
            timer = null;
            alert('Game over !!!');
        }
    }
}

function randForFood() {
    var isInsnake = true;
    while (isInsnake) {
        var x = getRandInRange(0, (canvas.width - 20) / 20) * 20;
        var y = getRandInRange(0, (canvas.height - 20) / 20) * 20;   //格子换成坐标 * 20
        //食物矩形
        var rect = new Rect(x, y, 20, 20, 'blue');
        //判断食物与头重叠  
        if (isRectHit(snake.head, rect)) {
            isInsnake = true;
            continue;
        }
        isInsnake = false;
        //判断食物是否与蛇身重叠    
        for (var i = 0; i < snake.body.length; i++) {
            if (isRectHit(snake.body[i], rect)) {
                isInsnake = true;
                break;
            }
        }
    }
    return rect;

}
function isRectHit(rect1, rect2) {
    var minX1 = rect1.x;
    var minX2 = rect2.x;
    var minY1 = rect1.y;
    var minY2 = rect2.y;

    var maxX1 = rect1.x + rect1.width;
    var maxX2 = rect2.x + rect2.width;
    var maxY1 = rect1.y + rect1.height;
    var maxY2 = rect2.y + rect2.height;

    //判断矩形相交的最大/最小值
    var minX = Math.max(minX1, minX2);
    var minY = Math.max(minY1, minY2);
    var maxX = Math.min(maxX1, maxX2);
    var maxY = Math.min(maxY1, maxY2);
    if (minX < maxX && minY < maxY) {
        return true;
    } else {
        return false;
    }

}

function getRandInRange(min, max) {
    return Math.round(Math.random() * (max - min) + min);//格子做表 round() 方法可把一个数字舍入为最接近的整数 ?man,min哪来的

}

var food = randForFood();
function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    snake.move();
    snake.sDraw();
    food.rDraw();
    if (isRectHit(snake.head, food)) {
        // console.log('吃到了');
        isEatFood = true;
        food = randForFood();
    }
}
timer = setInterval(animate, 50);

document.onkeydown = function (e) {
    var event = e || window.event;
    switch (event.keyCode) {
        case 37: {
            snake.direction = 0;
            break;
        }
        case 38: {
            snake.direction = 1;
            break;
        }
        case 39: {
            snake.direction = 2;
            break;
        }
        case 40: {
            snake.direction = 3;
            break;
        }
    }
}

unction Rect () -> Initialization square
Rect.prototype.rDraw -> shown square

function Snake () -> snake initial shape (physical and logical relationships contained in the sections of the snake beginning)
Snake.prototype.sDraw -> draw a snake (the method can be used for drawing a square that is rDraw)
Snake. prototype.move -> (which contains only 1 which food is encountered and not encountered where the food 2 to make a change of direction is determined whether touch the wall 3)

function randForFood () -> is determined whether the intersection
function animate (); -> the entire movement (move to the overall timer)
function isRectHit (); -> intersect conditions
document.onkeydown (e); -> keyboard bindings event

Released eight original articles · won praise 0 · Views 102

Guess you like

Origin blog.csdn.net/Edasi/article/details/104431730