I was working on a job last week where I need to create an animation of ‘data lines’, ie lines that seem to pulse from one point to another. The first thing that sprung to mind was using the bitmapData Class in a similar way to other examples I have seen, and use a particle system to emit dots which would travel out from a pre-determined point and leave a trail behind them. This was exciting because it’s the first time I’ve used something from my research & development time on a live job, instead of a live job sparking ideas which I explore in my research & development time. Well the job went great, the client loved the effect that the dots created and all-in-all everyone was happy.
Then, a few days later I received an email saying that the animation was chugging and was creating a really negative experience when used on lower-end machines. I’d also started to encounter this problem when I was building the animation and pumping it with 300+ particles to update each frame. I couldn’t explain it, I was using bitmapData to make the thing run fast and stop any performance problems. Well, after some research in to tips and trick for using the bitmapData class, it turns out I had used the technique in the wrong way! Thankfully I need to remove 1 line of code from my Particle class and place it in the ENTER_FRAME loop instead. A simple change that literally meant I can now run an animation with 1000+ particles @ 60 fps and not get a performance hit (unless I go fullscreen!).
The problems was that in my original animation I was looping through an array of Particles and calling the render() method on each. This draws an Ellipse on an empty Sprite which isn’t added to the display list, and then it calls the draw() method to draw the empty Sprite on to the bitmap which IS added to the display list and is the object you see. This is meant to be faster because, instead of displaying 1000+ graphics each frame and grinding the Flash player to a hault, the system only displays 1 bitmap which changes each frame.
The problem was that I was calling draw() for the bitmap in each Particle. So with a 100 Particle system draw() was being called 100 times a frame. This is the problem! The solution was actually quite simple and was one of those annoying ‘doink’ moment where you see exactly what the problems is and call yourself an idiot for not realising sooner. I removed the draw() call from the Particle completely and placed it in the ENTER_FRAME loop after all the Particles had been rendered.
The new systems can have an array of 1000+ particles that it loops through each frame and calls the render() method on. Then once all the Particles have rendered their graphic to the empty Sprite I use draw() once to draw the Sprite to the Bitmap. So once all the code has run, the only thing the Flash player has to render is the Bitmap, because nothing else is in the display list.
You can download a zip of the new example here to see for yourself. The download is the same system that is running in the example above.
