【问题标题】:Cannot read property 'x' of undefined (JavaScript)无法读取未定义的属性“x”(JavaScript)
【发布时间】:2015-06-12 18:38:30
【问题描述】:

我目前正在尝试使用 JavaScript 和 Canvas 从 tutorial 构建一个蛇游戏。目前我在这条线上收到一个错误:grid.set(FOOD, randPos.x, randPos.y); 这是底部的setFood 函数的一部分。我不明白 .x 来自哪里,因为我没有看到在该范围内定义的 X 或 Y。如果有人能指出我正确的方向,我将不胜感激,这样我就可以完成我的第一场比赛!!!谢谢。

<script>
    //CONSTANTS
    var COLS=26;
    var ROWS=26;

    //ID's
    var EMPTY=0;
    var SNAKE=1;
    var FOOD=2;

    //Direction
    var LEFT=0;
    var UP=1;
    var RIGHT=2;
    var DOWN=3;

    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){
            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)];
        console.log("working");
        grid.set(FOOD, randPos.x, randPos.y);
        console.log("working???")
    }

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

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

        frames = 0;
        keystate = {};

        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++;
    }

    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 FOOD:
                        ctx.fillStyle = "#f00";
                        break;
                }
                ctx.fillRect(x*tw, y*th, tw, th);
            }
        }
    }

    main();
</script>

【问题讨论】:

  • 只是为了澄清。我明白为什么我会收到错误(因为范围内没有 x),但我无法回溯以了解我在哪里搞砸了。
  • x 是循环中项目的值。这里的问题不是 x 而是 randposundefined
  • 让我帮你调试:grid.set(FOOD, randPos.x, randPos.y); 给你一个错误,说你试图从未定义的东西中获取x 属性。所以randPos 是未定义的。 randPos 来自 empty[Math.floor(Math.random()*empty.length)];empty 是在嵌套 for 循环中创建的数组:empty.push({x:x, y:y});。你知道x 来自哪里吗?
  • @Steez:你 200% 确定这是你正在运行的实际代码吗?我们都会犯错,但我一直在这里查看唯一负责的代码行,我目前的结论是“这不可能发生”。
  • 你的get: function(x,y){是不是真的需要return this._grid[x][y];,否则返回值为undefined

标签: javascript oop canvas


【解决方案1】:

看看setFood 函数。在出现错误的行上方几行,有一个循环用包含xy 字段的对象填充empty 集合。这些对象之一被分配给randPos 变量。

该错误可能是由于对randPos 变量的值分配无效引起的。它是未定义的,因此它不包含必需的x 字段。

更新

您似乎只是在您的grid.get(x,y) 函数中错过了return 关键字,所以它应该是这样的:

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

请验证添加它是否可以解决您的问题。

【讨论】:

  • 但是为什么会发生这种情况?特别是考虑到相关的代码片段,看起来完全合法。
  • 确认这是否属实:grid.get(x,y)===EMPTY。我的意思是,检查代码是否进入循环并调用empty.push({x:x, y:y});对于每个空字段。
  • 请注意,您使用COLSROWS 调用grid.init(),但在setFood() 函数中您使用canvas.Widthcanvas.Height
  • 您关于宽度和高度的断言不正确。任何地方都使用正确的范围。
  • 好吧,是我遗漏了什么还是您遗漏了grid.get() 方法中的return 关键字;)?
【解决方案2】:

让我帮你调试:

grid.set(FOOD, randPos.x, randPos.y); 给你一个错误,说你试图从未定义的东西中获取 x 属性。

好的,所以randPos 是未定义的。

randPos 来自empty[Math.floor(Math.random()*empty.length)];

empty 是在嵌套 for 循环中创建的数组:empty.push({x:x, y:y});。你知道x 是从哪里来的吗?

正如 Lukasz 所指出的,只有在特定情况下,像这样的数组取消引用是未定义的。如果你尝试做类似的事情会怎样

var a = [];
console.log(a[0]);

?

empty 的原因是空的?没有网格单元=== EMPTY

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

因为缺少return

【讨论】:

    【解决方案3】:

    新答案。检查你的功能

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

    并将其与您链接的视频中的视频进行比较

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

    您需要添加返回部分,否则函数将返回undefined,并且名为empty 的数组将不会获得任何内容,因此您的随机数生成器会建议您使用empty[0],即@987654325 @。

    最后一个答案是用 randPos["x"] 替换 randPos.x,但正如下面 cmets 中的 bbill 所告知的那样,不是这样。

    【讨论】:

    • Javascript 在这些情况下支持 .[] 表示法。我知道的有问题的情况是当字段是数字时,然后只使用[]
    猜你喜欢
    • 2022-09-22
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多