A Flash Developer Resource Site

Page 2 of 2 FirstFirst 12
Results 21 to 36 of 36

Thread: Optimizing Particles in AS3

  1. #21
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    ah, I see. managed to get pooling up for the arrows in Invasion... not convinced that I've gained any framerate (maybe a tiny bit), but it definitely no longer judders every few seconds from the GC.

    http://www.birchlabs.co.uk/Invasion5Pooled.swf
    http://www.birchlabs.co.uk/Invasion5NoPool.swf

    (also, fun result from when I forgot to reinstanstiate gravity: http://www.birchlabs.co.uk/Invasion5Fun.swf)

    Can you explain this whole BitmapData.lock() and unlock() thing to me? it sounds like it's something I should be using.
    http://www.birchlabs.co.uk/
    You know you want to.

  2. #22
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    Oh, I assumed you would be using it.

    Basically locking the bitmap stops it forcing a redraw, so you lock(), blit all your bobs, then unlock();

    unlock() also takes a rectangle as a param, so you can use that for dirty rectangle handling on the main canvas.

    Squize.

  3. #23
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Just implemented that. Not sure if it makes a difference... possibly it does? But is the assumption here that Flash will try to render the bitmap halfway through the frame (or every time we run a copyPixels())? and what does 'render' mean 'draw to screen'?
    http://www.birchlabs.co.uk/
    You know you want to.

  4. #24
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Thank you Squize!
    That's an excellent blog. It's great information which covers a the things I've been puzzling over the last few days.
    I will definitely look into pooling, I didn't realise how efficient it was. Now that I'm working on a project that's pushing around a gazillion particles, this stuff is becoming important.

    I like your practical take on benchmarking too (from your blog).. That was always my feeling... but I thought I was just being lazy "A lot faster" is good enough for me!

    Cool, I will try that copyPixel clear screen trick.. it's blindingly simple, I see now!

  5. #25
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    V, in terms of locking a bitmap it means rendering to the bitmapData object, rather than rendering to the screen.

    You're not going to get a huge increase in performance, same as pooling, but when you're dealing with lots and lots of bobs then these little things make a difference ( Like marking the class as Final ).
    If you're tracking dirty rectangles though you can reduce the number of pixels which need plotting which helps more ( via unlock(rect); ).

    No worries dandylion, glad it was some help. I've got some ideas on how to improve the blitter engine for using on the iPhone via CS5, but times against me atm, so it's on the back burner for now.

    Squize.

  6. #26
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Right. 'Dirty rectangles' refers to something related to damage mapping, I assume?

    And what's this about marking a class as Final?
    http://www.birchlabs.co.uk/
    You know you want to.

  7. #27
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    Yeah it's damage mapping.

    If you know the largest rectangle which needs updating then you can just unlock() that sized area.

    As to final ( Sorry I shouldn't have capped the F ),

    public final class myClass{

    }

    Gives a minor speed increase as it stops the class being dynamic. You can also use it on methods too, but I've got to be honest I've never felt the need to push things that far.
    I mainly just use it on particle classes, where I'll be running lots of instances.

    Squize.

  8. #28
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    I thought 'static' was to make something non-dynamic?
    http://www.birchlabs.co.uk/
    You know you want to.

  9. #29
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Quote Originally Posted by VENGEANCE MX View Post
    I thought 'static' was to make something non-dynamic?
    "final" means that the class can't be extended.

    It means you can't do this:

    public function AnyClass extends...

    .. it also prevents you from overriding any of the class's methods.

    "static" means that any of the class's properties belong just to that class, not its instances.

    To be able to add properties dynamically you have to declare a class as "dynamic".

    The MovieClip and Object class are dynamic, so you can add properties/variables to instances of those classes on a whim, whenever you need to. This is convenient because you don't have to build a whole class to support those new properties.

  10. #30
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,378
    Quote Originally Posted by VENGEANCE MX View Post
    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.
    Someone correct me if I'm wrong, but this is based on AS2 theories. In AS3, even if you add two objects at depth 1 and 3:
    Code:
    stage.addChildAt(mc1, 1);
    stage.addChildAt(mc2, 3);
    mc2 still falls down to a depth of 2 preventing you from creating "holes" in the stack order. Presents a bit of headache when trying to simply swap depths on an isometric engine, for instance (at least it did for me... it was a serious pain in the ass!).

    Quote Originally Posted by dandylion13
    The MovieClip and Object class are dynamic, so you can add properties/variables to instances of those classes on a whim, whenever you need to. This is convenient because you don't have to build a whole class to support those new properties.
    So to say this is to imply that -any- object can be turned into a dynamic object capable of taking on new members?

    Code:
    var s:Sprite = new Sprite();
    s.myVar = "Error"; // error here, null reference if memory serves
    
    dynamic var s:Sprite = new Sprite();
    s.myVar = "Success"; // this works?
    Quote Originally Posted by Squize View Post
    Yeah it's damage mapping.

    If you know the largest rectangle which needs updating then you can just unlock() that sized area.
    Don't suppose you can elaborate on this a bit more? Maybe a simple example fla?

    Quote Originally Posted by Squize View Post
    As to final ( Sorry I shouldn't have capped the F ),

    public final class myClass{

    }

    Gives a minor speed increase as it stops the class being dynamic. You can also use it on methods too, but I've got to be honest I've never felt the need to push things that far.
    I mainly just use it on particle classes, where I'll be running lots of instances.

    Squize.
    But if you wanted optimal performance you'd want to set any classes to final that you were either creating instances of or you didn't want to get over-ridden by the parent classes methods?
    Last edited by ImprisonedPride; 03-09-2010 at 08:13 AM.
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  11. #31
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Quote Originally Posted by ImprisonedPride View Post
    So to say this is to imply that -any- object can be turned into a dynamic object capable of taking on new members?

    Code:
    var s:Sprite = new Sprite();
    s.myVar = "Error"; // error here, null reference if memory serves
    
    dynamic var s:Sprite = new Sprite();
    s.myVar = "Success"; // this works?
    I think you can just declare a class as dynamic, not its instances. (Someone please correct me if I'm wrong!) Like this:

    public dynamic AnyClass...

    That means the code above won't work for Sprites, because the Sprite class is not dynamic. However, you could create a dynamic class that extends the Sprite class so that you could add properties to instances of that new class.

  12. #32
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    How I handle depths is via my PlayField class. That's just a list of bobs in that particular playfield. If I need to swap depths then I just alter the order of the list.

    The Canvas class loops through each playField ( In order, so these can be sorted too ), which then loop through each bob.
    It's pretty much how Flash does it anyway.

    "Don't suppose you can elaborate on this a bit more?"

    In pretend code

    *Update sprites position
    *Is the sprites x< the current left hand side of our rectangle ?
    * Yes, so make the left hand side of our rectangle this x value
    *Do the same for all the remaining sides of the sprite

    "But if you wanted optimal performance you'd want to set any classes to final that you were either creating instances of or you didn't want to get over-ridden by the parent classes methods?"

    I guess so yeah, although for classes which only have one instance it's neither here nor there really, whereas if you've got a 100 pooled instances of your particle class then it's a bit more worth while ( Although nothing major, none of these tips are, it's just when you're doing something really intensive that it makes a difference, like a plasma effect or a voxel engine like the one I did, where the sheer number of things running every little helps ).

    Squize.

  13. #33
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    Hi!

    I just ran some tests of my own and clearing the stage with fillRect runs a few frames faster for me than using copyPixels.

    But this doesn't mean it always will.. it's worth trying both ways, context might make all the difference.

  14. #34
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    Has anyone tried adding clipping to their engines yet ?

    Say the bob is half on/off the screen, is it worth running a test for that and reducing the size of the copyPixels rect rather than leaving Flash to do it ?

    Just wondering if it's worth while.

    Squize.

  15. #35
    Senior Member
    Join Date
    Oct 2009
    Posts
    117
    I just discovered this article on basic blitting that was published by Adobe a few weeks ago. It might help someone new to this:

    http://www.adobe.com/devnet/flash/ar...itting_mc.html

  16. #36
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Not gonna run any tests, but here's my two cents:

    It's probably not worth implementing clipping for small objects; let's say you have 5,000 small objects on-stage, chances are very few of them will only be partially on-screen. Let's say 100 are half off-stage... even if we save some time drawing those, we probably had to ask the other 4,900 a pointless question. I can only imagine that being slower.

    However, if we're working with big sprites (which by definition are more likely to be half on-screen), like if we're using a copyPixels() engine to draw parallax and background trees and stuff. Then I can see there being a point in checking.

    For small objects, it's probably still worth running a check "should I draw it at all", but not running "should I draw it partially"; if your objects could really go anywhere, and have a reason not to get deleted when they leave the stage boundaries, then I can see it being worth running that coordinate check if it's likely to occur.
    http://www.birchlabs.co.uk/
    You know you want to.

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