从子类访问阶段元素

时间:2011-03-16 23:58:55

标签: flash actionscript-3

问题很简单:访问阶段对象(如影片剪辑或文本字段)来自子类。 当我定义一个子类并尝试访问阶段对象时,问题出现了。我怎样才能做到这一点? 想象一下,我在舞台上有一个名为redBox_mc的影片剪辑。我希望在我加载xml之后将其更改为alpha。(或者子类中的任何其他动作)

主要课程:

package src{
   // ..
   public class code01 extends MovieClip {
     public var rt:xmlReader = new xmlReader("art.xml"); // my subclass 
     public function code01():void {
     // .. my code
     }
   }
}

xmlReader子类:

package src{
    // ..
    public class xmlReader extends MovieClip {
        // ..  
        public function xmlReader(xmlFilename:String)
            // .. my code
                stage.redBox_mc.alpha =  .2 ; // doesn’t work
                MovieClip(parent).redBox_mc.alpha =  .2 ; // doesn’t work
        }
    }
}

请帮帮我..

1 个答案:

答案 0 :(得分:10)

有许多方法可以让子对象的类可以访问该阶段:

选项1

最简单的方法是将舞台的引用解析为子对象的类:

Main.as(文档类):

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite
    {
        public function Main()
        {
            if(stage) init()
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        public function init(e:Event = null):void
        {   
            var foo:Foo = new Foo(stage);

        }// end function

    }// end class

}// end package

Foo.as:

package 
{
    import flash.display.Stage;

    public class Foo
    {
        public function Foo(stage:Stage)
        {
            if(stage) trace("success"); // output: success

        }// end function

    }// end class

}// end package

选项2

另一个选项是将显示对象添加到显示列表中。通过这样做,您的显示对象的类将具有对该阶段的引用。然后,您必须在显示对象的类中添加一个事件侦听器,该类侦听要添加到舞台的显示对象。只有当事件监听器收到此事件时,您才会引用该阶段:

Main.as(文档类):

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite
    {
        public function Main()
        {
            if(stage) init()
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        public function init(e:Event = null):void
        {   
            var foo:Foo = new Foo();
            addChild(foo);

        }// end function

    }// end class

}// end package

Foo.as:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Foo extends Sprite
    {
        public function Foo()
        {
            if(stage) init()
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        public function init(e:Event = null):void
        {   
            if(stage) trace("success"); // output: success

        }// end function

    }// end class

}// end package

选项3

另一种选择是将阶段的引用存储在可以全局访问的类中。要执行此操作,您可以使用静态公共属性或方法来设置和直接从类中获取舞台的引用:

Main.as(文档类):

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Main extends Sprite
    {
        public function Main()
        {
            if(stage) init()
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        public function init(e:Event = null):void
        {   
            GlobalVars.stage = stage;

            var foo:Foo = new Foo();

        }// end function

    }// end class

}// end package

GlobalVar.as:

package
{
    import flash.display.Stage;

    public class GlobalVars
    {
        public static var stage:Stage;

    }// end class

}// end package

Foo.as

package 
{
    import flash.display.Stage;

    public class Foo
    {
        public function Foo()
        {
            var stage:Stage = GlobalVars.stage;
            if(stage) trace("success"); // output: success

        }// end function

    }// end class

}// end package

<强> [UPDATE]

查看您的代码我无法弄清楚为什么您的xmlReader类首先扩展DisplayObjectxmlReader似乎处理所有与xml相关的逻辑,如加载和解释xml,那么为什么不把它留在那?让另一个类处理舞台上的对象。我认为你的问题的真正解决方案是更好的代码结构,以下是一个例子:

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;

    public class Main extends Sprite
    {
        public function Main()
        {
            if(stage) init()
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        public function init(e:Event = null):void
        {   
            var textField:TextField = new TextField();
            textField.name = "textField";
            stage.addChild(textField);

            var stageManager:StageManager = new StageManager(stage, "dummy.xml");

        }// end function

    }// end class

}// end package

import flash.display.Stage;
import flash.events.Event;
import flash.text.TextField;

class StageManager
{
    private var _stage:Stage;
    private var _xmlReader:XMLReader;

    public function StageManager(stage:Stage, url:String)
    {
        _stage = stage;
        _xmlReader = new XMLReader(url);
        _xmlReader.addEventListener(Event.COMPLETE, onXMLReaderComplete);

    }// end function

    private function onXMLReaderComplete(e:Event):void
    {
        var textField:TextField = _stage.getChildByName("textField") as TextField;
        textField.text = "XML LOADED!";

    }// end function

}// end class

import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
import flash.errors.IOError;


class XMLReader extends EventDispatcher
{
    public var xml:XML;

    public function XMLReader(url:String) 
    {
        read(url);

    }// end function

    public function read(url:String)
    {
        var urlLoader:URLLoader = new URLLoader(new URLRequest(url));
        urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onURLLoaderIOError);
        urlLoader.addEventListener(Event.COMPLETE, onURLLoaderComplete);

    }// end function

    private function onURLLoaderIOError(e:IOErrorEvent):void
    {
        throw new IOError(e.text);

    }// end function

    private function onURLLoaderComplete(e:Event):void
    {
        xml = URLLoader(e.target).data as XML;
        dispatchEvent(new Event(Event.COMPLETE));

    }// end function

}// end class