无法读取未定义的属性“-1”

时间:2011-06-23 16:41:44

标签: javascript oop canvas

这是我第一次尝试在Javascript项目中使用类 - 我正在尝试在HTML5 Canvas中实现Conway的生命游戏。 Here's the code.正如您所看到的,第一代渲染很好,但next()函数出现了问题,导致它无法再运行。 (我确实注意到有问题的错误实际上是在get()的最后一行抛出的,这是由neighbors()调用的函数之一,由next()调用。我不能在任一函数中发现任何问题,但显然某事错误!)

4 个答案:

答案 0 :(得分:3)

问题是[关于%的假设是错误的,因此get/set函数中的警卫不能按预期工作:

-1 % 42 // results in -1

快乐的编码。


我会考虑移除 get/set函数中的警卫并使用sentinel values(或其他邻居边缘框)作为边框(例如第一行/最后一行和列永远不会实际绘制到屏幕上。)

这可以避免大量的后卫检查 - get/set每次迭代都会被称为一大堆(我甚至都没有它们作为功能)。我认为删除get/set和守卫“没问题”因为这些操作是进程的内部操作并且与算法密切相关 - 它们不是直接公开的,而JavaScript只是如此之快。

每个周期执行“全网格邻居检查”为C * O(h*w)。虽然它具有相同的复杂性,但是明显更小的C可以使程序运行得更快。

答案 1 :(得分:1)

你在next

中有这个循环
 for(var y = 0; y < this.height; y++){
     for(var x = 0; x < this.width; x++){
         newMap[x][y] = this.get(x, y);

         //Rule 1: any live cell with fewer than two live neighbors dies
         if(this.get(x, y) == true && this.neighbors(x, y) < 2){
             newMap[x][y] = false;
         }

         //...

所以在第一次迭代中,xy为零。现在看看neighbors正在做什么:

this.neighbors = function(x, y){
    n = 0;
    //...
    if(this.get(x-1, y-1)){n++;}
    //...
    return n;
}

如果xy0,则会尝试检查单元格(-1,-1)

this.map[x][y] = val;

但是你的map只有正整数键。

如果您想“环绕”,请增加get中的值以避免负值:

x = (x + this.width) % this.width;
y = (y + this.height) % this.height;

答案 2 :(得分:1)

该行

x = x % this.width;

无法正常工作:

-1 % 640 

给出

-1

轻松修复:

x = (x + this.width) % this.width;

答案 3 :(得分:1)

让我们检查第一个细胞。假设x为0且y为0.在处理该单元格期间,您最终会检查this.map[-1][-1]。由于this.map[-1]未定义,因此您无法在其中找到元素-1,即使它确实存在(它不存在)。

您有几个选择:

  • 在抓取该单元格左侧的任何内容之前检查x > 0,然后在抓取右侧任何内容之前x < this.width - 1ythis.height的相似故事。
  • 在尝试访问其中的任何内容之前,请确保已定义this.map[x - 1]this.map[x + 1]。与y +/- 1相同 - 如果未定义,请将其视为假。
  • this.map[-1]this.map[whatever][-1]定义为false,以及this.map[this.width]this.map[whatever][this.height]
  • 重做您的数学运算,以便x - 1变为(x + width - 1) % width。与y - 1相同。那应该让地图环绕。