100 Movie clips vs BitmapData... why are MCs faster?
I'm currently in the process of trying to make a faster version of Invasion 4, since in the later levels there's an incredible number of objects flying around, and it kills most computers.
The main problem, I thought, was that Flash doesn't like having lots of movie clips to keep track of.
I plotted for a while, and then came up with this solution: have just one movie clip, but draw it 100 times into a BitmapData object!
So here's the code I used:
PHP Code:
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Matrix;
var stageW:Number = 700;
var stageH:Number = 400;
// Make my BitmapData...
var myBmp:BitmapData = new BitmapData(stageW, stageH, true, 0x00000000);
createEmptyMovieClip("bmp", getNextHighestDepth());
bmp.attachBitmap(myBmp, getNextHighestDepth());
// Make an array of all the infantry that are walking.
walkingInfantry = [];
onEnterFrame = function () {
// Clear the BitmapData.
myBmp.fillRect(new Rectangle(0, 0, stageW, stageH), 0x00000000);
// Make sure infantry is on walking frame, since frame 2 is his attacking animation, and frame 3 is his death animation
infantryClip.gotoAndStop(1);
// Loop through the array of all the infantry that are walking
for (i in walkingInfantry) {
w = walkingInfantry[i];
// Add soldier's xspeed to his _x
w[0] -= -w[3];
// Make soldier move between -.5 and .5 pixels on the _y axis.
w[1] -= -0.5+Math.random();
w[2]++;
if (w[2]>infantryClip.anim._totalframes) {
w[2] = 1;
}
var translateMatrix:Matrix = new Matrix();
// Translate BitmapData to the coordinates of this soldier
translateMatrix.translate(w[0], w[1]);
// Make infantry MC go to the frame that this soldier's on
infantryClip.anim.gotoAndStop(w[2]);
// Draw this soldier
myBmp.draw(infantryClip, translateMatrix);
}
};
for (i=0; i<=100; i++) {
infantryClip.gotoAndStop(1);
walkingInfantry.push([-50, 290+random(20), random(infantryClip.anim._totalframes)+1, 3+Math.random()*5]);
// ^^^ [x, y, frame, xspeed] ^^^
}
Compared to the 100 movie clips code, which is this:
PHP Code:
infantryClips = [];
onEnterFrame = function () {
for (i in infantryClips) {
w = infantryClips[i];
w._x -= -w.speed;
w._y -= -0.5+Math.random();
}
};
for (i=0; i<=100; i++) {
infantryClips.push(attachMovie("infantryClip", "infantryClip"+getNextHighestDepth(), getNextHighestDepth(), {_x:-50, _y:290+random(20), speed:3+Math.random()*5}));
}
But the '100 movie clips' method ran at a higher framerate than the '1 movie clip drawn in 100 different positions' method. What gives? Surely the BitmapData technique would mean that Flash doesn't have to render as much, and wouldn't have to store the properties of all those movie clips?
You can view the BitmapData file at:
http://www.birchlabs.co.uk/InvasionOptimized.swf
And the 100 movie clips at:
http://www.birchlabs.co.uk/WithoutBMPData.swf
Is there any way I can use BitmapData to make 100 troops move at a higher framerate than with 100 movie clips? I'm sure there's got to be. Is the lag linked to Redraw Regions? The BitmapData fills the whole stage (I'd narrow it down to just the strip of land the infantry walk on, but arrows will be able to appear pretty much anywhere in the final game), whereas the 100 movie clips use a much smaller redraw area.