This blog has moved to a new location! http://iqandreas.github.com/

Thursday, February 11, 2010

Optimize AS3 for speed - Bitmap filters reply

I originally posted this as a reply to a comment on MichaelJamesWilliam's blog entry "Learn how to Optimize your AS3 Code". The spam catcher kept refusing to submit it (I'm guessing because of all the links), so I reposted the reply here.



kustrle February 11, 2010 at 7:51 am
I was sure pixel perfect collision detection already first check if two objects are overlaping. Is there any way of reducing lag that comes from glow, blue, etc without photoshop? Since we lose flexibility there too. If we want to change glow to other color later it will be much harder. Can we tell flash to convert those objects to some kind of bitmap picture and then forgot about all filters? Great tutorial!


@kustrle - Yes, it is possible to save the "filtered" version of DisplayObjects as BitmapData and use that the entire time.


If all your enemies of a certain look the same, you can apply all the filters before the game starts, however, if each enemy is different in it's own way, you can apply the filters once they are needed.

This is a little bit of "quasi-code" of how to add a glow filter to an enemy if it is enraged. Flash only needs to calculate the glow once, and since I'm also no longer using vector graphics, it speeds up the rendering time enormously. There are better ways, but this describes it simply.

  1. if (enemy.enraged)
  2. {
  3.    //enemyNormal_bmp is here the currently displayed Bitmap of the enemy
  4.    enemy.removeChild( enemyNormal_bmp );
  5.  
  6.    var enraged_bitmapData:BitmapData = makeEnraged(enemyNormal_bmp.bitmapData);
  7.    var enemyEnraged_bmp = new Bitmap(enraged_bitmapData);
  8.    enemy.addChild( enemyEnraged_bmp );
  9. }
  10.  
  11. function makeEnraged( normalBitmapData:BitmapData ):BitmapData
  12. {
  13.    //Of course, this code right now is more optimized for readability than speed. :P
  14.    var srcBmd:BitmapData = normalBitmapData.clone();
  15.    var srcRect:Rectangle = srcBmd.rect;
  16.    var filter:BitmapFilter = new GlowFilter();
  17.  
  18.    //Since adding glow makes the image a little larger, figure out the new size
  19.    var targetRect:Rectangle = srcBmd.generateFilterRect(srcRect, filter);
  20.  
  21.    //Create the new bitmap data that will be returned
  22.    var bmd:BitmapData = new BitmapData(targetRect.width, targetRect.height, true);
  23.    bmd.applyFilter(srcBmd, srcRect, new Point(-targetRect.x, -targetRect.y), filter);
  24.  
  25.    return bmd;
  26. }

In fact, there is an entire field of options and projects where people use BitmapData to increase speed and allow more items on the screen, as rendering too many vectors tends to be slow for the Flash Player.

Here are a few links that might point you in the right direction.
http://mikegrundvig.blogspot.com/2007/05/copypixel-is-faster-then-sprites.html
http://board.flashkit.com/board/showthread.php?t=732354
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d65.html

I plan on releasing a simple "tile game" framework that uses only drawn bitmaps, so keep an eye on my blog for future updates.
http://iqandreas.blogspot.com/

2 comments:

  1. Hey, cheers for putting in so much effort :)

    ReplyDelete
  2. @MichaelJWilliams
    It was 1AM and I was ridiculously bored. ;)

    I guess I could have elaborated a bit more, but I at least got the basics touched on.

    Nice blitting tutorial by the way. I'm definitely bookmarking it as the question comes up alot on the kirupa.com forums. Now I finally have a good link to paste into posts, and no longer have to procrastinate writing out my own tutorial on blitting.

    ReplyDelete