In the first BitmapData test I did, I had one BitmapData object. I had an array of different troop properties, and used draw() 100 times, translating it to draw at the coordinates of each troop in the array.
In the second BitmapData test, I had two BitmapData objects - the main one, and the buffer, and I had an array of troop properties. The buffer was 35x50 pixels, and I used draw() once to put a rasterized version of the soldier's movie clip into it. Then I used draw() 100 times to put the buffered image into the main BitmapData in the positions of each troop in the array.
The difference between them is that in the first one, I was converting the movie clip to a bitmap each of the 100 times I drew it, whereas in the second one, I only converted it to a bitmap the first time, then copied that bitmap onto the battlefield 100 times.
I was told to use copyPixels(), and tried it out, but it turned out that copied pixels replace the pixels I want to draw into, instead of being drawn over them. A small difference, but it means that if there's a 0% alpha pixel in the buffer, it makes the corresponding pixel in the main frame 0% alpha as well, instead of drawing 0% of that buffer pixel's colour on top of the main bitmap (like draw() does).
In other words, copyPixels() replaces areas of the image, whereas draw() puts pixels on top of the existing ones. So using draw() to insert a 100 by 100 pixel square of 0% alpha pixels wouldn't change the main bitmap at all, but using copyPixels() to insert the same square would clear that area of the main bitmap. This means that copyPixels() wouldn't allow troops to overlap each other - they'd just get wiped off the battlefield if they intersected any transparent copied pixels.
[EDIT] Added depth sorting. With BitmapData. How did I do it? Wouldn't you like to know.
Last edited by VENGEANCE MX; 10-29-2006 at 06:26 PM.
i guess you sorted an array based on a z value then draw into a bitmapData. I've used this sort of thing before as well. I was thinking of making a nice little class to manage it, maybe later
One more thing to test: Instantiating objects takes a lot of time, so you can test take out the "onEnterFrame" the two instantiations you have:
do a:
var rect:Rectangle = new Rectangle(0, 0, stageW, stageH);
var translateMatrix:Matrix = new Matrix();
and inside the loop:
myBmp.fillRect(rect, 0x00000000);
...
translateMatrix.translate(w[0], w[1]);
EDIT:
Also, are you sure about the "transparency" problem? I had the same problem when tried some bitmap scrollers, and the problem was that the buffer was not transparent "initialized" (you have to do a buffer.fillRect(new Rectangle(0,0, bufferWidth, bufferHeight), 0x00000000); prior to do any draw).
addTroop = function() {
if (walkingInfantry.length==1) {
if (suggestedY<=walkingInfantry[0][1]) {
walkingInfantry.push(troop);
} else {
walkingInfantry[1] = walkingInfantry[0];
walkingInfantry[0] = troop;
}
} else if (walkingInfantry.length>1) {
for (j in walkingInfantry) {
w = walkingInfantry[j];
if (suggestedY<=w[1]) {
walkingInfantryHalf1 = walkingInfantry.splice(0, j);
walkingInfantryHalf2 = walkingInfantry;
walkingInfantryHalf1.push(troop);
walkingInfantry = walkingInfantryHalf1.concat(walkingInfantryHalf2);
return;
}
}
} else {
walkingInfantry.push(troop);
}
};
for (i=0; i<100; i++) {
troop = [-50, 290+random(20), random(infantryClip.anim._totalframes)+1, 3+Math.random()*5]
addTroop();
}
Long story short, it checks the _y position I'm telling the troop to spawn at, and sorts it into the appropriate place in the array based on that value. The for..in loop goes from the last element in the array to the first one, so the higher the index of the element is, the lower down that troop will be on the battlefield.
And no, MVolmaro, I'm not sure about it. But I cleared the buffer at the end of every frame with that script, so even if it didn't start off with an alpha channel, it would've had one by the second frame.
In any case, draw() is a lot easier to use. CopyPixels() I was using for about half an hour before I got it putting the troops in the right place (translation matrices are a lot easier to use than the Point object, and you don't have to specify how much of the area you want to copy, or what coordinate to start copying from, when you're using draw()).
And about the instantiating objects thing - I'd already worked that one out on my own by the time I was writing the buffered test.
Is it good or bad that my pc pushed a stead 25-30 fps for both test? lol
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
Very cool Veng. The bitmap one ran at a steady 10FPS and the movieclip one ran about 15 then to about a 22 when they started to get off the screen then back to 18 when they were gone.
ImprisonedPride, it's not unheard of. One other guy I know had an equally fast computer, which was able to handle both at optimum speeds.
Walsher, I think you're playing the wrong version. The bitmap one should be running up to 4 times faster than the movie clip one, rather than being slower. You probably clicked the links in my first post, rather than the ones later on in the topic. Try this bitmap test instead:
no kidding....not sure what kinda of computer you're all running, but I run both at 29/31 fps constant.......so I was really suprised to hear people are getting only 10 fps??!....or so on them.......I'm running a 2ghz laptop with 1 gb of ram.......
Didn't I go through this with you last time there was a BitmapData thread, actually blitting to BitmapData is slow.
Vengeance, if you want the fastest way, store the graphics of the sprite as BitmapData, and use attachBitmap().
I made an example previously, ParticleEffect was made by Squize, blitting sprites onto a BitmapData the size of the screen. ParticleSystem is simply BitmapData MovieClips.
Didn't I go through this with you last time there was a BitmapData thread, actually blitting to BitmapData is slow.
Vengeance, if you want the fastest way, store the graphics of the sprite as BitmapData, and use attachBitmap().
I made an example previously, ParticleEffect was made by Squize, blitting sprites onto a BitmapData the size of the screen. ParticleSystem is simply BitmapData MovieClips.
this is an interesting way of doing it....I can see the difference in speed....but I'm curious, using this method, how do you deal with animated/multi-frame sprites then?......do you create a bitmapdata through which you load every graphic frame of a sprite, and pass it on to/into an MC that will then cycle through them bmpdata frames??.......
You could do it a few ways, have the sprites and cycle them, through attachBitmap() and forcing it onto the same depth. Or you could attach a large tile sheet bitmap and use scrollRect to change its position for the frames (this is the method I currently use)
"Didn't I go through this with you last time there was a BitmapData thread, actually blitting to BitmapData is slow."
Mate, you should know how stubborn I am when I have an idea rattling around my head
The performance wasn't too far off, but yeah having to double buffer the sprite holder mc and all the other painful stuff that went with it stopped me trying to optimise it any further. Also 2 days out of a 30 something day dev time is more than enough for an experiment
"Or you could attach a large tile sheet bitmap and use scrollRect to change its position for the frames (this is the method I currently use)"
Hmmm that feels like it's going to be quicker than my method of just constantly attaching a bitmap at the same depth. May give that a bash too.
That method works really well, but it completely screws with the width and height property of the MC, so (at least in AS3) I just override the width/height getter/setter and send out the width/height of the scrollRect instead. Also it's dead fast
Or you could attach a large tile sheet bitmap and use scrollRect to change its position for the frames (this is the method I currently use)
I think I know what you mean, but I'm not 100% clear on it....do you mean, load the tile sheet with all the sprite frames as a bitmap, attach it to an MC, and then, within that MC using scrollRect with a window size to move the tilesheet/bmp around to show the correct fram for the sprite??
if you could post an example of that, it would be great
also I wonder how that would work with the bitmap.hitTest method....meaning if when hitTesting it against say another sprite to find pixel-level collision, it would take into account the entire bmpdata Sheet, or just what's in the scrollRect window........haven't had the chance to test it so I'm thinking out loud.....but was curious if you looked into that....
I don't like the idea of making a sprite sheet for everything, but it would make a lot of sense, and also be an easier way of solving the 'synchronized march' issue that the troops have (since with this method I can only have them being on the animation frame that the buffer uses).
It's still not going quite as smoothly as I want it, so I think I'll try the spritesheet thing when I get some more time. Should be fun.