views:

170

answers:

2

I have created a Paralax effect in Flash 10 where I have about 5 layers each sitting on a different Z-axis. These 5 layers have been grouped in a symbol, so when moving the symbol around its x and y axis, the layers move in 3D perspective as expected.

We need to dynamically render text on each layer, but the problem is, I am using addChild() to add textFields to these layers to display text, and this is causing the framerate to slow down drastically, to about 12 fps.

I tried a different approach, whereby I took a bitmap snapshot of the each layer, remove all the children (textfields) and add the bitmap onto the layer instead, hoping for an improvement in framerate...but to no avail.

How could I get more performance out of this? Would it be better to use something like PixelBender (that is if I can dynamically render text in PixelBender), or would using a 3D engine like Away3D or Papervision help here?

+2  A: 

Rendering text in pixelbender would be completely crazy. There is a much easier way.

Don't use the z axis, instead do the parallax yourself, as long as the clips are not transformed, but only translated flash can cache them and everything will be nice and fast.

What I'd do is add them to an array and then update all of the positions each frame. To conveniently have them in an array I'd make a small class to associate the offset to each sprite:

class Parallax
{
    public var sprite:DisplayObject;
    public var offset:Number = 1;

    public function ParallaxedSprite(sprite:DisplayObject, offset:Number) {
     this.sprite = sprite;
     this.offset = offset;
    }

}

Once that class is made we add each of the clips/sprites we want to parallax to an array:

var _sprites:Array = [  new ParallaxedSprite(foo, 1), 
                        new ParallaxedSprite(bar, .75), 
                        new ParallaxedSprite(baz, .5) ];

(the square brackets are shorthand for creating an array)

Then, each frame we loop over the list and set the offsets accordingly:

var offsetX:Number = 100;
var offsetY:Number = 100;

for each (var parallax:Parallax in _sprites) {
    parallax.sprite.x = offsetX * parallax.offset;
    parallax.sprite.y = offsetY * parallax.offset;
}

And finally, to get that last speed boost, set the cacheAsBitmap property on your sprites:

foo.cacheAsBitmap = true;
bar.cacheAsBitmap = true;
baz.cacheAsBitmap = true;

Note that cacheAsBitmap will speed up the drawing of your sprites as long as they are not transformed, but once you DO transform them with this set you will have an added overhead of recreating this cache, so if you plan to rotate/scale alot it's better to leave it off.

grapefrukt
I bet your way will be faster, since there is no concept of 3D, thanks for your prompt reply! Much appreciated!
Joe Zephyr
A: 

Try minimizing 'overdraw'. Overdraw is how many times you redraw a pixel (or region) on the screen until the final frame is rendered.

So suppose you have 5 parallax layers and the first one is completely opaque, then drawing the other 4 is a complete wast of time.

By determining which parts of your layers are visible and only drawing those regions, you save a lot of 'overdraw', and thus make it faster

Toad