TypeError:错误#1009 Actionscript 3

时间:2010-05-21 02:13:54

标签: 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

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

2 个答案:

答案 0 :(得分:5)

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

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

消息说:

  

无法访问的属性或方法   空对象引用。

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

someobject.someMethod();

someobject.someProperty = "foo";

有些对象碰巧是空的。 您无法调用方法或访问null 的属性。

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

这只是说一个名为mySprite的变量可以保存一个Sprite类型的对象:

var mySprite:Sprite;

但是在某些时候你创建一个Sprite并将其分配给mySprite,mySprite保存的值将为null。如果你这样做:

mySprite.x = 0;

在初始化mySprite之前(即在为其指定Sprite之前),您将获得相同的Null Reference错误。

此错误消息还提供了一些帮助上下文,您可以利用这些上下文(在他们过去 ... Flash中的错误是沉默的;当事情不起作用时,您必须手动追查问题)。

好的,让我们打破这个错误信息:

 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对象。它将对舞台的引用传递给Ship构造函数方法。

Ship构造函数中的代码:

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

它抓住了上一步中传递的引用。它存储它并创建一个新的KeyObject对象。 KeyObject构造函数传递给阶段的引用(与从引擎传递到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(它是对Class的引用)。第二行本身也不能有这个空问题。因此,如果这是该方法中的所有代码,则问题必须在第三行或第四行。两者都访问您传递的阶段引用并尝试在其上调用方法(addEventListener)。所以,如果一个失败,另一个也会失败。然后,第三行:这就是问题所在。

因此,此时stage为空。如前所述,您无法在null上调用方法,这就是错误告诉您的内容。

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

ourShip = new Ship(stage);

你可以非常肯定,在这一点上,舞台是空的。将其添加到Engine扩展MovieClip(这又是一个DisplayObject)的事实,以及任何DisplayObject只有在添加到显示列表时才引用舞台对象这一事实。结论:当运行构造函数时,Engine的实例未附加到显示列表。

修复此问题的方法(可能还有其他方法)可能是将Engine构造函数中的代码移动到单独的函数中,该函数仅在/当Engine对象具有对stage对象的有效引用时才会执行。

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
}

希望这有帮助。

答案 1 :(得分:1)

我觉得你的舞台属性是空的。

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

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

trace(stage);

在此行上方添加:

ourShip = new Ship(stage);

如果它跟踪“null”那么那就是你的问题。