如何以正确的方式在 Actionscript 3 / Flex 3 中嵌入图像?

Posted

技术标签:

【中文标题】如何以正确的方式在 Actionscript 3 / Flex 3 中嵌入图像?【英文标题】:Howto embed images in Actionscript 3 / Flex 3 the right way? 【发布时间】:2010-11-06 09:58:12 【问题描述】:

我正在创建一个在 Actionscript / Flex 3 (Flash) 中使用大量图像的游戏。现在我已经到了设计阶段,我必须想出一种使用嵌入图像的结构化方式(必须通过旋转、颜色等进行操作)。

不幸的是,经过一番调查后,您似乎必须手动嵌入图像才能使用它们。我目前有这样的设置:

Resource.as 类文件:

package

    public final class Resource
    
        [Embed (source="/assets/ships/1.gif" )]
        public static const SHIPS_1:Class;
    

所以,对于一艘船,我必须:

将图像以正确的名称放入正确的文件夹中 在 Resource.as 文件中以相同的方式命名它 在 Resource.as 文件中创建同名常量

即使这一切都可以通过简单地将文件放在指定的文件夹中来实现。

为了让事情变得更糟,我仍然必须使用:

var test:Bitmap = new Resource.SHIPS_1();

在创建非常庞大的应用程序时,必须有更好的方法来处理资源吗?想象一下,我需要数千张图片,这个系统根本不适合。

【问题讨论】:

对游戏开发一无所知,但您真的需要嵌入数千张图片吗?似乎 swf 会变得相当庞大 【参考方案1】:

而不是

var test:Bitmap = new Resource.SHIPS_1();

使用

myImage.source = Resource.SHIPS_1;

嵌入是正确的。 :D 你使用它的方式是错误的:)

阿德里安

【讨论】:

但是这种嵌入方式会带来很多麻烦。没有更好的办法吗? 编辑:Resource.SHIPS_1 在 Resource 甚至没有定义的情况下怎么可能是正确的? 1. Resource.SHIPS_1 必须事先定义。 2.没有别的办法..除了嵌入到css文件中,但那更糟:( 您不需要实例化 Resource,您将 SHIPS_1 定义为静态常量,因此您只需将其用作 adrian 指出的源。【参考方案2】:

这正是 Flash CS4 的用途。不过,您的方式对我来说似乎很好-尽管即使它是常量,我也不会将所有大写用于类名。低下头来复制粘贴吧!

或者,您可以在运行时加载文件。

【讨论】:

+1 在运行时加载文件。否则,您最终可能会得到比您真正需要的更大的 SWF。 你是说我应该从网络服务器加载它们? 这样做的(大)缺点是每个人都可以下载我所有的图形内容。 每个人(拥有正确的工具和知识)都可以下载您的内容,“下载以显示您想要的方式”和“下载以存储它”在技术上是相同的。你可以让它变得更难,但不要自欺欺人地认为它不能或不会这样做。【参考方案3】:

如果您需要处理大量资源,您可以按照以下 3 个步骤操作:

    将它们放在未压缩的 zip 存档中

    将 zip 文件嵌入为二进制数据:

    [嵌入(source = 'resources.zip', mimeType = 'application/octet-stream')]

    使用FZip访问资源

如果您选择涉及加载外部文件的其他方法,请注意某些 Flash 游戏网站要求将其托管的游戏包含在单个 swf 文件中。

【讨论】:

【参考方案4】:

更好的方法 http://itfailed.blogspot.com/2011/02/howt-o-embed-images-in-actionscript-3.html

【讨论】:

它比任何东西都“好得多”?这只是最简单的标准方法,甚至在原始问题和许多答案中都提到过:P【参考方案5】:

这取决于您的单个图像有多大,但您可以将它们全部放在一个图像中,就像精灵表一样。如果您想绘制一艘特定的船,请在该船的图像中使用正确的 xy 偏移量,并使用 copyPixels 将其绘制到您的位图上。

【讨论】:

【参考方案6】:

这是旧的,但因为我偶然发现它寻找不同的东西,我会在这里为后代写:)

我使用不同的方法。我用 Flash Professional 创建了一个 swf 电影并导入其中的所有图形,然后将它们全部标记为“Export for ActionScript”。 编译 swf 并在您的主项目中仅嵌入 swf 并通过它访问所有图形...

我发现这种方法更有条理。既然可以通过导入文件来实现,为什么还要编写整个资源类呢? ;)

【讨论】:

因为开发人员讨厌 *uckin' Flash 创作工具(CS5、CS4、Cs3 等)。它过时了,它很旧。我的意思是——我喜欢 Flash,但 Adob​​e 搞砸了 Flash 创作软件。开发人员希望将自己选择的文本编辑器与 flex 框架结合使用。您的建议意味着开发人员必须在 Flash 和编辑器之间切换 - 这简直糟透了! 我不同意,尊敬的。即使我非常讨厌 Flash 开发环境(我自己也是 flashDevelop 人),但当有一个完美的可用图形环境进行布局时,那就在那里进行布局吧!当您可以从您的 Photoshop 模型在 Flash 中组装整个东西时,谁愿意复制和粘贴 x 和 y 坐标?好吧,我想这完全取决于你的工作流程,以及你是一个纯粹的开发者。 @TomAuger 使用创作软件还有一个问题:它完全由供应商锁定。一旦您的作品进入 Adob​​e 环境,它就会永远被困在那里,因为除了 Adob​​e 昂贵的过时软件之外,它无法在任何软件中使用。 @SasQ 我不确定我是否理解您的评论。 OP 是关于嵌入图像的。如果您使用 Flash IDE 导入图像,您仍然可以在其他任何地方使用这些图像。只有当您谈论的是在 Flash 中创建的矢量图时,您的评论才有意义。【参考方案7】:
package

    public final class Resource
    
        [Embed (source="/assets/ships/1.gif" )]
        public static const SHIPS_1:Class;
    

