TypeError:this._grid [x]未定义

时间:2016-10-14 08:15:59

标签: javascript canvas

我正在尝试使用JavaScript和Canvas中的tutorial构建一个蛇游戏。此时我在这一行收到错误(TypeError:y未定义):

return this._grid[x][y];

是var网格对象的一部分。如果有人能指出我正确的方向,我会非常感激,所以我可以完成游戏! 谢谢。

<script>
//Constants
var COLS = 26, ROWS = 26;
// IDs
var EMPTY=0, SNAKE = 1, FRUIT = 2;
// Directions
var LEFT = 0, UP = 1, RIGHT = 2, DOWN = 3;
// KeyCodes
var KEY_LEFT=37, KEY_UP=38, KEY_RIGHT=39, KEY_DOWN=40;

    var grid = {
        width: null, 
        height: null,
        _grid: null,

        init: function(d,c,r){
            this.width = c;
            this.height = r;

            this._grid = [];
            for(var x=0; x<c; x++){
                this._grid.push([]);
                for(var y=0; y < r; y++){
                    this._grid[x].push(d);
                }
            }
        },

        set: function(val,x,y){
            this._grid[x][y] = val;
        },

        get: function(x,y){
            return this._grid[x][y];
        }
    }

    var snake = {
        direction: null,
        last: null,
        _queue: null,

        init: function(d,x,y){
            this.direction = d;
            this._queue = [];
            this.insert(x,y);
        },

        insert: function(x,y){
            this._queue.unshift({x:x, y:y});
            this.last = this._queue[0];
        },

        remove: function(){
            return this._queue.pop();
        }
    }

function setFood() {
    var empty = [];
    for (var x = 0; x < grid.width; x++) {
        for (var y = 0; y < grid.height; y++) {
            if (grid.get(x, y) === EMPTY) {
                empty.push({x:x, y:y});
            }
        }
    }
    var randpos = empty[Math.floor(Math.random()*empty.length)];
    grid.set(FRUIT, randpos.x, randpos.y);
}

    //Game objects
    var canvas, ctx, keystate, frames, score;

    function main() {
    canvas = document.createElement("canvas");
    canvas.width = COLS*20;
    canvas.height = ROWS*20;
    ctx = canvas.getContext("2d");
    document.body.appendChild(canvas);

    ctx.font = "12px Helvetica"

    frames = 0;
    keystate = {};
    document.addEventListener("keydown", function(evt) {
        keystate[evt.keyCode] = true;
    });
    document.addEventListener("keyup", function(evt) {
        delete keystate[evt.keyCode];
    });

    init();
    loop();
}

    function init(){
        grid.init(EMPTY, COLS, ROWS);

        var sp = {x:Math.floor(COLS/2), y:ROWS-1};
        snake.init(UP, sp.x, sp.y);
        grid.set(SNAKE, sp.x, sp.y);

        setFood();
    }

    function loop(){
        update();
        draw();

        window.requestAnimationFrame(loop, canvas);
    }

    function update() {
    frames++;

    if (keystate[KEY_LEFT] && snake.direction !== RIGHT)
     snake.direction = LEFT;
    if (keystate[KEY_UP] && snake.direction !== DOWN) 
        snake.direction = UP;
    if (keystate[KEY_RIGHT] && snake.direction !== LEFT) 
        snake.direction = RIGHT;
    if (keystate[KEY_DOWN] && snake.direction !== UP) 
        snake.direction = DOWN;

    if (frames%5 === 0) {
        var nx = snake.last.x;
        var ny = snake.last.y;

        switch (snake.direction) {
            case LEFT:
                nx--;
                break;
            case UP:
                ny--;
                break;
            case RIGHT:
                nx++;
                break;
            case DOWN:
                ny++;
                break;
        }

        if (grid.get(nx, ny) === FRUIT) {
            var tail = {x:nx, y:ny};
            score++;
            setFood();
        } else {
            var tail = snake.remove();
            grid.set(EMPTY, tail.x, tail.y);
            tail.x = nx;
            tail.y = ny;
        }




        grid.set(SNAKE, tail.x, tail.y);

        snake.insert(tail.x, tail.y);
    }

    if (0 > nx || nx > grid.width-1 ||
        0 > ny || ny > grid.height-1 
        || grid.get(nx, ny) === SNAKE
        ) {
        return init();
    }
}

function draw() {
    var tw = canvas.width/grid.width;
    var th = canvas.height/grid.height;

        for (var x = 0; x < grid.width; x++) {
        for (var y = 0; y < grid.height; y++) {
            switch (grid.get(x, y)) {
                case EMPTY:
                    ctx.fillStyle = "#fff";
                    break;
                case SNAKE:
                    ctx.fillStyle = "#0ff";
                    break;
                case FRUIT:
                    ctx.fillStyle = "#f00";
                    break;
            }
            ctx.fillRect(x*tw, y*th, tw, th);
        }
    }
    ctx.fillStyle = "#000";
    ctx.fillText("SCORE: " + score, 10, canvas.height-10);
};

    main();

    </script>

1 个答案:

答案 0 :(得分:1)

如果您传递的数据不能保证在正确的范围内,您需要审核或捕获超出范围的值。

如果您认为数据不需要审查,则需要找到索引未定义数组项的错误值x的来源。

对于调试,要么在getter中添加一个断点,并使用调试器找出x的哪个值不正确并抛出错误或将调试器设置为&#34;中断错误&#34;并检查给你带来不良后果的x值。

将您的获取功能更改为

    get: function(x,y){
        try{
            return this._grid[x][y];
       } catch(e){
           console.error("access to _grid["+x+ "][" + y +"] failed");
           throw e;
       }
    }

因此,您可以看到错误抛出时x值是什么。

一旦找到原因并解决问题,就可以删除try catch

相关问题