Worms-like destructible terrain in Flash
Do you remember Worms game and its destructible terrain?

Jordi Sanglas Molist explains us how to create a basic destructible terrain with AS3
« Today, browsing the “most popular” posts, I found “Create a flash artillery game – step 1“, where you talked about making a game similar to Worms.
Then, I thought: “How will I make a destructible terrain?”
After looking for some information, I realized I should use a Bitmap. So I started with a really basic prototype:
- The character falls if he doesn’t touch the ground
- You can press at any point of the terrain to make a hole (because I don’t still have weapons)
The code is fully commented (and there are only 59 miserable lines), so you won’t have any problem to understand it.
I’ll be three days on holiday, so on Sunday I’ll start writing the next part, which I think it may talk about moving the character.
I think I’ll do it in that way: if you press the right arrow and in the right the obstacle is less than X
pixels height, you can move. I’ll try if that works. »
I am looking forward for character movement, meanwhile this is the script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | package { import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.geom.Point; import flash.geom.Matrix; import flash.events.Event; import flash.events.MouseEvent; public class worms extends Sprite { public var terrain_bmpd=new BitmapData(550,200,true,0xFF00FF00);//This is the Bitmap of the terrain public var terrain_bmp=new Bitmap(terrain_bmpd);//and this the BitmapData public var character=new Sprite();//The character will work as a worm public var hole=new Sprite();//That's the hole we need public var hole_matrix:Matrix;//The hole_matrix is used to set the position of the hole public var left_foot:Point; public var right_foot:Point;//These are the feet of the character. We will use it to check collisions public function worms() { draw_objects();//This function draws the character, the terrain and the hole. stage.addEventListener(Event.ENTER_FRAME,fall); stage.addEventListener(MouseEvent.MOUSE_UP,mouse_up); } public function fall(e:Event) { /*This function will move down the character if there isn't a collision between the terrain and the "feet" of the character*/ for (var i:int=0; i<10; i++) {//We want to check every pixel if there's acollision, so we won't move the character 10 pixels all at once left_foot=new Point(character.x-5,character.y+10); right_foot=new Point(character.x+5,character.y+10); if (!(terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,left_foot))&&!(terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,right_foot))) { character.y++;//If there aren't any collisions, make the character fall one pixel } } } public function mouse_up(e:MouseEvent) { hole_matrix=new Matrix();//We need to reset the matrix each new hole hole_matrix.translate(e.stageX-terrain_bmp.x,e.stageY-terrain_bmp.y);//and setthe coordinates of the hole terrain_bmpd.draw(hole,hole_matrix,null,BlendMode.ERASE);//Then, we can draw the hole in the BitmapData } public function draw_objects() { terrain_bmp.y=200;//The terrain shouldn't be at the top of the stage! stage.addChild(terrain_bmp);//We can make the terrain visible character.graphics.beginFill(0x0000FF);//Let's draw the character. It will be a blue rectangle. character.graphics.drawRect(-5,-10,10,20); character.x=250; stage.addChild(character); hole.graphics.beginFill(0x000000);//Now we draw the hole. It doesn't matter the colour. hole.graphics.drawCircle(0,0,30); } } } |
And this is the result:
Click on the terrain to create holes and watch your “worm” falling down.
They can be easily customized to meet the unique requirements of your project.















(27 votes, average: 4.52 out of 5)









This post has 32 comments
Alexandre Colella
Wonderfull!
And a bit difficulty.
The Matrix and translate commands… hmmmm… I don´t know.
:)
Monkios
Very nicely translated into Flash.
I hope to see your game soon.
Poupi
I’m reading this blog since a long time, and your work is just amazing.
I can’t believe that the basics of Worms’ engine are so… easy !
Bivis
Nice! I always though that it was difficult… but is very easy!!!
I have a question on a thing: How is the performance of the BlendMode.ERASE ???
I’ve clicked a lot on terrain and didn’t have any problem with performance. But in a more complex game can we have some problems?
If yes.. there’s a way to build again the terrain, but this time with the holes in itself?
Thanks by nice tutorial!
Allan
Nice tutorial. Looking foward to seeing your progress.
I created a worms style game not too long ago, similar process. If you like, you can see my game at http://portfolio.allanbishop.com/bin/load.html?url=Orbot.swf
Kaustav
Hey nice tut!
A while ago i did a worms-like destructible terrain too. I didnt use bitmaps though, only vectors. It may be simpler.
All i did, was create a ball over the place where one clicks. Every time one clicks, a new ball is placed. All of the balls are part of the same movieclip.
Then, the hero would ‘hit the ground’ when he is touching the ground AND NOT the balls. Voila! Destructible terrain!
It worked pretty well, and you can destroy terrain in any shape. No need for bitmaps! It seems to be fast also.
What do you think?
Jordi Sanglas Molist
I was also worried about the performance, but I think that the function BitmapData.draw() calculates only the final pixels: it doesn’t matter how you got to them.
I’m not sure, but I guess that flash would have included a method to delete again the circles if they were still there. However, that’s a good observation.
Jordi Sanglas Molist
That’s also a great idea (it may be easier). I didn’t think about that strategy. However, as I started using bitmaps, I’ll continue with it. If you use bitmaps, the result is the same (you can also destroy the terrain in any shape). Speed? I think in both cases it’s fast: as I said in Bivis’ reply, I guess that the circles disappear after the BitmapData.draw() function.
I’m only 15 and I hardly ever find good tutorials to learn programming languages, so I always miss lots of things.
Emanuele Feronato
Kaustav’s idea should work, but you’ll need to apply a mask to the terrain if you have a background image… and it won’t work if you simply use the “holes” movieclip as a mask… interesting idea anyway…
Kaustav
True, the images do make a problem. And bitmap is probably faster once you start to use many circles, since you still have to check through each one, while on a bitmap, once a pixel is destroyed, its done.
On the plus side, it might be easier for collision detection, since you can easily make physics for the inside of circles.
In any case, i still think bitmap is better. I want to see how you make the character move, it was difficult for make to make smooth movement.
Jodi Houareau
Awesome tut, exactly what I’ve been looking for!
I’ve been trying to empliment the stardust particle engine for the explosion when terrain is destroyed, its quite tricky though. Maybe you can include something like that in one of you future tuts.
Great work, Thanks
Jodi Houareau
So wheres part two? I’ve been on the edge of my seat for like a month :-)
Jordi Sanglas Molist
I sent part 2 to Emanuele Feronato two or three weeks ago, I’m also waiting. Part 2 is about character movement (I also solved a bug). Part 3 will be about the explosion impulse.
Well, I’m sorry. I don’t know when is he going to post that.
Jodi Houareau
Ah okay, thanks Jordi. Appreciate the feedback. Interested to see how this develops. Keep up the good work!
Jordi Sanglas Molist
As I don’t know when Emanuele will post my second part, maybe you can give me your e-mail address or tell me how to send the tutorial to you.
I’m stuck in part 3. I looked for some information about the explosion impulse and how to calculate it, but I didn’t find anything.
Emanuele Feronato
I am sorry, I did not receive anything.
Send me the 2nd part and I’ll publish it at once.
Emanuele
Jordi Sanglas Molist
I sent you two e-mails, so I thought you were busy.
I sent the 2nd part again. Did you receive it now?
Jodi Houareau
Still no part two… Would be great if you could send it to me Jordi, can use this address jh.spammer@gmail.com
Jordi Sanglas Molist
I sent you part 2, but I don’t know if you’ll receive it (I tried to send other e-mails to my family, and they got them).
Emanuele Feronato
I am still not receiving the file. If someone has received it, can you please forward to info[at]emanueleferonato.com?
Jodi Houareau
Alas, I also hav’nt recieved it. Must be lost in the intertubes somewhere.
Jordi Sanglas Molist
I really don’t know what’s happening. I received Emanuele’s mail (about freewebspace), but it seems that you don’t receive my messages. I did a last try, using a hotmail account (instead of telefonica). If it doesn’t work, I’ll upload it on freewebspace.
Jodi Houareau
Yay! got it! thanks bud! will forward it to you emanuele. Super keen to see your progress.
Worms-like destructible terrain in Flash – Part 2 - Emanuele Feronato
[...] After having some troubles with the email, I am finally able to post Jordi Sanglas Molist‘s second step of Worms-like destructible terrain in Flash. [...]
satya
i got the point and now i am able to use .as file, previously i was using to write code in .fla only.
rise4peace
Hi Emanuele,
Your tutorials are extremely helpful and I appreciate the knowledge you’ve provided.
I’ve been trying to figure out how to use the translate function in order to achieve a slicing effect with a game I am developing.
In a nutshell, I’m trying to replicate the functionality of a missile falling from the sky and penetrating through a users shield, just like what happens in space invaders, and for the life of me I’m coming up short.
Using your tutorial I’ve gone ahead and added code that makes the blue rectanle fall from the top of the screen. I then use the fall event to which I’ve added a penetrateBase() function which gets triggered when the missile touches the base using your hitTest checks.
The penetrateBase() function looks like this:
public function penetrateBase()
{
trace(“hitting shield”);
character.y++;
characterMatrix = new Matrix();
characterMatrix.translate(character.x, character.y);
terrain_bmpd.draw(character, characterMatrix, null, BlendMode.ERASE);
}
Unfortunately when I run the code, the missile falls correctly and penetrates the base, but instead of removing a vertical slice from the base, the base is left untouched.
I know I’m pretty close, I’m almost positive I’m getting hung up on translating the coordinates properly for the falling missile and its intersection with the base.
Any suggestions would be greatly appreciated.
cheers,
rise4peace
Gabi Barrientos
This is so awesome!
I’ve been waiting for this tutorial for so long!
I’ve been working on a multi player game engine which is supposed to be a mix between worms and lemmings, and i could not get this part right myself.
Thank you so much!
Ben
I was working on something similar based on the game DeathTank that came with Duke Nukem on the Saturn.
This was only an exercise, but managed to get something similar. I never got round to implementing the movement restriction based on the angle, and the angle of the “tank” is not offset…
http://flashpimp.co.uk/flashtank/
note the nuke takes longer than the shell to charge. The game also works with multiple players, and I built a SocketServer in AIR to broadcast movement to all players. Haven’t got round to finishing it yet as I have been busy on other stuff!
Christian Scholz-Flöter
Thanks for sharing!
Somehow I can click 24 times to generate a hole in my Bitmap. After that, a click does not have any effect any more. Does anyone have an explanation for this strange behaviour?
Code:
var hole:Sprite = new Sprite();
var hole_matrix:Matrix;
var polyData:Poly = new Poly(0,0);
var polyBmp:Bitmap = new Bitmap(polyData);
stage.addChild(polyBmp);
stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void {
hole_matrix=new Matrix();
hole.graphics.beginFill(0x000000, 1);
hole_matrix.translate(e.stageX-polyBmp.x,e.stageY-polyBmp.y);
hole.graphics.drawCircle(0,0,30);
polyData.draw( hole, hole_matrix, null, BlendMode.ERASE);
}
Poly is a PNG-Bitmap symbol in my library with a linkage class name “Poly”.
How to create a destructible Texture in XNA « Bayinx
[...] Emanuel Feronato’s Destructible Terrain in Flash [...]
How to create a destructible Texture in XNA | XNA Hero
[...] Emanuel Feronato’s Destructible Terrain in Flash [...]
Cloudy Pixel Games » Tutorial #1:Pixel Perfect Collision with Flixel Part 1
[...] two tutorials that had the code is here and [...]