Howto embed images in Actionscript 3 / Flex 3 the right way?
Asked Answered
M

11

13

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.

Mady answered 27/6, 2009 at 20:28 Comment(1)
don't know anything about game development, but would you really need to embed thousands of images? Seems like the swf would get pretty heftyOvertime
W
6

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

Weisberg answered 27/6, 2009 at 20:36 Comment(0)
R
16

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.

Rounders answered 28/6, 2009 at 21:53 Comment(0)
W
6

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

Weisberg answered 27/6, 2009 at 20:36 Comment(0)
U
5

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.

Uncircumcised answered 27/6, 2009 at 22:33 Comment(0)
S
2

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? ;)

Shirtmaker answered 19/10, 2011 at 16:16 Comment(0)
P
2

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

Pretense answered 13/10, 2012 at 14:24 Comment(0)
C
1

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.

Chemmy answered 11/6, 2011 at 18:15 Comment(0)
S
1
package
{
    public final class Resource
    {
        [Embed (source="/assets/ships/1.gif" )]
        public static const SHIPS_1:Class;
    }
}
Shading answered 20/2, 2012 at 5:6 Comment(0)
S
0
[Embed (source="/assets/ships/1.gif" )]
    public static const SHIPS_1:Class;
Shading answered 5/3, 2012 at 12:53 Comment(0)
H
0

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 {}
Hansiain answered 29/3, 2012 at 14:49 Comment(0)
S
0

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

Shading answered 2/4, 2012 at 7:35 Comment(0)
A
0

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?

Apices answered 20/11, 2012 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.