我有两节课;我的Main类和一个名为BlockPlace的类。我想使用我的Main类来运行BlockPlace,但由于某种原因它无法运行。我尝试过更改这两个代码,但只会导致错误。我知道代码有效,因为我在时间轴上测试了它。我应该重组整个事物还是有不同的解决方案?这是我的课程:
主要类别:
package
{
import flash.display.*;
import source.map.*;
public class Main extends MovieClip{
public function Main()
{
BlockPlace();
}
}
}
BlockPlace:
package source.map{
import flash.display.MovieClip;
import flash.display.Stage;
public class BlockPlace extends MovieClip{
public function BlockPlace(){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
答案 0 :(得分:4)
你可以看到几个问题,这可能会解释你所看到的行为。
首先,您将此称为函数,而不是构造函数。
如果你想静态引用这个函数,那么你想稍微改变一下:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public static function create(stage:Stage){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用:
调用它BlockPlace.create(stage);
请注意,该类不再扩展MovieClip,并且该方法被标记为static,这意味着它可以直接从类中引用,而不需要该类的实例。另请注意,功能签名已更改。它现在接受一个从外部传入的参数 - 阶段。
使用此方法,您可以将Main
实例中的舞台引用添加到此实用程序功能中以执行某些操作。这可能是解决您问题的最直接的解决方案。
相反,如果你想把它保持为扩展MovieClip的类 - 这意味着什么 - 那么你需要实例化一个类的实例:
var blockPlace:BlockPlace = new BlockPlace();
然后,你需要在圣人身上得到它:
this.addChild(blockPlace);
但是你的舞台上还有一点鸡蛋问题。实例化类时,在其构造函数中引用stage
属性。然而,在它构造的这一点上,它还没有被添加到任何附着在舞台上的DisplayObjectContainers
。因此stage
属性为null
。因此,您无法向舞台添加任何内容或获取stageHeight
或stageWidth
。
你需要等到发生这种情况 - 直到addChild(blockPlace)
被宣告才会发生。
因此,您需要重新考虑一下您的架构,您可以将逻辑移动到另一个函数中,一旦您确定它已附加到舞台上,您将明确调用该函数。类似的东西:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
}
public function initialize():void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用类似的东西消费:
var blockPlace:BlockPlace = new BlockPlace();
addChild(blockPlace);
blockPlace.initialize(); // safe to call because its on the stage now given that `this` is on the stage
然而,更惯用的方法是使用事件等待MovieClip添加到舞台,然后执行一些工作。例如:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
this.addEventListener(Event.ADDED_TO_STAGE, stageAvailable);
}
private function stageAvailable(e:Event):void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
请注意,构造函数现在设置了一个事件监听器,该监听器说:“当我被添加到阶段时,请执行另一个名为stageAvailable
的函数中的工作。”
您必须注意一些小的警告,可以直接在舞台上构建显示对象 - Flash IDE会这样做。所以事件不会为那些物品开火,因为当事件被附加时,它已经在舞台上,因此不会开火。写作最具防御性的方式是:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
if(stage) stageAvailable()
else this.addEventListener(Event.ADDED_TO_STAGE, stageAvailable);
}
private function stageAvailable(e:Event = null):void {
if(event) this.removeEventListener(Event.ADDED_TO_STAGE, stageAvailable);
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
在构造函数中,它检查是否有一个阶段,如果是,则立即调用该函数。如果没有,那么它会设置一个监听器,等待这种情况发生。然后在处理程序中,如果由于事件而调用它,则在自身之后清理并删除侦听器。
答案 1 :(得分:1)
变化:
BlockPlace();
为:
var blockPlace:BlockPlace = new BlockPlace();
你需要实际实例化它。