【问题标题】:Unable To Get Proper Class from Flash IDE无法从 Flash IDE 获取正确的类
【发布时间】:2011-10-24 14:23:34
【问题描述】:

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

这是我第三次尝试它,我完全被卡住了。

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

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

我的代码旨在查找和存储MyEntity 的位置,将其从容器movieclip 中删除,添加它的全新实例(基础正确),然后将该新实例设置为与原创。

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 扩展,因为这是我的游戏引擎中所有实体都需要使用的主类。

有什么想法吗?还是有更好的办法?

【问题讨论】:

  • 库中 MyEntity 剪辑的链接属性如何?你能上传截图吗?你如何创建你的类的第一个对象?
  • 当然,MyEntity 的属性窗口如下所示。这也是code for MyEntityBaseClass。这些被削减只是为了证明这个问题。这就是LayerInIDE contains。在进一步研究这个问题后,我相信这是上课的问题。它似乎删除了对象的所有属性。
  • 您可以尝试将 MyEntity 设置为 BaseClass 并将任何内容设置为“Class”。

标签: flash actionscript-3


【解决方案1】:

在对 Flash 进行了多次修补和普遍破坏后,我找到了解决问题的方法。感谢Stephen Braitsch 帮助我找到正确的方向。

好的,所以这个解决方案有点复杂(而且很老套),但它解决了我之前讨论的问题。

首先,您需要扫描特定影片剪辑中所有显示对象的 main 函数。我已经命名为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 提供支持的关卡编辑器,可以自动完成所有工作,将实体放置在您想要的位置。

感谢大家的帮助。

【讨论】:

    【解决方案2】:

    所以,如果我理解正确,您想要做的是允许人们将库资源拖到您可以检查并可能在运行时重铸的舞台上?例如,在 IDE 中,有人创建了一个只有艺术品的哑 Sprite,将其拖到舞台上并将其设置为导出为“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.
    }
    

    【讨论】:

    • 虽然这绝对有效并获得了艺术品,但这并不是我所需要的。我需要能够使用从 BaseClass 扩展的任何类来执行此操作。换句话说,它可能不是 MyEntity,它可能是 MyCharacterEntity。我在您的示例中遇到的另一个问题是,一旦您将其重铸为 BaseClass,它就会失去其所有原始类函数。 MyEntity 具有使其成为 MyEntity 的函数,而不仅仅是具有默认函数的 BaseClass。虽然这肯定让我朝着正确的方向前进。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2021-04-27
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    相关资源
    最近更新 更多