无法从Flash IDE获取正确的类

时间:2011-08-11 01:48:35

标签: flash actionscript-3

我正在尝试将通过Flash的IDE拖放到MovieClip中创建的实例替换为实际类,这样我就可以将它们添加到游戏循环中并将它们作为实际实体。换句话说,我正在尝试创建一种简化的方法,允许开发人员可视化地将他们的实体添加到我正在处理的平台引擎中。

这是我的第三次尝试,我完全陷入困境。

下面的代码循环播放一个动画片段,该影片片段包含一个导出的符号,该符号链接到一个名为MyEntity的类。但是,它失去了BaseClass的扩展名,因此在编译时不会移动。

它继承:MovieClip > BaseClass > MyEntity。但是,当使用IDE编译时,它会忽略BaseClass并且只执行MovieClip > MyEntity

我的代码旨在查找并存储MyEntity的位置,将其从容器动画片段中删除,添加一个全新的实例(基础正确)然后将该新实例设置为相同的位置原来的。

for ( var i:int = 0; i < LayerInIDE.numChildren; i++ )
{
    // first we want to get all the display objects in the layer
    // these are objects that were placed from within the Flash IDE (ie. dragged and dropped into the MovieClip
    var original:DisplayObject = LayerInIDE.getChildAt( i );            

    // we want to get the class of the display object so we can recreate it as a specific entity class that it 
    var originalName:String = getQualifiedClassName( original );
    var originalClass:Class = getDefinitionByName( originalName ) as Class;

    // debug trace, see output below
    trace( originalName, originalClass, originalClass is BaseClass );

    // filter out movieclips
    if ( originalClass != MovieClip )
    {
        // remove the original
        LayerInIDE.removeChild( original );

        // recreate the class with the correct extension
        var newEnt = originalClass();
            newEnt.x = original.x; newEnt.y = original.y;
        LayerInIDE.addChild( newEnt );
    }
}

这不起作用。

输出Game.entities::MyEntity [class MyEntity] false。 MyEntity是一个合适的类,并且从BaseClass扩展。但是,问题是IDE奇怪地删除了对基类的引用 - 好像MyEntity从未有过基类。我似乎无法重新创建它,因为获取对类的引用也返回MyEntity从未有过BaseClass。但是,如果我键入var newEnt = MyEntity();而不是通过getDefinitionByName获取类名,则它会正常工作并从BaseClass扩展。

我需要它从BaseClass扩展,因为这是我的游戏引擎中所有实体都需要使用的主类。

有什么想法吗?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

因此,如果我理解正确,那么您要做的是允许人们将库资源拖到您可以检查并可能在运行时重新创建的舞台上?例如,在IDE中,有人创建了一个只有艺术品的愚蠢的精灵,将它拖到舞台上。将其设置为导出为“MyEntity”类。然后在运行时,您要检查它是否为“MyEntity”类型,以便您可以向其中注入您在BaseClass中定义的功能。如果是这种情况,您可以通过以下方式解决此问题:

var do:DisplayObject = LayerInIDE.getChildAt( i );
if (do is MyEntity){
    var bc:BaseClass = new BaseClass(do);
    addChild(bc);
}

// then inside of BaseClass.as

private var entity:MyEntity;
public function BaseClass(view:MyEntity)
{
    entity = view;
    addChild(entity);
// from here you can script your MyEntity object as needed.
}

答案 1 :(得分:0)

经过多次修补和普遍破坏Flash后,我得到了解决问题的方法。感谢Stephen Braitsch的帮助,让我朝着正确的方向前进。

好的,所以这个解决方案有点复杂(和hacky),但它解决了我之前讨论过的问题。

首先,您需要扫描特定动画片段中所有显示对象的主函数。我把我的名字命名为LayerInIDE

需要两个功能。 ReplaceEntsRecreateReplaceEnts扫描所有对象,并确定它们是否从BaseClass延伸。如果他们这样做,它会继续前进,然后通过Recreate抛出它们。 Recreate获取原始类和位置并重新创建类,允许我们在运行时正确访问资产。

import Game.entities.MyEntity;
import Game.entities.BaseClass;
import Game.entities.Layer;

var LayerInIDE:Layer = new Layer();
stage.addChild( LayerInIDE );

ReplaceEnts( LayerInIDE );

function ReplaceEnts( layer:Layer ):void
{
    for ( var i:int = 0; i < layer.numChildren; i++ )
    {
        // Get the display object.
        var original:DisplayObject = layer.getChildAt( i );

        // Make sure we're only doing this to objects that extend from BaseClass
        if ( original is BaseClass )
        {
            // Get the original class
            var originalName:String = getQualifiedClassName( original );
            var originalClass:Class = getDefinitionByName( originalName ) as Class;
            // Remove the original
            layer.removeChild( original );

            // Recreate it with the original class
            // Make sure we keep the original position and rotation.
            var bc = Recreate( originalClass, original.x, original.y, original.rotation );
            layer.addChild( bc );

            // Test functions
            trace( bc ); // outputs: [object MyEntity]
            bc.TestFunc(); // outputs: test
            bc.BaseTest(); // outputs: base
        }
    }
}

// This is the core function that does all the work.
// It recreates the entity with the proper class and sets it to its original position.
function Recreate( entClass:Class, iPosX:int = 0, iPosY:int = 0, iRot:int = 0 ):BaseClass
{
    var newEnt:BaseClass = new entClass();
    newEnt.x = iPosX; newEnt.y = iPosY;
    newEnt.rotation = iRot;

    return newEnt;
}

然后BaseClass包含:

package Game.entities
{
    import flash.display.MovieClip;

    public class BaseClass extends MovieClip
    {
        // The example function as mentioned above in the ReplaceEnts function.
        public function BaseTest():void
        {
            trace( "base" );
        }
    }
}

一旦完成设置,我们还需要制作MyEntity类:

package Game.entities
{
    public class MyEntity extends BaseClass
    {
        // The example function as mentioned above in the ReplaceEnts function.
        public function TestFunc():void
        {
            trace( "test" );
        }
    }
}

最后一点,Games.entities.Layer只是一个简单的MovieClip。我只是为了组织目的而创建了自己的类。

这里的解决方案很简单。当用户拖动从BaseClass扩展到图层的对象时,该函数在启动时运行并用适当的类替换资产,并允许实体管理器接管并适当地处理资产。它允许我想要实现的目标,一个由IDE驱动的关卡编辑器,可以自动完成所有工作,将实体放置在您想要的位置。

感谢所有帮助人员。