0

我有两节课;我的 Main 类和一个名为 BlockPlace 的类。我想使用我的 Main 类来运行 BlockPlace,但由于某种原因它不起作用。我已经尝试更改这两个代码,但它只会导致错误。我知道代码有效,因为我在时间轴上对其进行了测试。我应该重组整个事情还是有不同的解决方案?这是我的课程:

主类:

package  
{  
    import flash.display.*;
    import source.map.*;

    public class Main extends MovieClip{
        public function Main()  
        {  
            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;
        }
    }
}
4

2 回答 2

4

我可以看到您有几个问题,这可以解释您所看到的行为。

首先,您调用 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。因此,您无法向舞台添加任何内容或获取stageHeightor 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.

于 2012-07-24T17:45:27.877 回答
1

改变:

BlockPlace();

到:

var blockPlace:BlockPlace = new BlockPlace();

您需要实际实例化它。

于 2012-07-24T17:17:39.573 回答