0
\$\begingroup\$

I am trying to animate a specific tile in my 2d Array, using blitting. The animation consists of three different 16x16 sprites in a tilesheet. Now that works perfect with the code below. BUT it's causing memory leakage. Every second the FlashPlayer is taking up +140 kb more in memory. What part of the following code could possibly cause the leak:

//The variable Rectangle finds where on the 2d array we should clear the pixels
//Fillrect follows up by setting alpha 0 at that spot before we copy in nxt Sprite
//Tiletype is a variable that holds what kind of tile the next tile in animation is
//(from tileSheet)
//drawTile() gets Sprite from tilesheet and copyPixels it into right position on canvas

        public function animateSprite():void{

                    tileGround.bitmapData.lock();

                    if(anmArray[0].tileType > 42){
                        anmArray[0].tileType = 40;
                        frameCount = 0;
                    }
                    var rect:Rectangle = new Rectangle(anmArray[0].xtile * ts, anmArray[0].ytile * ts, ts, ts);
                    tileGround.bitmapData.fillRect(rect, 0);

                    anmArray[0].tileType = 40 + frameCount;
                    drawTile(anmArray[0].tileType, anmArray[0].xtile, anmArray[0].ytile);

                    frameCount++;

                    tileGround.bitmapData.unlock();
                }



        public function drawTile(spriteType:int, xt:int, yt:int):void{

                    var tileSprite:Bitmap = getImageFromSheet(spriteType, ts);
                    var rec:Rectangle = new Rectangle(0, 0, ts, ts);
                    var pt:Point = new Point(xt * ts, yt * ts);
                    tileGround.bitmapData.copyPixels(tileSprite.bitmapData, rec, pt, null, null, true);

                }


                public function getImageFromSheet(spriteType:int, size:int):Bitmap{

                    var sheetColumns:int = tSheet.width/ts;
                    var col:int = spriteType % sheetColumns;
                    var row:int = Math.floor(spriteType/sheetColumns);
                    var rec:Rectangle = new Rectangle(col * ts, row * ts, size, size);
                    var pt:Point = new Point(0,0);

                    var correctTile:Bitmap = new Bitmap(new BitmapData(size, size, false, 0));
                    correctTile.bitmapData.copyPixels(tSheet, rec, pt, null, null, true);
                    return correctTile;

                }
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The main memory consumption is because you're allocating new memory by creating a new Bitmap in your getImageFromSheet method.

You could write your code without any of these allocations. Instead of creating new Points and Rectanlges and Bitmaps every time, you could use two private member variables for the Point and Rectangle (where you simply change properties) and perform the copyPixels method directly from your sprite-sheet to your canvas. There's no need for the intermediate copy to a Bitmap. If you still want to pass around new bitmap-data, use BitmapData directly and not a Bitmap which is only a DisplayObject wrapper so that you can add it to the flash stage (which you don't need).

How long did you monitor your memory consumption? That allocated memory should actually be released by the garbage collector... but it would of course be better if you did not allocate that memory in the first place (since it's redundant).

\$\endgroup\$
20
  • \$\begingroup\$ @bummzack Nice! I changed all the Points and the Rectangles to private class variables and changed their properties within the functions (pt.x or rec.width, etc..). Worked perfectly! But I acctually need the Bitmap to contain the BitmapData, cause some images that I fetch from the tilesheet will be added to a Movieclip on the stage (addchild(bitmap)). I tried to do the same with the Bitmap varibales and BitmapData variables, changing them to private class variable, but when I then try to change myBitmapdata.width property, it says it's "read-only". Is there any other way I could achieve this? \$\endgroup\$
    – Kid
    Commented Jun 26, 2011 at 16:01
  • \$\begingroup\$ No, you can't change the width of a BitmapData. If you're adding these Bitmaps to the stage it's normal that your memory increases. The memory should free up whenever you remove these objects from the stage though. You could optimize this by using the same BitmapData in several Bitmaps though. That way every sprite "coordinate" would only require memory once. \$\endgroup\$
    – bummzack
    Commented Jun 26, 2011 at 16:47
  • \$\begingroup\$ @bummzack, That did help a lot, to use the same BitmapData in several Bitmaps, and removing them from renewing each time. They are now only renewed once and then recycled. Although there is one BitmapData that will change size depending on the current level (2d Array size), and sadly thats the one that will consume most memory. Gave me an idea though, what if I did all of this in reverse, let's say I kept the bitmaps in their place, and instead dispose() the bitmaps and removeChild the movieclips the movieclips BEFORE I add the MC's again and add new Bitmaps? Would that be efficient? \$\endgroup\$
    – Kid
    Commented Jun 26, 2011 at 19:51
  • \$\begingroup\$ Not sure if I really understand. Another approach would be to use the scrollRect property the Bitmap to show only the desired area of the image. That way you would always use the same BitmapData (the full image) but only specify the portion to show. \$\endgroup\$
    – bummzack
    Commented Jun 26, 2011 at 20:55
  • \$\begingroup\$ @bummzack Funny enough, I am already using scrollRect. I tried your advice, I changed the BitmapData size (width/height) to a full image, 2000 * 2000 pixels, and then made it a class variable. Now the memory in the Task Manager shows 52,000 K as oppose to 16,000 K, which is bad. I think 16,000 K for a flash game is acceptable though. Based on all the suggestions you have given in this thread, about optimizing the Bitmap and BitmapData, has trimmed it down tremendously! Which is great. The memory used to show 50, 000+ K, but now using the same BitmapData instead of several, its down to 16,000. \$\endgroup\$
    – Kid
    Commented Jun 26, 2011 at 23:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .