A Flash Developer Resource Site

Results 1 to 20 of 27

Thread: Trying to design some object pooling

Hybrid View

  1. #1
    Senior Member
    Join Date
    Nov 2003
    Location
    Las Vegas
    Posts
    770
    Quote Originally Posted by 691175002
    Except in extreme cases, object creation and collection is not going to be a massive performance bottleneck.
    Try a simple loop test with sufficient iterations, do one test that creates new geom objects (rectangles, points, etc), and do another one that uses object pooling. I think you'll find that object creation with some of Flash's native classes can be a very big bottleneck.

    One special case in the originator's game is the lasers. Generally speaking, a laser will be virtually instantaneous from origin to target. Due to this, you can use a simple pooling method that only has to loop from numberDestroyed to numberCreated, rather than having to rearrange a linked list based on destruction. For bullets and missles this won't work due to some objects being destroyed out of the creation order.

  2. #2
    Script kiddie VENGEANCE MX's Avatar
    Join Date
    Jun 2004
    Location
    England
    Posts
    2,590
    Here's a trimmed-down version of one of my Invasion tests, then. Put this script on your main frame (told you it's sloppy):

    PHP Code:
    stage.scaleMode "noScale";
    stage.quality "LOW";

    var 
    infSheetBMP:infSheet = new infSheet();
    var 
    troops:Sprite = new Sprite();
    var 
    troopPool:Array = new Array();

    var 
    frameRate:int=31;
    var 
    lowest:int=frameRate;
    var 
    checkCounter:int checkRate 8;
    var 
    startTime getTimer();
    var 
    lowestResetCnt=frameRate*5;
    var 
    fps:int 31;

    var 
    tI:int 0;
    var 
    t;

    var 
    te:TextField = new TextField();
    te.text "FPS: 31\nTroops: 0";
    te.autoSize TextFieldAutoSize.LEFT;
    addChild(te);

    function 
    createTroop(tr:Number):void {
        if (
    troopPool.length>0) {
            
    myTroop troops.addChild(troopPool[0]);
            
    troopPool.splice(01);
        } else {
            var 
    myTroop:Infantry = new Infantry(this);
            var 
    infSprite:Bitmap = new Bitmap(infSheetBMP);
            
    myTroop.addChild(infSprite);
            
    troops.addChild(myTroop);
        }
        
    myTroop.init();
    }

    stage.addEventListener(Event.ENTER_FRAMEEnterFrame);
    function 
    EnterFrame(event:Event):void {
        
    createTroop();
        
        
    tI troops.numChildren;
        while (
    tI--) {
            
    troops.getChildAt(tI);
            
    t.eF();
        }
        if(--
    checkCounter==0) {
            
    fr checkRate/((getTimer() - startTime)/1000);
            
    fps int(fr*10)/10;
            if (
    fps<=lowest){
                
    powest=fps;
            } else {
                if(
    fps>frameRate){
                    
    fps=frameRate;
                }
            }
            
    startTime getTimer();
            
    checkCounter checkRate;
        }
        if (--
    lowestResetCnt==0){
            
    lowestResetCnt=frameRate;
            
    lowest=frameRate;
        }
        
    te.text "FPS: "+String(fps)+"\nMCs: "+String(troops.numChildren);

    You'll need to download and put this into your Library:



    And Export it for ActionScript with a Linkage Identifier of infSheet.

    Finally, you'll need an Infantry.as in your project folder saying this:

    PHP Code:
    package {
        
    import flash.display.Sprite;
        
    import flash.display.Bitmap;
        
    import flash.display.BitmapData;
        
    import flash.geom.Rectangle;

        public class 
    Infantry extends Sprite {
            public var 
    _root;
            public var 
    speed:int;
            public var 
    frame:int;
            public var 
    objMode:String;
            public var 
    cond:Boolean;
            public var 
    inc:int;
            
            public var 
    obj:String "Inf";
            
            public var 
    WIDTH:int 35;
            public var 
    HEIGHT:int 54;
            public var 
    FRAMES:int 17;
            
            public var 
    rect:Rectangle;
            
            public function 
    Infantry(mr:Object) {
                
    _root mr;
                
    cacheAsBitmap true;
                
    scrollRect = new Rectangle(0,0WIDTHHEIGHT);
                
    draw();
            }
            public function 
    draw():void {
                
    rect scrollRect;
                
    rect.frame WIDTH;
                
    scrollRect rect;
            }
            public function 
    init():void {
                
    Math.floor(245-Math.random()*12)
                
    = -50-Math.random()*20;
                
    frame 0;
                
    speed 3;
                
    objMode  "Walk";
                
    cond true;
                
    inc Math.round(Math.random()*5);
                
    WIDTH 35;
                
    HEIGHT 54;
                
    FRAMES 17;
                
    scrollRect = new Rectangle(0,0WIDTHHEIGHT);
            }
            public function 
    eF():void {
                if (
    <= 300) {
                    
    x-=-speed;
                } else if (
    x>300) {
                    
    -= 21 ;
                    
    -= -10;
                    
    objMode "Die";
                    
    frame 0;
                    
    FRAMES 19;
                    
    WIDTH 54;
                    
    HEIGHT 44;
                    
    scrollRect = new Rectangle(0121WIDTHHEIGHT);
                }
                
    draw();
                
    frame++;
                if (
    objMode=="Die") {
                    if (
    frame==FRAMES) {
                        
    _root.troops.removeChildAt(_root.tI);
                        
    _root.troopPool.push(this);
                    }
                } else {
                    if (
    frame==FRAMES) {
                        
    frame 0;
                    }
                }
            }
        }

    Sorry if it doesn't work; I haven't tested that, so I might've removed some unnecessary stuff. I'd compile it all for you, but Flash 9 doesn't run on my Intel Mac. As for webgeek's version... you'd need to ask him for that.

    Oh, bear in mind that while object pooling does get rid of the bottleneck of object instantiation, you can still create a far faster entity engine using copyPixels(). My non-pooling copyPixels() engine runs about 20 times faster than this. Comparison:

    Pooling sprites (FPS capped at 31, so note that this isn't a very fair benchmark):
    http://www.birchlabs.co.uk/Invasion5F9.swf
    copyPixels():
    http://www.birchlabs.co.uk/Invasion_5.html
    Last edited by VENGEANCE MX; 05-21-2008 at 12:20 PM.
    http://www.birchlabs.co.uk/
    You know you want to.

  3. #3
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    V, pooling isn't limited to sprites mate.

    I'm sure we've spoken about this before, you can still use bobs with pooling rather than just sprites.

    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