使用TypeError变量undefined吃了几次后,蛇游戏崩溃了

时间:2018-05-05 14:37:40

标签: javascript

我几天都在学习JavaScript。所以我对此完全陌生。

这是我的蛇游戏代码,它还没有完成,但我遇到了问题。如果这是一个逻辑错误,我不完全确定。

几次吃完食物后,游戏崩溃了

  

TypeError:snakeBody [l]未定义。

Screenshot of the error is here.

整个代码如下:

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

<head>
<style>
    canvas {
        background: #080d16;
        border: 5px solid green;
        padding: 0;
    }
</style>
</head>

<body>
<canvas id="mycan" class="mycan" width="1860" height="920"></canvas>
<script>
    var canvas = document.getElementById('mycan');
    var ctx = canvas.getContext('2d');
    var snakeSize = 20;
    var snakeX = 100;
    var snakeY = 100;
    var foodX = 310;
    var foodY = 310;
    var foodSize = 10;
    var dx = 20;
    var dy = 20;
    var leftPressed = false;
    var rightPressed = true;
    var topPressed = false;
    var bottomPressed = false;
    var snakeBody = [{x:snakeX,y:snakeY},{x:snakeX-20,y:snakeY}];
    var z = 0;



    //keypress event listner
    document.addEventListener('keypress', keyHandler, false);
    //keypress event handler function
    function keyHandler(e) {
        if (e.keyCode == 37) {
            leftPressed = true;
            rightPressed = false;
            topPressed = false;
            bottomPressed = false;
        } else if (e.keyCode == 38) {
            leftPressed = false;
            rightPressed = false;
            topPressed = true;
            bottomPressed = false;
        } else if (e.keyCode == 39) {
            leftPressed = false;
            rightPressed = true;
            topPressed = false;
            bottomPressed = false;
        } else if (e.keyCode == 40) {
            leftPressed = false;
            rightPressed = false;
            topPressed = false;
            bottomPressed = true;
        }
    }

    //draw food 
    function food() {
        ctx.beginPath();
        ctx.arc(foodX, foodY, foodSize, 0, Math.PI * 2);
        ctx.fillStyle = "pink";
        ctx.fill();
        ctx.closePath();
    }
    //draw snake
    function snake() {
        for (var l = 0; l < snakeBody.length; l++) {
            ctx.beginPath();
            ctx.rect(snakeBody[l].x, snakeBody[l].y, snakeSize, snakeSize);
            if (l == 0) {
                ctx.fillStyle = "lightblue";
            } else {
                ctx.fillStyle = 'grey';
            }
            ctx.fill();
            ctx.closePath();

        }
        console.log(l);
        var head = {
            x: snakeX,
            y: snakeY
        };
        snakeBody.pop();
        snakeBody.unshift(head);

    }

    function tail() {
        if ((snakeX + dx / 2 > foodX - foodSize && snakeX + dx / 2 < foodX + foodSize) && (snakeY + dy / 2 > foodY - foodSize && snakeY + dy / 2 < foodY + foodSize)) {
            foodX = (Math.floor(Math.random() * 88) + 1) * 20 + 10;
            foodY = (Math.floor(Math.random() * 45) + 1) * 20 + 10;
            z++;
            if (snakeBody[snakeBody.length - 1].x == snakeBody[snakeBody.length - 2].x && snakeBody[0].y < snakeBody[1].y) {
                snakeBody[z] = {
                    x: snakeBody[snakeBody.length - 1].x,
                    y: snakeBody[snakeBody.length - 1].y + 20
                };

            } else if (snakeBody[snakeBody.length - 1].x == snakeBody[snakeBody.length - 2].x && snakeBody[0].y > snakeBody[1].y) {
                snakeBody[z] = {
                    x: snakeBody[snakeBody.length - 1].x,
                    y: snakeBody[snakeBody.length - 1].y - 20
                };
            } else if (snakeBody[snakeBody.length - 1].y == snakeBody[snakeBody.length - 2].y && snakeBody[0].x > snakeBody[1].x) {
                snakeBody[z] = {
                    x: snakeBody[snakeBody.length - 1].x - 20,
                    y: snakeBody[snakeBody.length - 1].y
                };
            } else if (snakeBody[snakeBody.length - 1].y == snakeBody[snakeBody.length - 2].y && snakeBody[0].x < snakeBody[1].x) {
                snakeBody[z] = {
                    x: snakeBody[snakeBody.length - 1].x + 20,
                    y: snakeBody[snakeBody.length - 1].y
                };
            }
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        snake();
        food();
        tail();

        if (rightPressed && snakeX + dx < canvas.width) {
            snakeX += dx;
        } else if (leftPressed && snakeX > 0) {
            snakeX += -dx;
        } else if (topPressed && snakeY > 0) {
            snakeY += -dy;
        } else if (bottomPressed && snakeY + dy < canvas.height) {
            snakeY += dy;
        }

    }

    setInterval(draw, 80);
</script>
</body>

</html>

2 个答案:

答案 0 :(得分:0)

你在算法中有错误 - 你的snakeBody put / pops元素你在这个数组中使用索引时会错过一些“极端情况” - 问题不是JS而是算法 - 调试它并在chrome中使用“triangle” konsole在错误的左侧看到更多细节(stacktrace)

答案 1 :(得分:0)

我多次检查并运行您的代码。此错误不适合我。您最好检查snake函数中的值,然后使用它们。将您的snake功能修改为此

function snake() {
    for (var l = 0; l < snakeBody.length; l++) {
        ctx.beginPath();
        if(snakeBody && snakeBody[l] && snakeBody[l].hasOwnProperty('x') && snakeBody[l].hasOwnProperty('y')) {
            ctx.rect(snakeBody[l].x, snakeBody[l].y, snakeSize, snakeSize);
        }
        if (l == 0) {
            ctx.fillStyle = "lightblue";
        } else {
            ctx.fillStyle = 'grey';
        }
        ctx.fill();
        ctx.closePath();

    }
    console.log(l);
    var head = {
        x: snakeX,
        y: snakeY
    };
    snakeBody.pop();
    snakeBody.unshift(head);

}

如您所见,snakeBody没有索引24和25.但是这种情况满足了这一点。

enter image description here