Canvas 贪吃蛇游戏


450*450

实现原理

思路分析

  1. 蛇的移动
  2. 改变蛇的方向
  3. 产生苹果
  4. 吃苹果蛇会增长
  5. 咬到自己就结束游戏

关键步骤:

1. 准备画布和做动画需要的变量

window.onload = function(){
    var cvs = document.getElementById("cvs");
    var ctx = cvs.getContext("2d");

    function draw(){
    // 声明需要的变量 
    var sceneSize = 30; // 场景大小
    var size = 20; // 格子的大小

    var snake = [{x:10, y:12}, {x:10, y:13}, {x:10, y:14}]; // 蛇的身体
    var direction = 1;// 蛇的方向     0: 左    1: 上      2:右      3:下

    var apples = []; // 所有的苹果

    var countFrame = 0;

    // 清除画布
    ctx.clearRect(0, 0, cvs.width, cvs.height);

}

      setInterval(draw, 500);
            }

2. 绘制场景

var sceneSize = 30; // 场景大小
var size = 20; // 格子的大小

function draw(){
// 清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);// 绘制场景
    drawScene();
    drawSnake();
        }            
    // 绘制场景
    function drawScene(){
    ctx.strokeStyle = "blue";
    for(var x = 0; x < sceneSize; x++){
        for(var y = 0; y < sceneSize; y++){
            ctx.strokeRect(x*size, y*size, size, size);
                        }
                    }
                }

3. 绘制蛇

// 蛇的身体是由很多的正方形组成的, 考虑蛇的长度是多少个正方形, 每个正方形的宽和高
function drawSnake(){
    ctx.fillStyle = "purple";
    for (var i = 0; i < snake.length; i++) {
        ctx.fillRect(snake[i].x*size, snake[i].y*size, size, size);
                }
        }

4. 蛇头的移动

// 绘制一帧
    function draw(){
// 清除画布
    ctx.clearRect(0, 0, cvs.width, cvs.height);
// 绘制场景
    drawScene();
// 绘制蛇
    drawSnake();

// 每一帧更新数据
    update();
}

// 每一帧更新数据
    function update(){
        snake[0].y--;
    }

5. 移动方向控制

// 每一帧更新数据
    function update(){
// 移动
    move();
}

// 移动
    function move(){
        switch(direction){
        case 0: snake[0].x--; break;
        case 1: snake[0].y--; break;
        case 2: snake[0].x++; break;
        case 3: snake[0].y++; break;
                }        
        }

6. 身体的移动

// 在move方法里
// 移动function move(){
// 蛇的身体的移动
    for(var i=snake.length-1; i >= 1; i--){
// 把当前身体移动上一节身体所在的位置
        snake[i].x = snake[i-1].x;
        snake[i].y = snake[i-1].y;
        }

// 蛇头的移动
    switch(direction){
        case 0: snake[0].x--; break;
        case 1: snake[0].y--; break;
        case 2: snake[0].x++; break;
        case 3: snake[0].y++; break;
                }
        }

7. 产生苹果

var apples = []; // 所有的苹果
// 绘制苹果
function drawApples(){
ctx.fillStyle = "orange";
    for (var i = 0; i < apples.length; i++) {
        ctx.fillRect(apples[i].x*size, apples[i].y*size, size, size);
                    }    
                }

// 产生苹果
function generateApple(){
    var x = parseInt(Math.random()*sceneSize);
    var y = parseInt(Math.random()*sceneSize);
        apples.push({x:x, y:y});
                }

8. 吃苹果

function draw(){
// 清除画布
    ctx.clearRect(0, 0, cvs.width, cvs.height);
// 绘制场景
    drawScene();
// 绘制苹果
    drawApples();
// 绘制蛇
    drawSnake();

// 每一帧更新数据
    update();
    }

// 每一帧更新数据
function update(){
// 移动
    move();

  if (countFrame % 20 == 0)
    generateApple();

    countFrame++;
    }

    // 移动
function move(){
    // 蛇的身体的移动
    for(var i=snake.length-1 ; i >= 1; i--){
// 把当前身体移动上一节身体所在的位置
        snake[i].x = snake[i-1].x;
        snake[i].y = snake[i-1].y;
        }

// 蛇头的移动
    switch(direction){
        case 0: snake[0].x--; break;
        case 1: snake[0].y--; break;
        case 2: snake[0].x++; break;
        case 3: snake[0].y++; break;
        }

// 吃苹果
    for (var i = 0; i < apples.length; i++) {
        if (apples[i].x === snake[0].x &&
        apples[i].y === snake[0].y) {
        apples.splice(i, 1);    
                }
            }
        }

9. 身体增长

// 身体增长方法
    function grow(){
        var body = {
            x: snake[snake.length-1].x,
            y: snake[snake.length-1].y
                    };
            snake.push(body);
        }

// 在move方法里的吃苹果里,调用grow()
    for (var i = 0; i < apples.length; i++) {
        if (apples[i].x === snake[0].x &&
            apples[i].y === snake[0].y) {
    // 吃到苹果了
            apples.splice(i, 1);
            grow();
                }
        }

