Sign in to follow this  
Xlander

[web] Correct way to allocate bitmap images in Flash?

Recommended Posts

Xlander    175
I am making a Flash game using FlashDevelop. While proframming it I noticed it was using a large amount of memory and it slowly rises. This seems to be quite large amount of memory for a fairly simple game. In my game I have 4 large sprite objects that contatin 625 sprites as children. At load time I create the 4 large sprites and then create all the 625 children. Each child sprite has 1 bitmap image added as a child to it. They all use the same bitmap image of a 20x20 pixel square. Each of these child sprites are slowly added to it's parent overtime as they need to become visible. Thus I have few questions. Is Flash able to work out that the bitmap image used by all the 4 * 625 children sprites are the same and does not load it into memory 2500 times? Is there a way to tell what is using up all the memory and profiler in more detail other than a straight total used value? Why would the memory usage be slowly going up? I have allocated all objects at load time. I can provide code samples later if needed. Any help would be great! Thanks, Xlander

Share this post


Link to post
Share on other sites
Tesseract    285
Are these tiles? And are all of the tiles the same? If so, you can draw a single tile onto another bitmap repeatedly, instead of having the same thing in memory almost 2000 times.

Actually, if you could give us a more detailed description of what the tiles look like and what you are doing with them, this would be an easier questions to answer.

I am kind of struggling with similar issues with a tile-based game engine I am working on

Share this post


Link to post
Share on other sites
Xlander    175
They are sprites. They can all move about independent of each other.
They all just happen to use the same bitmap as every thing in my game is a square, just of differing colors.

Share this post


Link to post
Share on other sites
esrix    184
You say that they use the same image. Do they all use the same image file loaded 625 x 4 times, or do you load the image once as a BitmapData object and then simply have 625 x 4 Bitmap objects point to the same BitmapData?

Share this post


Link to post
Share on other sites
Xlander    175
@esrix
I am unsure how the bitmap stuff works in Actionscript.

Here is what my Square Sprites constructor looks like it may help explain what I am doing.


public function Square()
{
state = SquareState.DEAD;

bitmap = new Resources.SquareBitmap();
bitmap.x = -bitmap.width / 2;
bitmap.y = -bitmap.height / 2;
addChild(bitmap);

var glowFilter:GlowFilter;
glowFilter = new GlowFilter(0xFF0000, 1, bitmap.width/4, bitmap.height/4, 2, 1, false, false);

filters = [glowFilter];
}


Share this post


Link to post
Share on other sites
esrix    184
The Bitmap object and the BitmapData object are two different classes. The Bitmap is what is drawn to the stage in Flash, but the BitmapData object holds all of the pixel data for a Bitmap. In order to make a Bitmap object, you have to have a BitmapData object. Take a look at the Bitmap constructor:


Bitmap(bitmapData:BitmapData = null, pixelSnapping:String = "auto", smoothing:Boolean = false)



If all of your Bitmaps are using the same image and you don't plan on manipulating the pixel data on a per-bitmap basis, you can increase performance by loading that image once as a single BitmapData object and have several bitmaps reference the same singular BitmapData.


//custom BitmapData loader
var bmd:BitmapData = new myBitmapDataLoader();

//Bitmap objects
var bitmap1:Bitmap = new Bitmap( bmd );
var bitmap2:Bitmap = new Bitmap( bmd );
...
var bitmap53:Bitmap = new Bitmap( bmd );



If you are declaring a new BitmapData object with each SquareBitmap instance in your code, you may be able to cut down on the memory consumption if you make the BitmapData a static variable so that it only gets loaded once. That way, all the SquareBitmaps will reference the same data. As long as all of your bitmaps are consistent, you shouldn't have too many problems. It's more efficient to load the image data once and use it over and over again instead of loading it 625 x 4 times.

Another way to potentially increase performance is to load your image once into one BitmapData object (we'll call it "bmd_img") and then have each of your 4 large sprites ("sprite1", "sprite2", "sprite3", "sprite4") have their own Bitmaps ("bm1", "bm2", "bm3", "bm4") with their own unique BitmapData ("bmd1", "bmd2"... you get the idea ^_^ ). Then, whenever you want to draw your square onto any of the sprites, grab the appropriate BitmapData and copy the pixels from bmd_img.

This is because it's usually quicker for Flash to draw objects (sometimes even non-bitmap objects) to the pixels in a Bitmap and then draw that Bitmap to the screen.


//Create your bitmap data with the image
var bmd_img:BitmapData = new myBitmapDataLoader();

//Create your bitmap data for the bitmap
//This assumes that you have an 800 x 600 movie clip with the
//sprites stacked 2 x 2
//Adjust the width and hight to meet your needs
var bmd1:BitmapData = new BitmapData(400, 300);
var bmd2:BitmapData = new BitmapData(400, 300);
var bmd3:BitmapData = new BitmapData(400, 300);
var bmd4:BitmapData = new BitmapData(400, 300);

//Create the bitmaps
var bm1:Bitmap = new Bitmap(bmd1);
var bm2:Bitmap = new Bitmap(bmd2);
var bm3:Bitmap = new Bitmap(bmd3);
var bm4:Bitmap = new Bitmap(bmd4);

//Create your sprites
var sprite1:Sprite = new Sprite();
var sprite2:Sprite = new Sprite();
var sprite3:Sprite = new Sprite();
var sprite4:Sprite = new Sprite();

//Position your sprites
sprite1.x = 0;
sprite1.y = 0;
sprite2.x = 400;
sprite2.y = 0;
sprite3.x = 0;
sprite3.y = 300;
sprite4.x = 400;
sprite4.y = 300;

//Add the appropriate children
sprite1.addChild(bm1);
sprite2.addChild(bm2);
sprite3.addChild(bm3);
sprite4.addChild(bm4);

...

//Now to start drawing!
//Define the area you want to copy from bmd_img
//We want it to copy the pixel data from the upper left
//of the image and blit to an area that is 64 x 64 pixels
var rect:Rectangle = new Rectangle(0, 0, 64, 64);

//Create a point to show the X and Y coordinates you want to render to
var pt:Point = new Point(10, 10);

//Draw!
bm1.bitmapData.copyPixels(bmd_img, rect, pt);



Also, whenever you are completely finished with BitmapData objects and you want to free up memory, be sure to call the dispose() function.


bmd1.dispose();



You can get the info for Bitmaps here and the info for BitmapData here.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this