A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 36

Thread: Optimizing Particles in AS3

  1. #1
    The New Guy
    Join Date
    Nov 2007
    Posts
    67

    Optimizing Particles in AS3

    Hi Guys

    I've just moved this question from the AS3 board to here (chances are someone here may have an answer)
    I'm in the middle of developing a shooter which has a particle class that is spawning a lot of movieclip instances. Is there any way to optimize particles in AS3 to improve speed/performance? I've noticed things get a little sluggish when there's 800+ instances.

    I tried using the "cache as bitmap" option but it seems to affect the motion. For some reason it makes it jerky. I can't figure that one out.

    I have managed to increase the speed by between 5 - 9 FPS by replacing the vector particles with photoshopped bitmap particles, but I could still do with a few tips on giving it that extra boost.

    The particles are just blobs and don't change shape, form or size once they are "born". A pre-determined number is spawned and they just move constantly and recycle themselves once they leave the screen, thats all.

    Any ideas on optimization would be really helpful.

    Thanks guys!

  2. #2
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    maybe you shouldn´t work with multiple instances but instead attach bitmap slices to a total bitmap- that way you dont waste resources upon massive instainces but instead just on arrays containing the coordinates + the complete bitmap shape to be rendered.

  3. #3
    Professional Flash Developer
    Join Date
    Aug 2007
    Location
    California
    Posts
    105
    renderhjs's method is a good one. If you are using the particles for explosions, you can pre-render them and cache the output as arrays of BitmapData objects. All of the particles for each explosion (or other effect) now become one array of bitmaps. You then render each frame of the animation like renderhjs says above. That way you don't have to calculate anything on the fly. The only down side is having to pre-render them in your game initialization.

    A more advanced version is to render the first one on the fly, and cache its frames during that first render. The next one and every other one is built like above, from the now pre-cached array of bitmapdata frames.

    I have some methods that might help you in an article(s) on my site:

    http://www.8bitrocket.com/newsdispla...?newspage=7496

    http://www.8bitrocket.com/newsdispla...?newspage=2594

    The second one applies to AS2, but the exact same idea can be used in As3

    -Jeff

  4. #4
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    Each particle only needs 4 properties: x, y, xmov, ymov. You dont need MovieClip class for this, instead extend Point class for example or basic Object. Then use 1 single bitmap and copyPixels to draw it on screen at position of each particle.

    Also consider using time based movement instead of fixed fram based value, this will make them move at same speed even when fps drops so fps drop becomes less visible.

    It is probably not even needed to move them all at each frame, split them in half and move first half in one frame and other half in next frame.

  5. #5
    The New Guy
    Join Date
    Nov 2007
    Posts
    67
    Ok thanks for all the replies guys.
    I forgot to mention that its a heavy snow scene, which I'm trying to replicate.
    Theres several layers of snowfall with each flake falling at a different speed. Each flake also has a different transparency.

    As soon as one flake goes off the screen, its moved back to the top again (rather than killing it)

    I think the idea of drawing lots of flakes to a bitmap and then drawing that to the stage every timer-tick would work well, but I'm not sure how I'd go about doing that (I'm still a beginner)

    Do you have any easy-to-understand sample code I could look at which demonstrates this or something similar?

    I appreciate the help! Thanks!

  6. #6
    Professional Flash Developer
    Join Date
    Aug 2007
    Location
    California
    Posts
    105
    I did a tutorial last year on the subject. It details more than just blitting. It explains how to create a sprite sheet, use a tile editor to create a level, read in the XML for the level into a basic a tiled based engine, and blit all of the tiles to a single bitmap data. It is here:

    http://www.8bitrocket.com/newsdispla...?newspage=6077

    -Jeff

  7. #7
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Quote Originally Posted by tonypa View Post
    use 1 single bitmap and copyPixels to draw it on screen at position of each particle.
    Could anyone point me to a practical example of this in action?

    Thanks!

  8. #8
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    I believe Dave did it that way with this,

    http://www.kongregate.com/games/JGOware/retroshoot360

    If he didn't then he's got some magic skills to get that much stuff running so quickly.

    Squize.

  9. #9
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    http://www.birchlabs.co.uk/
    You know you want to.

  10. #10
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Hi,

    I have specific question about this technique: how can one modify the alpha of individual tiles or particles?

  11. #11
    Senior Member
    Join Date
    Sep 2006
    Posts
    132
    Yes, copying sprites and their positions to one bitmap data, clearing bitmap data, and re-drawing to it.
    If you still get a slow down, you could optimise by slowing down how fast the bitmap data re-draws until its as slow as it can go without looking jumpy.
    I will be willing to test if you show a demo on here sometime. I'll mention my pc specs. Infact, might put my pc specs in my signature.
    May 2009 - Working on Thorenzitha RPG - episode 7

  12. #12
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    if you want your bobs to be able to fade out individually, you're gonna have to put faded sprites of them into the spritesheet. for example:



    these have been pre-rendered to be able to rotate and fade out.
    http://www.birchlabs.co.uk/
    You know you want to.

  13. #13
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    If it's any help, I'm still working on my blitter engine and I've found it quicker to use copyPixel to clean the canvas ( ie copy a background image to it then plot on that ) than fillRect.

    Squize.

  14. #14
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    woah. I'll try that myself. btw, what's your opinion on using object pooling for bobs? the objects being instantiated aren't massive DisplayObject ordeals, they're a tiny class with coordinate, angle and frame information and not much else, so they're pretty quick to make and delete.
    http://www.birchlabs.co.uk/
    You know you want to.

  15. #15
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Thank you for feedback, everyone!

    I have a few working tests running and, wow, I'm impressed! I haven't done any benchmarking but this feels 4-5 times faster than moving Sprites around. I'm loving it!

    Vengeanace, Thank you for your feedback regarding alpha/fading!
    I spent quite a bit of time trying to figure that out, but don't know the Bitmap/BitmapData classes well enough to know if there was something I was missing. I thought I could use BlendMode.APLHA or mergeAlpha in some obscure way, but I couldn't get anything working. So, that explains - I can't!

    I've got it then: just pre-render alpha and rotation in the tile sheet.. makes sense for performance reasons too.

    Regarding clearing the canvas.. this is the code I'm using:

    _bitmapData.fillRect(_bitmapData.rect, 0);

    Squize, how do you clear the canvas with copyPixels... ?

    Hey Vengeance, please forgive my ignorance, but what are "bobs" and what is "pooling"?

    Thanks everyone!
    Last edited by dandylion13; 03-08-2010 at 04:46 AM.

  16. #16
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Ah, when you're blitting sprites around a screen, the sprites you are plotting would be your 'bobs' (http://en.wikipedia.org/wiki/Blitter_object).

    Object-pooling is a way to avoid the slowdown associated with creating and deleting objects. For example, if I want to make a bunch of sprites fly around, I can create several thousand sprites when I'm setting up the game (so take a few seconds hit on performance while you make all of those), and then just use one of those whenever I need a new sprite. You can recycle them, so if your projectile gets used up (like a shell explodes), you can throw the sprite object back into the pool to be used again.

    The problems with it are that you get that bit of slowdown when you're creating the pool (which isn't a big problem, as that only happens once), you need to allocate a pool bigger than you'll actually need (which means your memory usage will always be higher than if you hadn't pooled), it adds a little bit more complexity when you're trying to create objects (which is a big issue if your code is as messy as mine), and it might be that creating a small object with few variables in it would be faster than going through the process of looking up and recycling one from the pool (and this is the bit I want to know... but I guess it wouldn't be a big deal for me to just check myself).
    http://www.birchlabs.co.uk/
    You know you want to.

  17. #17
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Thank for that excellent explanation, Veng!!

    Ah, so it looks like pooling is much like a look-up table, which I use all the time to pre-calculate vectors.

    "Bobs"... got it! That was a nice trip back to my Amiga days

    I do have one other question:

    The last bob drawn appears on top of the others. What's the best way to manage stacking order in this system?

    (Thanks for your patience everyone, this is a new topic for me! )

  18. #18
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Maybe a linked list? So:

    objectsArray = [someObject0, someObject1, someObject2];
    depthsArray = [1, 3, 2];

    Indices of each array correspond to each other, so someObject0 is considered to be at depth 1, someObject1 is considered to be at depth 3, and someObject2 is considered to be at depth 2.

    So that's a way of organizing and keeping track of what depth to put them at. As for how to actually draw them at the depth specified... since you'll be using copyPixels() to draw them in, you need to draw them in the order you want them. So go through depthsArray until you find the lowest number, and the array element from the depthsArray that has that number, is the same as the element of the object you currently want to draw from the objectsArray.
    http://www.birchlabs.co.uk/
    You know you want to.

  19. #19
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Thanks again Vengeance! That's a great place for me to start, I'll take a stab at it!

  20. #20
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    How my engine works is by emulating the DisplayList, so it does all the depth sorting for me.

    Hmmm, rather than re-write it,
    http://blog.gamingyourway.com/PermaL...f9fb0c74e.aspx

    V, as to pooling, yeah I always use it. It doesn't really matter about the size or complexity of the objects you're creating, by pooling you're saving having to run the constructor code every time and nothing is being flagged up for GC, so now unexpected glitches when the GC kicks in.
    Pooling takes no time to set up, just use a Vector list.

    dandylion to use copyPixels to clear the screen just set up a bitmap as your background, which can be as simple as a black rectangle the size of your screen, and copy that onto the canvas bitmap which you'd usually use fillRect on.

    Squize.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center