2010-05-21 73 views
-1

我非常沮丧。我正在跟随一个教程,并且自己模仿它。到目前为止,我已经能够理清大多数错误,但是这个错误让我很难过。我试着用教程标本替换所有的类文件,但我仍然得到错误。TypeError:Error#1009 Actionscript 3

TypeError: Error #1009: Cannot access a property or method of a null object reference. 
    at com.senocular.utils::KeyObject/construct() 
    at com.senocular.utils::KeyObject() 
    at com.asgamer.basics1::Ship() 
    at com.asgamer.basics1::Engine() 

现在,没有真正理解错误,我粘贴了在线文件,以供您查看。

Ship class: textbin.com/78z35 

Engine class: textbin.com/32b24 

KeyObject class: textbin.com/p2725 

由于使用样本类文件时仍然发生错误,我真的不知道从哪里开始。我会很乐意尝试任何建议。

+0

那么这是你的例外“无法访问空对象引用的属性或方法”。更明确地发布你的代码! – Jorgesys 2010-05-21 02:15:26

回答

5

提示:如果您允许调试,则该异常会告诉您源代码中引发错误的确切行。假设您使用的是Flash IDE,请转到发布设置,然后在Flash选项卡中选中“允许调试”。这会让事情变得更容易。

无论如何,你有一个错误消息。如果仔细阅读,可以缩小问题的位置。我不知道你是程序员,还是你有兴趣成为一名程序员;如果你不是,这个答案将有望解决这个特殊的问题。无论如何,如果你不介意漫不经心,让我告诉你,如果你有兴趣成为更好的程序员,注意错误并学习如何调试/排除故障是你需要开发的最重要的能力之一(如果不是最重要的话);所以也许这会给你一些提示,可以用来解决其他问题。

的消息称:

Cannot access a property or method of a null object reference.

这意味着,在某些时候,你做了这样的事情:

someobject.someMethod(); 

someobject.someProperty = "foo"; 

而且someobject碰巧为空。 您无法调用方法或访问空值的属性。

好的,现在你知道,某处某个变量的值为null。注意,你定义一个属性变量的事实并不意味着它实际上持有一个对象。

这只是说,一个名为mySprite上的变量可以容纳Sprite类型的对象:

var mySprite:Sprite; 

但直到在某些时候你创建一个Sprite并将其分配给mySprite上,由mySprite上保存的值会空值。如果你这样做:

mySprite.x = 0; 

初始化之前mySprite上(即分配到雪碧之前),您将有此相同的空引用错误。

此错误消息也提供了一些helpul背景下,您可以在他们使用你的优势(昔日 ...闪光灯错误是沉默;当事情没有工作,你不得不手动跟踪下来问题)。

好吧,让我们打破这种错误消息下:

at com.senocular.utils::KeyObject/construct() 
at com.senocular.utils::KeyObject() 
at com.asgamer.basics1::Ship() 
at com.asgamer.basics1::Engine() 

你在上面叫什么堆栈跟踪。它基本上告诉你代码在哪里爆炸,并给你一些背景:你是如何到达那里的。

第一行说明实际发生错误的位置。也就是说,KeyObject对象中的构造方法。该方法由KeyObject构造函数调用,该构造函数又由Ship构造函数调用,该构造函数又由Engine构造函数调用。

现在,让我们来分析一下,你如何到达那里,下面的堆栈跟踪,自下而上:

代码在发动机的构造:

ourShip = new Ship(stage); 

这将创建一个新的船舶对象。它将阶段的引用传递给Ship构造函数方法。

代码在船舶构造:

this.stageRef = stageRef; 
key = new KeyObject(stageRef); 

它吸引在上一步中通过裁判。它存储它并创建一个新的KeyObject对象。 KeyObject构造函数传递一个对stage的引用(这是从引擎传递给Ship的同一个引用)。

守则KeyObject构造:

KeyObject.stage = stage; 
keysDown = new Object(); 
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); 
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased); 

现在我们得到的地步,错误消息告诉你问题所在。所以,在某个地方,你正在使用一个变量来保存null并试图访问它的一个方法或属性。

此KeyObject存储对它在静态变量中传递的阶段的引用,并创建一个新的Object对象。到目前为止,没有问题。 KeyObject不能为null(它是对类的引用)。第二行本身也不能有这个空问题。因此,如果这是该方法中的所有代码,则问题必须位于第三行或第四行。都访问您通过的阶段引用,并尝试调用一个方法(addEventListener)。所以如果一个失败了,另一个也会失败。然后,第三行:这就是问题所在。

因此,在那一点stage为空。如前所述,你不能在null上调用方法,这就是错误告诉你的。

现在,如果你回到第一个方法调用,你可以看到,这是问题的根源:

ourShip = new Ship(stage); 

您可以相当肯定的是,在这一点上,阶段为空。再加上这个事实,即Engine扩展了MovieClip(这又是一个DisplayObject),并且事实上任何DisplayObject只有在它被添加到显示列表时才具有对舞台对象的引用。结论:Engine的实例在其构造函数运行时未附加到显示列表中。

解决方法(可能有其他方法)可能会将引擎构造函数中的代码移动到一个单独的函数,该函数仅当/当Engine对象具有对舞台对象的有效引用时才会执行。

public function Engine() : void { 
    if(stage) { 
     initialize(); 
    } else { 
     addEventListener(Event.ADDED_TO_STAGE,initialize); 
    } 
} 

private function initialize(e:Event = null):void { 
    removeEventListener(Event.ADDED_TO_STAGE,initialize); 
    // here goes the code that's currently in Engine constructor 
} 

希望这会有所帮助。

+0

非常感谢您花时间查看我的代码。 你的建议工作正常,现在问题已解决。 也感谢扩展答案,对于像我这样的初学者程序员非常有见识:) – 2010-05-21 10:16:35

+0

@matt_t。别担心! – 2010-05-21 13:47:25

1

我有一种感觉,你的舞台属性为空。

你必须自己测试一下舞台对象的轨迹。

在你的构造函数的第一行Engine类,添加:

trace(stage); 

添加,只是这条线之上:

ourShip = new Ship(stage); 

如果追溯“空”,那么这是你的问题。