AS3 Embed images class and then get these images into another class?
Asked Answered
C

2

5

For example, right now I have a class called "Balls.as". Here I load 10 different balls-images. You know, like this:

[Embed(source = "/ball1.png")]
[Embed(source = "/ball2.png")]

The problem is that if I spawn 5 balls, these balls images gonna get embeded 5 * 5 times right? Correct me if I'm wrong! So I though, can't I have a ballimageloading class? That loads these images once, and then in Balls.as I can load whatever ball i want for the moment?

Coranto answered 27/1, 2013 at 15:57 Comment(0)
B
11

You won't need to "load" them, they are embedded. You just have to instantiate the images. It's a good idea to have one class that manage shared ressources, as such:

public class TextureAssets 
{
    [Embed(source = "../lib/ball1.png")]
    private static var Ball1:Class;

    [Embed(source = "../lib/ball2.png")]
    private static var Ball2:Class;

    public static var ball1Texture:BitmapData;
    public static var ball2Texture:BitmapData;

    public static function init():void
    {
        ball1Texture = (new Ball1() as Bitmap).bitmapData;
        ball2Texture = (new Ball2() as Bitmap).bitmapData;
    }

Then you would call TextureAssets.init() once (in the Main.as for example) and when you need the bitmapData: use new Bitmap(TextureAssets.ball1Texture)
This way your program needs uses only memory required for one bitmapData instead of having many which ends up being the same.
If you need to perform operations on a bitmapData while keeping the original you can use:

var modified:bitmapData = TextureAssets.ballTexture.clone();


Also, if you are instantiating all balls images from within one class it's a good idea to drop static access and instead initialise the bitmapDatas in the constructor, create a new TextureAssets() and call the textures through the variable
(Static field access is slower than direct (.) access : http://jacksondunstan.com/articles/1690)

Basilius answered 27/1, 2013 at 16:43 Comment(4)
I agree with static field access being slower than direct, but I think for this case, it's better to concentrate on code management and easiness than on minor performance boosts.Linderman
@Linderman : The main point is getting the bitmapData to be built once if the same image is going to be shared and stay unchanged. Your code above creates a new bitmapData object for every call to 'var mBall1:Bitmap = new Assets.BallImage1() as Bitmap;' which would lead to memory leaks if user1941346 doesn't call mBall1.bitmapData.dispose() before removing it from the display list or loosing the reference. In addition to the cost of building a new bitmapData each time, for a 100 calls there's a difference of aprox. 500 kb for a little 64x64 png, in contrast to aprox 100 kb for the above method.Basilius
Okay.. I might be wrong, but calling clone method also creates a new BitmapData object and returns it (at least, that's what the docs say). help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/…Linderman
I gave the clone example only if there's a need to "modify the bitmapData" (like color transformations or filter), to preserve the original.Basilius
L
10

The best practice is to have an Assets class which will contain static embeded images, like this:

[Embed(source="ball1.png")]
public static var BallImage1:Class;

Then all you'll have to do is declare a variable for your loaded Bitmap and use it, like so:

protected var mBall1:Bitmap = new Assets.BallImage1() as Bitmap;

This will create a Bitmap instance of your loaded image and you can then add it to the display list. Loading will happen only once per image and you'll have all your images at your fingertips, accessible from every class you have.

Linderman answered 27/1, 2013 at 16:32 Comment(1)
Thanks! I'll try to look into that later tonight!Coranto

© 2022 - 2024 — McMap. All rights reserved.