我在Sprite周围创建了一个名为ClickableCircle的包装器,用于在实例化时将自身添加到显示列表中。这是一个玩具版本:
public class ClickableCircle extends Sprite {
protected var circle:Shape;
protected var myName:String;
public function ClickableCircle(name:String, x:uint, y:uint) {
super();
circle:Shape = new Shape();
circle.graphics.beginFill(0x00ACDC, 1);
circle.graphics.drawCircle(0, 0, 12);
this.myName = name;
this.x = x;
this.y = y;
this.addChild(circle);
this.addEventListener(MouseEvent.CLICK, reportClickedID);
// Here's the problematic line: can't add itself to display list
// Error #1009: Cannot access a property or method of a null object reference.
stage.addChild(this);
trace("Created " + name + " at " + String(x) + ", " + String(y));
}
private function reportClickedID(e:MouseEvent):void {
trace("You just clicked on " + this.myName);
}
}
问题在于,当从主应用程序实例化ClickableCircle时,它会在尝试将自身添加到舞台时崩溃,bc stage为null。另一方面,如果addChild()从ClickableCircle构造函数中注释掉,并且实例化的cs被添加到主应用程序级别的显示列表中,那么一切正常:
public class GreetingApp extends Sprite {
public function GreetingApp() {
var cs:ClickableCircle = new ClickableCircle("joe", 100, 200);
// If the child is added here, everything works.
stage.addChild(cs);
}
}
由于GreetingApp和ClickableCircle都扩展了Sprite,我认为该阶段将在两个地方实例化并可访问。我是ActionScript / Flex的新手,所以我确定我做的事情很愚蠢。谁能告诉我它是什么?
答案 0 :(得分:2)
你是对的,舞台将为空。原因是因为DisplayObjects只有在添加到显示列表后才会对stage进行隐式引用。在你的情况下,这会产生一些捕获22。
至少有几种方法可以解决这个问题。
选项1:在构造函数中传递对舞台的引用。像
这样的东西var cs:ClickableCircle = new ClickableCircle("joe", 100, 200, stage);
现在,在ClickableCircle实例中,您可以访问舞台。我通常会像这样使用它
public function ClickableCircle(name:String, x:uint, y:uint, target:*) {
...
target.addChild(this);
}
选项2.您可以使用静态变量来引用主应用程序类中的舞台。或者,同样地,您可以使用在创建ClickableCircle之前实例化的单例,并将对该阶段的引用传递给单例。然后你可以从任何地方访问它。
public static var STAGE:DisplayObjectContainer;
然后,假设您的类名为Main,您可以在ClickableCircle类中执行此操作:
Main.STAGE.addChild(this);
如果这没有意义,或者您需要更多帮助,请告诉我。
答案 1 :(得分:1)
实际上,一个有用的实用程序是一种StageManager,它是从Main Application Sprite / MovieClip / DisplayObject设置的。您可以键入Stage的访问者,因为这是更合适的类类型。
private var _stage:Stage;
public static function get stage() : Stage
{
if( stage == null ) throw new Error( "You must set the stage in your root before trying to access it." );
return stage;
}
public static function set stage( value:Stage )
{
_stage = value;
}
这是一个合理的单例,因为每个应用程序中只有一个Stage实例。