10. 穿墙

// 在move方法里做实现穿墙的功能 
// 判断蛇头和场景大小的关系, 蛇头到达边缘会返回到当前边缘的另一边
    if(snake[0].x >= sceneSize) snake[0].x = 0;
    if(snake[0].x < 0) snake[0].x = sceneSize-1; 
    if(snake[0].y >= sceneSize) snake[0].y = 0;
    if(snake[0].y < 0) snake[0].y = sceneSize-1;

11. 蛇头咬到自己 游戏结束

// 咬到自己
    for (var i=1; i < snake.length; i++){
        if (snake[i].x === snake[0].x &&
            snake[i].y === snake[0].y) {            
                clearInterval(handle);
                    alert("aaaaaaaaaaaaaa");
                        }
                    }

12. 全部源代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            body{
                overflow: hidden;
            }
        </style>
        <script type="text/javascript">
            window.onload = function(){
                var cvs = document.getElementById("cvs");
                var ctx = cvs.getContext("2d");

                var sceneSize = 30; // 场景大小
                var size = 20; // 格子的大小
                var snake = [{x:10, y:12}, {x:10, y:13}, {x:10, y:14}]; // 蛇的身体
                var direction = 1;// 蛇的方向     0: 左    1: 上      2:右      3:下

                var apples = []; // 所有的苹果

                var countFrame = 0;

                // 绘制一帧
                function draw(){
                    // 清除画布
                    ctx.clearRect(0, 0, cvs.width, cvs.height);
                    // 绘制场景
                    drawScene();
                    // 绘制苹果
                    drawApples();
                    // 绘制蛇
                    drawSnake();

                    // 每一帧更新数据
                    update();
                }

                // 每一帧更新数据
                function update(){
                    // 移动
                    move();

                    if (countFrame % 20 == 0)
                        generateApple();

                    countFrame++;
                }

                // 移动
                function move(){
                    // 蛇的身体的移动
                    for(var i=snake.length-1 ; i >= 1; i--){
                        // 把当前身体移动上一节身体所在的位置
                        snake[i].x = snake[i-1].x;
                        snake[i].y = snake[i-1].y;
                    }

                    // 蛇头的移动
                    switch(direction){
                        case 0: snake[0].x--; break;
                        case 1: snake[0].y--; break;
                        case 2: snake[0].x++; break;
                        case 3: snake[0].y++; break;
                    }

                    // 穿墙
                    if(snake[0].x >= sceneSize) snake[0].x = 0;
                    if(snake[0].x < 0) snake[0].x = sceneSize-1;
                    if(snake[0].y >= sceneSize) snake[0].y = 0;
                    if(snake[0].y < 0) snake[0].y = sceneSize-1;                    

                    // 吃苹果
                    for (var i = 0; i < apples.length; i++) {
                        if (apples[i].x === snake[0].x &&
                            apples[i].y === snake[0].y) {
                            // 吃到苹果了
                            apples.splice(i, 1);
                            grow();
                        }
                    }

                    // 咬到自己
                    for (var i=1; i < snake.length; i++){
                        if (snake[i].x === snake[0].x &&
                            snake[i].y === snake[0].y) {

                            clearInterval(handle);
                            alert("aaaaaaaaaaaaaa");
                        }
                    }
                }

                // 绘制场景
                function drawScene(){
                    ctx.strokeStyle = "gray";
                    for(var x = 0; x < sceneSize; x++){
                        for(var y = 0; y < sceneSize; y++){
                            ctx.strokeRect(x*size, y*size, size, size);
                        }
                    }
                }

                // 绘制蛇
                function drawSnake(){
                    ctx.fillStyle = "purple";
                    for (var i = 0; i < snake.length; i++) {
                        ctx.fillRect(snake[i].x*size, snake[i].y*size, size, size);
                    }
                }

                // 绘制苹果
                function drawApples(){
                    ctx.fillStyle = "orange";
                    for (var i = 0; i < apples.length; i++) {
                        ctx.fillRect(apples[i].x*size, apples[i].y*size, size, size);
                    }    
                }

                // 产生苹果
                function generateApple(){
                    var x = parseInt(Math.random()*sceneSize);
                    var y = parseInt(Math.random()*sceneSize);
                    apples.push({x:x, y:y});
                }

                // 身体增长
                function grow(){
                    var body = {
                        x: snake[snake.length-1].x,
                        y: snake[snake.length-1].y
                    };
                    snake.push(body);
                }

                generateApple();
                generateApple();
                generateApple();

                var handle = setInterval(draw, 50);

                window.onkeydown=function(e){
                    switch(e.keyCode){
                        case 37: 
                            if (direction != 2)
                                direction=0;
                            break;
                        case 38: if (direction != 3) direction=1; break;
                        case 39: if (direction != 0) direction=2; break;
                        case 40: if (direction != 1) direction=3; break;
                    }
                }
            }
        </script>
    </head>
    <body>
        <canvas id="cvs" width="800" height="800">您的浏览器不支持Canvas</canvas>
    </body>
</html>

results matching ""

    No results matching ""