The other day I got an email from someone who wanted to know how the “infinite” drawing in isotope3 worked. I figured this would be a excellent time both to share some code and get a post done around here.
I’m using a technique I first started to use in my game Eater of Worlds, it has since appeared in a few other things I’ve made.
Just piling hundreds of objects in a single DisplayObject causes Flash to redraw all of them each frame. Drawing vectors in Flash is pretty fast, but having to redraw them each frame is a bit unnecessary if they aren’t really changing. Enter cacheAsBitmap, this does exactly what you would expect it to. And it’s great. Until the content changes, then you have to redraw everything again. Taking both the hit of the redraw with the added punishment of creating the cache (not sure how big that is though).
In isotope3 I redraw each and every frame, negating any boost cacheAsBitmap would give.
So what I do is i create a “cache” bitmap, basically the same as flash would do automatically, but this bitmap I’m controlling.
This makes stuff a tiny bit more complicated, since you will need to explicitly tell flash what to draw to the bitmap each frame (or whenever you feel like it really). Another drawback is that if you’re using it to pile in large amounts of objects and want to remove something it gets tricky. A good way to solve this would be to keep the DisplayObjects, but not attached to any visible clip, and updating them as needed.
Enough with the talking for now, here’s a demo (Click it to make it go!)
[kml_flashembed movie="http://prototyprally.com/wp-content/uploads/2008/09/canvasfader.swf" height="500" width="500" /]
This is how you set it up:
// initializing the canvas at 500x500, not using the // autoclear and with a full size back buffer. // if you're going to use blurring or some other "destructive" // effect, you can use a smaller back buffer that means // setting a bigger buffer divisor as the fourth argument var _canvas:Canvas = new Canvas(500, 500, false, 1); addChild(_canvas); // this color transform is applied each update(), // here i set the alpha multiplier to .5 making // whatever was in the buffer the last time around // gets faded by that amount var colorTransform:ColorTransform = new ColorTransform(1, 1, 1, .5, 0, 0, 0, 0); _canvas.colorTransform = colorTransform; // a simple blur filter // (it's faster with multiples of two for the blur-setting btw) var blurfilter:BlurFilter = new BlurFilter(4, 4, 1); // feed it in like this, this is too run on each update() _canvas.addFilter(blurfilter);
This is what you do each frame to apply fades, blurs or whatever effects you put in there:
// if you don't apply any effects this isn't even needed. _canvas.update();
To draw something on the canvas you do this:
// draws a white box var box:Shape = new Shape(); box.graphics.beginFill(0xffffff); box.graphics.drawRect(0, 0, 50, 50); _canvas.draw(box);
Big thanks to my friend Richard who gave me some feedback on the code making it possible to read for people that are not me.
Comments are very much appreciated!