你如何从另一个班级访问一个班级?

时间:2012-07-24 17:08:22

标签: actionscript-3

我有两节课;我的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;
        }
    }
}

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。因此,您无法向舞台添加任何内容或获取stageHeightstageWidth

你需要等到发生这种情况 - 直到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();

你需要实际实例化它。