1

所以我已经通过 SO 进行了大量搜索,但无法找到这个问题的答案。我的符号库中有一个为动作脚本导出的影片剪辑,并且我已经为它编写了一个自定义类。除了在我将影片剪辑添加到舞台后尝试访问自定义私有属性时,它大部分都很好用。下面是一个例子:

package {

    public class MyMovieClip extends MovieClip {

        private var _isEnabled:Boolean = false;

        public function MyMovieClip():void {

            trace(this);
        }

        public function set isEnabled( b:Boolean ):void {

            _isEnabled = b;
        }

        public function get isEnabled():Boolean {

            return _isEnabled;
        }
    }
}

然后我有另一个类,我在循环中将movieclip的实例添加到舞台:

package {

    public class MyOtherClass extends MovieClip {

        public var myMC:MyMovieClip;
        public var docClass:*;

        public function MyOtherClass( docRef:* ):void { // passing in a reference to the DocumentClass so I can access the stage
            docClass = docRef;
            init();
        }

        public function init():void {

            for(var i:int=0; i<6; i++) {

                var myMC:MyMovieClip = new MyMovieClip; // instantiate the movieclip which is exported for actionscript and has a custom class 
                //set a few native properties
                myMC.name = "myMC" + i; //setting the name so I can reference this movieclip after it's been added to stage
                myMC.y = myMC.height * i + 20;
                myMC.x = 20;
                myMC.alpha = .7;
            }

            dispatchEvent(new Event(MyOtherClass.MOVIECLIPS_ADDED)); // just to be safe, let's dispatch a custom event when all movieclips have been added
        }

        public function traceEnabled():void {

            trace(docClass.stage.getChildByName("myMC1").isEnabled); // this throws: 1119: Access of possibly undefined property isEnabled through a reference with static type flash.display:DisplayObject

        }
    }
}

最后我在我的文档类中实例化 MyOtherClass:

package {

    public class DocumentClass extends MovieClip {

        public var myOtherClass:MyOtherClass;

        public function DocumentClass():void {

            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }

        public function onAddedToStage(e:Event):void {

            myOtherClass = new MyOtherClass(); // upon instantiation, init is called in MyOtherClass and all of my movieclips are added to the sage
        }
    }
}

是什么赋予了?为什么 MyMovieClip 属性 isEnabled 在添加到舞台后无法访问?还有其他方法吗?(提前感谢您的帮助)

4

1 回答 1

0

在内部,a 的所有子项DisplayObjectContainer都被引用为DisplayObject,因此当您使用 时getChildByName,它会返回一个 DisplayObject。

为了在不导致编译时错误的情况下访问您的自定义属性,您需要将结果转换getChildByName为自定义属性的类。请参阅下面的代码。

然而,这不是您唯一的问题(尽管这是错误的原因,一旦您更正,您也会遇到运行时错误)。

在您的创建循环中,您没有添加myMC到显示列表中,因此调用 stage.getChildByName() 将返回 null,因为您的剪辑不在舞台上。

您也没有将 myOtherClass 添加到已发布代码的显示列表中。

此外,实际上并不需要存储对文档类的引用。只需添加 addedToStage 侦听器MyOtherClass并初始化处理程序。

这是一些更新的代码,适用于您MyOtherClass

    public function MyOtherClass():void { 
        if(stage){
            init(); //if stage is ready, call init, if not wait for the added to stage event
        }else{
            addEventListener(Event.ADDED_TO_STAGE,init);
        }
    }

    public function init(e:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE,init);

        for(var i:int=0; i<6; i++) {

            var myMC:MyMovieClip = new MyMovieClip;
            myMC.name = "myMC" + i; //setting the name so I can reference this movieclip after it's been added to stage
            myMC.y = myMC.height * i + 20;
            myMC.x = 20;
            myMC.alpha = .7;

            addChild(myMC); //!!!! add to the displayList
        }

        dispatchEvent(new Event(MyOtherClass.MOVIECLIPS_ADDED)); // just to be safe, let's dispatch a custom event when all movieclips have been added
    }

    public function traceEnabled():void {
        var myMC:MyMovieClip = this.getChildByName("myMC1") as MyMovieClip; //!!! cast it as MyMovieClip so you have access to all the properties/methods in that class
        if(myMC){  //myMC will be null if the cast failed
            trace(myMC.isEnabled); 
        }
    }

    /*
       getChildByName is slow and cumbersome. Most people generally only use it for accessing things put on the timeline in the Flash IDE.  Using events is a much better way of accessing your items. If traceEnabled was caused by a mouse event attached to myMC, then this would be a much better implementation:
    */
    public function betterTraceEnabled(e:Event):void {
        var myMC:MyMovieClip = e.currentTarget as MyMovieClip;
        if(myMC){
            trace(myMC.isEnabled);
        }
    }

和您的文档类别:

public class DocumentClass extends MovieClip {

    public var myOtherClass:MyOtherClass;

    public function DocumentClass():void {

        if(stage){
            onAddedToStage(null); //most of the time stage is already populated in the constructor of your document class
        }else{
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }
    }

    public function onAddedToStage(e:Event):void {

        myOtherClass = new MyOtherClass(); // upon instantiation, init is called in MyOtherClass and all of my movieclips are added to the sage
        addChild(myOtherClass); //add it to the displayList
    }
}
于 2012-09-21T21:00:33.253 回答