我可以看到您有几个问题,这可以解释您所看到的行为。
首先,您调用 this 就像是一个函数,而不是构造函数。
如果你想静态引用这个函数,那么你想稍微改变一下:
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,并且该方法被标记为静态,这意味着它可以直接从该类中引用,而无需该类的实例。另请注意,函数签名已更改。它现在接受一个从外部传入的参数——舞台。
使用这种方法,您将引用从您的Main
实例到此实用程序函数的阶段来做一些工作。这可能是解决您的问题的最直接的解决方案。
相反,如果您想将其保留为扩展 MovieClip 的类——这意味着一些含义——那么您需要实例化该类的一个实例:
var blockPlace:BlockPlace = new BlockPlace();
然后,你需要把它放在圣人身上:
this.addChild(blockPlace);
但是舞台上仍然存在一些鸡/蛋问题。当您实例化该类时,您在其构造函数中引用该stage
属性。然而,在它的建造的这一点上,它还没有被添加到任何DisplayObjectContainers
与舞台相连的人身上。所以stage
属性将是null
。因此,您无法向舞台添加任何内容或获取stageHeight
or 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;
}
}
}
In the constructor, it checks to see if there is a stage, and if so then it immediately calls the function. If not, then it sets up a listener to wait until that happens. Then in the handler, if it was called because of an event, then clean up after itself and remove the listener.