【讨论】:

【参考方案8】:
[Embed (source="/assets/ships/1.gif" )]
    public static const SHIPS_1:Class;

【讨论】:

【参考方案9】:

我喜欢这样做我的图书馆课程。

我为单身人士获取了 GSkinners 代码:http://gskinner.com/blog/archives/2006/07/as3_singletons.html

package

    import flash.display.Bitmap;
    import flash.display.BitmapData;

    public class Lib
    
        /*
        Make this an Singleton, so you only load all the images only Once 
        */

        private static var instance:Lib;
        public static function getInstance():Lib 
            if (instance == null) 
                instance = new Lib(new SingletonBlocker());
            
            return instance;
        
        public function Lib(p_key:SingletonBlocker):void 
            // this shouldn't be necessary unless they fake out the compiler:
            if (p_key == null) 
                throw new Error("Error: Instantiation failed: Use Singleton.getInstance() instead of new.");
            
        

        /*
        The actual embedding 
        */
        [Embed(source="assets/images/someImage.png")]
        private var ImageClass:Class;
        private var _imageClass:Bitmap = new ImageClass() as Bitmap;

        [Embed(source="assets/images/someOtherImage.png")]
        private var OtherImageClass:Class;
        private var _otherImageClass:Bitmap = new ImageClass() as Bitmap;

        public function get imgClass():Bitmap
            return _imageClass;
        
        public function get imgClassData():BitmapData
            return _imageClass.BitmapData;
        

        public function get otherImageClass():Bitmap
            return _otherImageClass;
        
        public function get otherImageClassData():BitmapData
            return _otherImageClass.BitmapData;
        
    

internal class SingletonBlocker 

【讨论】:

【参考方案10】:

[嵌入 (source="/assets/images/123.png" )] public static const className:Class;

【讨论】:

【参考方案11】:

我刚刚看了这个关于 Starling 框架的精彩教程: http://www.hsharma.com/tutorials/starting-with-starling-ep-3-sprite-sheets/

听起来 spritesheets 正是您正在寻找的: 您将所有单独的纹理捆绑到一个名为 spritesheet 的大纹理中,并创建一个 xml 文件,其中包含纹理在 spritesheet 中的位置信息。为此,您可以使用此工具: http://www.codeandweb.com/texturepacker

我不确定您是否可以将其用于商业项目,而且您所说的纹理数量听起来不像您只是出于爱好,因此您可能需要检查许可证。还有一个专业版。

Texturepacker 创建两个文件:spritesheet.png 和 spritesheet.xml。您只需将它们复制到您的项目中。 然后将此代码添加到您的一个类中。

    private static var gameTextureAtlas:TextureAtlas;

    [Embed(source="../media/graphics/mySpriteSheet.png")]
    public static const AtlasTextureGame:Class;

    [Embed(source="../media/graphics/mySpritesheet.xml", mimeType="application/octet-stream")]
    public static const AtlasXmlGame:Class;

    public static function getAtlas():TextureAtlas
    
        if(gameTextureAtlas==null)
        
            var texture:Texture=getTexture("AtlasTextureGame");
            var xml:XML=XML(new AtlasXmlGame());
            gameTextureAtlas=new TextureAtlas(texture,xml);
        
        return gameTextureAtlas;
    

现在您可以通过调用访问 spritesheet 的所有纹理

YourClass.getAtlas().getTexture("name");

简直太棒了。当您使用 texturepacker 时,您捆绑到 spritesheet 中的每个精灵的文件名都将成为它的纹理名。

这可能为时已晚,无法帮助您,但我希望未来的访问者可以从这个优雅的解决方案中受益。

我想强调一下,这个答案基本上是 sharma 教程的摘录。我什至可以随意复制他在截屏视频中使用的代码。所有的功劳都归于他

【讨论】:

【参考方案12】:

好主意,lhk

这是一个不错的解决方案,例如带有 vtf 和 vmt 的 Source-Engine vtf = 图像 vmt = 脚本(如 xml 或 javascript

很好,我想推荐 TexturePacker、TexturePath 或 TextureTarget:P

谢谢你的提示。

例如: mytexture.js:

xml 或 javascript:

function mytexture() basedir = "/assets/mytexture.png", normalmap = "/assets/mytexture_bump.png", normalcube ) [ 1, 1, 1 ] ;

我不认为是因为默认纹理在 mytexture.png 不存在的地方出现错误,而不是再次发生 :)

[Embed(source=".​​./assets/editors/error_texture.png")] 公共静态 常量 ERROR_TEX:类; ...

我怎么知道,因为 Actionscript 3 应该像 jsBirdge 或 ExternalInterface.call() 那样“读取”javascript;

有可能吗?

【讨论】:

以上是关于如何以正确的方式在 Actionscript 3 / Flex 3 中嵌入图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 actionscript 3 中检查 mm/dd/yyyy 的正确自定义输入?

Actionscript 3如何一次移动多个对象而没有延迟

如何以编程方式将 ActionScript CuePoints 注入 FLV 文件

ActionScript / Flash - 以编程方式位图填充 IDE 绘制的矢量?

如何使用 Actionscript 3、Flex 4 SDK 和 FlashDevelop 从 .fla 文件访问数据?

ActionScript 3.0 随机化数组、显示数字并拼接该数字