【问题标题】:Select an FXG file at the runtime - by its name在运行时选择一个 FXG 文件 - 按其名称
【发布时间】:2012-04-16 11:07:35
【问题描述】:

我有一个测试用例来证明我的问题。

当您在 Flash Builder 4.6 中将以下 4 个短文件添加到新的 Flex Mobile 项目中时,它会立即运行:

src/TestFXG.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    firstView="Home">
</s:ViewNavigatorApplication>

src/assets/en/Star.fxg:

<?xml version='1.0' encoding='UTF-8'?>
<fxg:Graphic xmlns:fxg="http://ns.adobe.com/fxg/2008" version="2">    
    <fxg:Path x="9.399" y="10.049" data="M 82.016 78.257 L 51.895 69.533 L 27.617 89.351 L 26.621 58.058 L 0.231 41.132 L 29.749 30.52 L 37.714 0.241 L 56.944 24.978 L 88.261 23.181 L 70.631 49.083 Z">
        <fxg:fill>
            <fxg:SolidColor color="#FFFFFF"/>
        </fxg:fill>
        <fxg:stroke>
            <fxg:SolidColorStroke 
                caps="none" 
                color="#FFFF66" 
                joints="miter" 
                miterLimit="4" 
                weight="10"/>
        </fxg:stroke>
    </fxg:Path>
</fxg:Graphic>

src/Home.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:my_components="*"
        title="Display random amount of stars">

    <fx:Script>
        <![CDATA[
            import Star;
            import spark.core.SpriteVisualElement;

            private static const STAR:SpriteVisualElement = new Star();
        ]]>
    </fx:Script>    

    <my_components:MyComp />
</s:View>

src/MyComp.as:

package {
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.utils.getDefinitionByName;
    import mx.core.UIComponent;
    import spark.core.SpriteVisualElement;
    import assets.Star;

    public class MyComp extends UIComponent {
        private static const WHAT:String = "assets.en.Star";

        override protected function createChildren():void {
            super.createChildren();

            for (var i:uint = 0; i < 3; i++) {
                var star:Star = new Star();
                //var star:SpriteVisualElement = new (getDefinitionByName(WHAT) as Class)();
                star.x = Math.random() * 100;
                star.y = Math.random() * 100;
                addChild(star);
            }
        }
    }
}

我的问题是:如果我在 assets 子目录中有许多适当命名的 FXG 文件(在我的实际应用程序中,我有 spades_queen.fxg、spades_king.fxg、spades_ace.fxg 等) -如何在运行时选择 FXG 文件?

上面的注释行给了我运行时错误:

ReferenceError: Error #1065: Variable Star is not defined.
    at global/flash.utils::getDefinitionByName()

当我将 src/assets/en/Star.fxg 移动到 src/Star.fxg 时,一切正常...

【问题讨论】:

    标签: actionscript-3 apache-flex flex4.6 flex-mobile fxg


    【解决方案1】:

    我猜您收到此运行时错误是因为 Star.fxg 未编译到完成的应用程序中,因为它没有按名称使用。令人困惑的是,为什么移动文件的位置会绕过错误。

    但是,请尝试在其中添加文件引用。导入它:

    import assets.en.Star
    

    并创建一个您从不使用的 Dum 实例,以便确保将文件编译到应用程序中:

    private var myStart :Star;
    

    那么这条线应该可以工作:

    var star:SpriteVisualElement = new (getDefinitionByName(WHAT) as Class)();
    

    您还可以使用编译器参数来强制将 FXG 类编译到您完成的应用程序中。

    我在我的 Casual Game 中使用了同样的方法,内置于 Flex。

    然而,奇怪的是为什么将文件移动到不同的目录会导致工作没有问题。这是一个谜,除非你引用了错误的包。 (AKA assets.en.Star--正如您在代码中使用的那样--verse src/assets/Star 您在问题中引用)。

    【讨论】:

      【解决方案2】:

      您不需要对 getDefinitionByName 做任何事情,您只需创建一个新的 Start 实例并使用 addElement 将其放置在舞台上。

              for (var i:uint = 0; i < 3; i++) {
                  var star:Star = new Star();
                  star.x = Math.random() * 100;
                  star.y = Math.random() * 100;
                  addElement(star);
              }
      

      为了让它工作,你必须导入你的 FXP 所在的包。可能是 assets.Star

      您也可以通过创建新实例来切换类型。

      假设你的资产中有 Star.fxg 和 King.fxg

      import assets.Star;
      import assets.King;
      
      var star:Star = new Star();
      var king:King = new King();
      

      【讨论】:

      • 是的,这有效 - 在编译时。但我的问题是:如何在运行时选择、加载和显示 FXG。例如,当您有一个 var WHAT:String - 可以容纳 StarKing
      • 您可以只传入一个字符串并在 switch 语句中使用它。 switch(item){ case "star": return new Star();休息;案例“国王”返回新国王();打破}
      • 您可以在类名上使用 getDefinitionByName。您只需要确保它已导入
      • 如果您查看我的问题,它已导入,但我无法让 getDefinitionByName 工作 - 除非我将所有 FXG 复制到根 src/ 目录中 - 我想避免这种情况并保留src/assets 目录下的 52 个用于扑克牌的 FXG 文件。
      • @f-a 导入它只是成功的一半;如果没有明确使用,Flex 编译器将删除该类。您还需要该类型的变量。您不必实例化它。或者您可以强制编译器不要删除带有编译器参数的类。我也认为“switch 语句方法”很糟糕。实用,但不灵活。
      猜你喜欢
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      相关资源
      最近更新 更多