I want to make bitmaps explode, but not by creating separate explosion graphics, instead I want to use the original picture and make it blow up into pieces, like this: http://www.tonypa.pri.ee/test/explode.html
What you think? Anyone done something like that or has ideas how to improve it?
but I am sure you´ll find more as you search yourself
but that demo is already pretty cool, perhaps add some glim, sparks or noise effects (wich can be unique sprites again) so that it looks more like breaking.
Also perhaps add random dirt maps, a common method in the 3d industry is using so called cavity (convex/concarve) or ambient occlusion maps to fake dirt and altering of objects. If you apply that on 2d it could for instance mean a slight inside glow of brown or black with blending mode set to multiply.
another cool idea could be to clamp chunks together instead of exploding thus imploded shifting into each other. Like hitting metal and watching how it gets more and more compact.
If you then use tesseltation of triangles it could look really great
In your example link tony, how is it done ?
In my latest games, I've maybe made something you're looking for. I have a movie clip, I split it into several piece of bitmaps and I explode the bitmaps.
I know that this is easier said than done, but I think some rotation on the little pieces would make it look a lot nicer. How exactly you would accomplish this, I don't know. Obviously you could just "draw" them rotated, but that's going to slow things down. Is it possible that you could prerender rotated shrapnel shaped pieces, then do a bitmapfill on to them? I wonder if that would be faster.
I have rotating shrapnel in this demo but it's all solid colored. Maybe you could just approximate the original bitmap by drawing small solid colored shrapnel of appropriate color.
Or you could just have each piece as a separate bitmap and just rotate them in the same way you would rotate anything else. Probably a lot more efficient than all of the other crazy things I suggested.
Did I mention it should of course run fast? Since its only for the eye-candy, most of the power is needed elsewhere. There will be many other elements flying around same time.
renderhjs, that looks interesting but too complicated.
I am simply using 1 bitmap and copyPixel to put pieces there, so cant handle rotations. After some time it breaks the bitmap into 4 smaller bitmaps.
Yeah, I love pre-rendering. If you're not exploding anything that's being created or deformed dynamically, I don't see what it would hurt. I'm only suggesting rotation because to me without rotation it looks more like it is being sliced up methodically than being exploded.
EDIT: It looks like you have changed it a bit since I last looked. Now things are exploding outward instead of completely randomly. That's actually something I considered suggesting, and I think it definitely looks better now.
//the array to hold all the pieces
var explArr:Array = new Array();
//bitmap for explosion, size of the screen
var explBmp:Bitmap = new Bitmap(new BitmapData(400, 400, true, 0));
this.addChild (explBmp);
//example object to be blown up
var ob:Object = new Object();
//use bitmap with linkage name ship_bmd
ob.bmp = new Bitmap(new ship_bmd(0, 0));
ob.bmp.x = 200;
ob.bmp.y = 200;
this.addChild (ob.bmp);
//listeners
this.stage.addEventListener (MouseEvent.CLICK, myClick, false, 0, true);
this.addEventListener (Event.ENTER_FRAME, doExplode, false, 0, true);
//user clicked, explode
function myClick (ev:MouseEvent):void {
//hide the original bitmap
if(explArr.length == 0){
//only hide it if the explosion was not already running
this.removeChild(ob.bmp);
}
startExplode (ob.bmp);
}
Begin explosion
PHP Code:
//starts the explosion with bitmap b
function startExplode (b:Bitmap):void {
//clear the array, dont clear if you want to have multiple explosions
explArr = new Array();
//first object to be inserted into array, its full bitmap
var curOb:Object = new Object();
//get bitmapdata
curOb.bmd = b.bitmapData;
//position
curOb.x = b.x;
curOb.y = b.y;
//movement
curOb.xd = 0;
curOb.yd = 0;
//lifetime
curOb.t = 0;
//put into array
explArr.push(curOb);
}
Run enterframe event
PHP Code:
//runs explosion
function doExplode (e:Event):void {
//check if array is empty
if(explArr.length > 0){
//start manipulating the bitmap
explBmp.bitmapData.lock();
//clear the bitmap
explBmp.bitmapData.fillRect(new Rectangle(0, 0, 400, 400), 0);
//loop the array
for(var n:int = 0; n < explArr.length; n++){
//get first piece in the array
var curOb:Object = explArr.shift();
//move the piece, 4 is speed value
curOb.x += curOb.xd/4;
curOb.y += curOb.yd/4;
//copy this piece into main bitmap
var r:Rectangle = new Rectangle(0, 0, curOb.bmd.width, curOb.bmd.height);
explBmp.bitmapData.copyPixels(curOb.bmd, r, new Point(curOb.x, curOb.y));
//check if its time is up
if(curOb.t <= 0){
//break it up if its at least 3 pixels
//you could break up 2 pixels too but it wont change much
if(curOb.bmd.width > 2){
//create 4 new pieces
breakOb (curOb, 0, 0);
breakOb (curOb, 1, 0);
breakOb (curOb, 0, 1);
breakOb (curOb, 1, 1);
}
}else{
//reduce life
curOb.t--;
//its still alive, add back into array
explArr.push(curOb);
}
}
//array is empty
if(explArr.length == 0){
//clear the bitmap
explBmp.bitmapData.fillRect(new Rectangle(0, 0, 400, 400), 0);
//re-place object
this.addChild (ob.bmp);
ob.bmp.x = 40 + Math.random() * 320;
ob.bmp.y = 40 + Math.random() * 320;
}
//finished manipulating the bitmap
explBmp.bitmapData.unlock();
}
}
Breaking up
PHP Code:
//creates smaller 1/4 piece of bitmap
function breakOb (curOb:Object, xd:Number, yd:Number):void {
var newOb:Object = new Object();
//half the size of old piece
var s:Number = curOb.bmd.width/2;
//create bitmapdata
newOb.bmd = new BitmapData(s, s, true, 0);
var r:Rectangle = new Rectangle(xd * s, yd * s, s, s);
//copy part of old bitmap into new piece
newOb.bmd.copyPixels(curOb.bmd, r, new Point(0, 0));
//check for empty bitmap
r = newOb.bmd.getColorBoundsRect (0xFF000000, 0x00000000, false);
//find if it contains any non-transparent pixels
if(r.width > 1 || r.height > 1){
//place new piece
newOb.x = curOb.x + xd * s;
newOb.y = curOb.y + yd * s;
//check if this was first division from original bitmap image
if(curOb.xd == 0 && curOb.yd == 0){
//make it move apart from origin
var xm:Number = newOb.x - curOb.x - s/2;
var ym:Number = newOb.y - curOb.y - s/2;
//add some randomness
xm = xm + xm * (Math.random() * 2 - 1) * 1;
ym = ym + ym * (Math.random() * 2 - 1) * 1;
}else{
//completely random movement
xm = Math.random() - 0.5;
ym = Math.random() - 0.5;
}
//movement speed depends on the size, change 30 / (s * s) for other results
var tm:Number = Math.sqrt(xm * xm + ym * ym) * (30 / (s * s));
//save movement, getting half of the movement from old piece
newOb.xd = xm/tm + curOb.xd/2;
newOb.yd = ym/tm + curOb.yd/2;
//lifetime, play with values here for different results
newOb.t = 10 + Math.random() * 30 - s * 1.5;
//add to array
explArr.push(newOb);
}
}
Notice that original bitmap should not be rotated, and it works better on the square images.
Thanks for sharing, Tony! Your example looks great! Runs great on my trusty old laptop (1,66GHz, 2Gb RAM). You could add an fps counter if you want more solid stats! Doesn't seem to slow down though, and the look and feel is awesome!
You're the man Tony. You should post things like that on your site for posterity. If you don't I might plop it on mine, with full credit given to you of course. Just good to have snippets like that put somewhere they can be read, instead of rotting away on some internet forum.
3 - send the parts flying off in different directions based on their relation to the center of the original image - determine angle of new part from center of original image then calculate starting x and y speeds (like this with rotation removed)
4 - apply gravity
5 - BOOM!
Before I struggle to marry all of these techniques together, I figured I'd ask if anyone out there has already done this