如何使用以下方法动态创建基于ActionScript 2 MovieClip的类

时间:2020-03-06 14:58:33  来源:igfitidea点击:

我已经创建了一个帮助程序方法,该方法允许在代码中基于MovieClip的类并调用构造函数。不幸的是,该解决方案并不完整,因为从不调用MovieClip回调onLoad()。

(链接到创建方法的Flashdevelop线程。)

如何修改以下函数,以便正确调用构造函数和onLoad()。

//------------------------------------------------------------------------
    //  - Helper to create a strongly typed class that subclasses MovieClip.
    //  - You do not use "new" when calling as it is done internally.
    //  - The syntax requires the caller to cast to the specific type since 
    //    the return type is an object. (See example below).
    //
    //  classRef, Class to create 
    //  id,       Instance name
    //  ...,      (optional) Arguments to pass to MovieClip constructor
    //  RETURNS   Reference to the created object 
    //  
    //  e.g., var f:Foo = Foo( newClassMC(Foo, "foo1") );
    //
    public function newClassMC( classRef:Function, id:String ):Object 
    {
      var mc:MovieClip = this.createEmptyMovieClip(id, this.getNextHighestDepth()); 
      mc.__proto__ = classRef.prototype; 

      if (arguments.length > 2) 
      {
        // Duplicate only the arguments to be passed to the constructor of
        // the movie clip we are constructing.
        var a:Array = new Array(arguments.length - 2);
        for (var i:Number = 2; i < arguments.length; i++)
          a[Number(i) - 2] = arguments[Number(i)];

        classRef.apply(mc, a);
      }
      else
      {
        classRef.apply(mc);
      }

      return mc; 
    }

我可能要创建的一个类的示例:

class Foo extends MovieClip

以及一些有关当前如何在代码中创建类的示例:

// The way I most commonly create one:
var f:Foo = Foo( newClassMC(Foo, "foo1") );

// Another example...
var obj:Object  = newClassMC(Foo, "foo2") );
var myFoo:Foo   = Foo( obj );

解决方案

我是否正确理解我们要创建一个添加了类行为且无需在库中定义空剪辑符号的空电影剪辑的实例?

如果是这种情况,则需要使用软件包技巧。这是我多年来一直在数百个项目中使用的基类(称为"视图"):

import mx.events.EventDispatcher;

class com.tequila.common.View extends MovieClip
{
    private static var _symbolClass : Function = View;
    private static var _symbolPackage : String = "__Packages.com.tequila.common.View";

    public var dispatchEvent : Function;
    public var addEventListener : Function;
    public var removeEventListener : Function;

    private function View()
    {
        super();

        EventDispatcher.initialize( this );

        onEnterFrame = __$_init;
    }

    private function onInitialize() : Void
    {
            // called on the first frame. Event dispatchers are
            // ready and initialized at this point.
    }

    private function __$_init() : Void
    {
        delete onEnterFrame;

        onInitialize();
    }

    private static function createInstance(symbolClass, parent : View, instance : String, depth : Number, init : Object) : MovieClip
    {
        if( symbolClass._symbolPackage.indexOf("__Packages") >= 0 )
        {
            Object.registerClass(symbolClass._symbolPackage, symbolClass);
        }

        if( depth == undefined )
        {
            depth = parent.getNextHighestDepth();
        }

        if( instance == undefined )
        {
            instance = "__$_" + depth;
        }

        return( parent.attachMovie(symbolClass._symbolPackage, instance, depth, init) );
    }

    public static function create(parent : View, instance : String, depth : Number, init : Object) : View
    {
        return( View( createInstance(_symbolClass, parent, instance, depth, init) ) );
    }
}

因此,使用该类所需要做的就是将其子类化:

class Foo extends View
{
    private static var _symbolClass : Function = Foo;
    private static var _symbolPackage : String = "__Packages.Foo";

    private function Foo()
    {
       // constructor private
    }

    private function onInitialize() : Void
    {
            // implement this to add listeners etc.
    }

    public static function create(parent : View, instance : String, depth : Number, init : Object) : Foo
    {
        return( Foo( createInstance(_symbolClass, parent, instance, depth, init) ) );
    }
}

我们现在可以像这样创建Foo的实例;

var foo : Foo = Foo.create( this );

假设"这"是某种类型的MovieClip或者View。

如果需要将其与库符号一起使用,则只需在_symbolPackage成员上省略__Packages前缀即可。

希望这可以帮助...