TypeError:错误#1009 Actionscript 3

mat*_*t_t -1 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()
Run Code Online (Sandbox Code Playgroud)

现在,没有真正理解错误我粘贴在线转储文件供你查看.

Ship class: textbin.com/78z35

Engine class: textbin.com/32b24

KeyObject class: textbin.com/p2725
Run Code Online (Sandbox Code Playgroud)

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

Jua*_*ano 5

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

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

消息说:

无法访问null对象引用的属性或方法.

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

someobject.someMethod();
Run Code Online (Sandbox Code Playgroud)

要么

someobject.someProperty = "foo";
Run Code Online (Sandbox Code Playgroud)

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

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

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

var mySprite:Sprite;
Run Code Online (Sandbox Code Playgroud)

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

mySprite.x = 0;
Run Code Online (Sandbox Code Playgroud)

在初始化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()
Run Code Online (Sandbox Code Playgroud)

你上面所说的是一个堆栈跟踪.它基本上告诉你代码爆炸的地方,并且还给你一些背景信息:你是如何实现的.

第一行告诉错误实际发生的位置.也就是KeyObject对象中的构造方法.该方法是从KeyObject构造函数调用的,而后者又是从Ship构造函数调用的,而构造函数又是从Engine构造函数调用的.

现在,让我们分析堆栈跟踪,自下而上的方式:

引擎构造函数中的代码:

ourShip = new Ship(stage);
Run Code Online (Sandbox Code Playgroud)

这将创建一个新的Ship对象.它将对舞台的引用传递给Ship构造函数方法.

Ship构造函数中的代码:

this.stageRef = stageRef;
key = new KeyObject(stageRef);
Run Code Online (Sandbox Code Playgroud)

它抓住了上一步中传递的ref.它存储它并创建一个新的KeyObject对象.KeyObject构造函数传递给阶段的引用(与从Engine传递到Ship的ref是相同的).

KeyObject构造函数中的代码:

KeyObject.stage = stage; 
keysDown = new Object(); 
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
Run Code Online (Sandbox Code Playgroud)

现在我们到了错误消息告诉你问题所在的位置.因此,在某个地方,您使用的是一个保存null并尝试访问其某个方法或属性的变量.

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

所以,那时stage是空的.如前所述,您无法在null上调用方法,这就是错误告诉您的内容.

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

ourShip = new Ship(stage);
Run Code Online (Sandbox Code Playgroud)

你可以非常肯定,在这一点上,阶段是空的.将其添加到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
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.