Howto embed images in Actionscript 3 / Flex 3 the

2019-01-17 16:55发布

问题:

I'm creating a game where a lot of images are being used in Actionscript / Flex 3 (Flash). Now that I've reached the designer stage, I have to work out a structural way of using embedded images (which have to be manipulated with rotation, color, etc.).

Unfortunately, after investigating a bit, it looks like you have to manually embed images before you can use them. I currently have it setup like this:

Resource.as class file:

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

So, just for one ship I so for have to:

Put the image in the correct folder with the correct name Name it in the same way in the Resource.as file Create the constant with the same name in the Resource.as file

Even though this should all be possible by simply putting the file in a specified folder.

To make things even worse, I still have to call it using:

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

There must be better ways to handle resources when creating very huge applications? Imagine I need thousands of images, this system simply wouldn't fit.

回答1:

instead of

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

Use

myImage.source = Resource.SHIPS_1;

The embedding is correct. :D the way you use it is wrong :)

Adrian



回答2:

If you need to handle a large number of resources you can follow these 3 steps:

  1. Place them in an uncompressed zip archive

  2. Embed the zip file as binary data:

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

  3. Access the resources using FZip

If you choose a different method that involves loading external files be aware that some flash game websites require the games they host to be contained within a single swf file.



回答3:

This is really what Flash CS4 is for. Your way seems fine to me though - although I wouldn't use all caps for a class name even if it is a constant. Just put your head down and get copy-pasting!

Alternatively you could load the files at runtime.



回答4:

This is old but since I stumbled across it searching for something different I'll write here for future generations : )

I use a different approach. I create a swf movie with flash professional and import all graphics in it and then mark them all for "Export for ActionScript". Compile the swf and in your main project embed only the swf and access all the graphics through it...

I find this approach much more organized. Why write the whole resources class when you can make it by importing files right? ;)



回答5:

I just watched this great tutorial on the Starling framework: http://www.hsharma.com/tutorials/starting-with-starling-ep-3-sprite-sheets/

It sounds like spritesheets are exactly what you're looking for: You bundle all your individual textures into one big texture that is called spritesheet and create an xml file that contains information where the textures are within the spritesheet. In order to do that you can use this tool: http://www.codeandweb.com/texturepacker

I'm not sure if you can use it for commercial projects and the amount of textures you're speaking of doesn't sound like you're doing this just as a hobby, so you might want to check the license. There's a pro version available, too.

Texturepacker creates two files: spritesheet.png and spritesheet.xml. You just copy them into your project. Then you add this code to one of your classes.

    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;
    }

Now you can access all the textures of the spritesheet by calling

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

It's simply awesome. When you're using texturepacker the filename of each of the sprites you bundled into the spritesheet becomes its texturename.

This is probably too late to help you, but I hope that future visitors can profit from this elegant solution.

I would like to emphasize that this answer is basically an excerpt from sharma's tutorial. I even felt free to reproduce the code he used in his screencast. All the credit goes to him



回答6:

It depends how big your individual images are but you could put them all in one image like a spritesheet. If you want to draw a particular ship use the correct xy offset in the image for that ship and use copyPixels to draw it to your bitmap.



回答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:

I like to do my Library classes like this.

I took GSkinners code for the singleton: 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:

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



回答11:

Good idea, lhk

That is nice solution like Source-Engine with vtf and vmt vtf = image vmt = script ( like xml or javascript )

Good i would like to suggest for TexturePacker, TexturePath or TextureTarget :P

Thanky ou for tip.

For example: mytexture.js:

xml or javascript:

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

I don't think because default texture gets error somewhere mytexture.png doesn't exists than it happens again :)

[Embed(source="../assets/editors/error_texture.png")] public static const ERROR_TEX:Class; ...

How do i know because Actionscript 3 should "read" to javascript like jsBirdge or ExternalInterface.call();

Is it possible?



回答12:

much better approach http://itfailed.blogspot.com/2011/02/howt-o-embed-images-in-actionscript-3.html