|
-
you won't be able to "apply" a type to an already created instance of a different (or ancestor) type.
In terms of pooling implementation, you can quite simply create a desired number of every type you'll be using in your application. You could map Class to a pool of that type in a Dictionary object to constrain your pool access to a single method. Offer another method to return an object you're done with to the pool. The pooling management class can identify the Class dynamically and return it to the appropriate pool.
-
The chances are that its unlikely that object pooling is really the best solution.
Except in extreme cases, object creation and collection is not going to be a massive performance bottleneck. Object pooling is moderately complex for what you get, and has the risk of the overhead being greater than simply creating objects on demand. Not only that, but the many potential types of objects that need to be pooled sticks a lot of excess complexity in there.
I assume that your goal is performance in using large quantities of objects.
There are alternatives to object pooling that may be more appropriate such as the flyweight pattern (http://en.wikipedia.org/wiki/Flyweight_pattern).
It is far faster to manage creation and deletion of coordinates (Numbers/ints) than complete objects, and opens the possibility for more optimization on top of that (Manually inlining method calls from the flyweight class).
Pools are far more suited to things like threads where creation may take orders of magnitude more time than the calculations being done. The example provided in the flyweight pattern (Characters being displayed in word processors) is really far more appropriate for bullets, there is many of them, they vary only in coordinates, it is impractical to have each one be an object in itself...
Last edited by 691175002; 05-20-2008 at 04:58 PM.
The greatest pleasure in life is doing what people say you cannot do.
- Walter Bagehot
The height of cleverness is to be able to conceal it.
- Francois de La Rochefoucauld
-
 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.
-
Script kiddie
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(0, 1); } 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_FRAME, EnterFrame); function EnterFrame(event:Event):void { createTroop(); tI = troops.numChildren; while (tI--) { t = 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,0, WIDTH, HEIGHT); draw(); } public function draw():void { rect = scrollRect; rect.x = frame * WIDTH; scrollRect = rect; } public function init():void { y = Math.floor(245-Math.random()*12) x = -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,0, WIDTH, HEIGHT); } public function eF():void { if (x <= 300) { x-=-speed; } else if (x>300) { x -= 21 ; y -= -10; objMode = "Die"; frame = 0; FRAMES = 19; WIDTH = 54; HEIGHT = 44; scrollRect = new Rectangle(0, 121, WIDTH, HEIGHT); } 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.
-
Hype over content...
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|