235. Angry Birds – Exploding birds!
I love explosions, so making the black bomber bird with physics was a lot of fun.
The black bomb bird in Angry Birds glows red when it hits something, then explodes a few seconds later.
I added some code to pull two bomb bird pictures (a normal image and a red image) out of my spritesheet – see my first Angry Birds for details on doing this.
Until now, I haven’t needed more than one picture for a bird, so I had to go through and make the original bird image into a table of images. Then, when there is a collision, I use this code to set a timer for the explosion and show the red image.
if b.birdType=="blackBird" and not b.explodeTimer then b.explodeTimer=ElapsedTime+2 --will be used below b.imgNo=2 --show red image end
In the DrawBird() function, I added this code
--check if it's time to explode if b.body.explodeTimer and ElapsedTime>b.body.explodeTimer then b.body.active=false --turn off physics for this bird Explode(vec2(b.body.x,b.body.y),200,1) --discussed below birdTimer=nil --turn off timer that usually removes birds b=LoadBird(true) --load next bird now end
Of course, the important part is the Explode function. What does it do?
Naturally, when wondering how to do it using physics, I used my good friend Mr Google, and found a page with a good idea.
Particles
The idea was to use a set of particles – that is, very small physics objects – that are sent out at high speed in all directions from the middle of the exploding bird. They will have just the effect we want, and I won’t have to do any of the work of figuring out which scene objects move or are destroyed. Well, there is some work.
To start with, I realised I could just create a set of little particles at the beginning, and set their active property off so they didn’t affect the scene. Then, whenever I have an explosion, I can just set their position and velocity, and make them active. When they hit something, or after a set time (eg 1 second), I set the active property off again.
So here is the code to create the particles
function CreateParticles(n) --n is number of particles particles={} local a=2*math.pi/n for i=1,n do local b=physics.body(CIRCLE,0.03) --VERY small! b.direction=vec2(math.cos(a*i),math.sin(a*i)) b.bullet=true --see below b.gravityScale=0 b.restitution=0.8 b.fixedRotation=true b.active=false --turn them off until we need them b.friction=0 b.mass=10 --make particles heavy so they hit harder particles[i]=b b.explode=true --so the collide function recognises them end end
The important settings here are
- set the size of the particle to 0.03. They need to be small, so when they are starting out in a small circle around the centre of the bird, they don’t collide with each other and change direction. However, making them small also makes them weak, which is why I set the mass property below
- b.direction – this isn’t a physics property, I’m just storing the angle of the particle so that when we have an explosion, I can set the velocity (a physics object is a table, so you can store your own information in there as well if you want)
- b.bullet – tells Codea to prevent fast moving particles from tunneling right through an object. Tunnelling happens when a particle moves so fast that it is on one side on an object in one frame, and on the other side of the object in the next frame, so it is easy for the physics engine not to realise that a collision occurred. Setting the bullet property tells Codea to check for this situation – and you must also set physics.continuous=true for this to work. It slows things down, but we don’t have a speed problem, so that’s OK.
- b.mass – make the particles heavy because they are very small
- b.explode is again not a physics property. I use this in the collide function to recognise particles that have collided with something, and turn them off, to improve speed
Then we have the Explode function, which explodes the bird when the timer runs out
function Explode(pos,s,t) --pos is centre of explosion --s is strength of explosion --t is time that particles are allowed to fly exTime=t or 1 particleTimer=ElapsedTime+exTime --I show smoke for twice as long as the particles smokeTimer=ElapsedTime+exTime*2 --turn particles on and set position and velocity for i=1,#particles do local b=particles[i] local p=pos+b.direction b.x,b.y=p.x,p.y b.linearVelocity=b.direction*s b.active=true end --make an explosion image exImg=MakeExplosionImage() exPos=pos --store explosion position sound("Game Sounds One:Punch 3") --bang! end
I haven’t mentioned smoke before. I have a little function that makes a smoke image that I show for a little longer than the actual explosion. I won’t show the code here because it’s nothing very clever, I just draw a bunch of random semi-transparent white circles on an image in memory.
I then update the particles each frame. This is mainly to check if I can turn them off yet, based on the timer. In the second part of the if test below, I draw the smoke, and then I draw a yellow dot for each particle. In the final game I would not draw these dots, but it’s useful at this stage to see where they are going.
function UpdateParticles() if particleTimer then if particleTimer<ElapsedTime then for i=1,#particles do particles[i].x=-1000 particles[i].active=false end particleTimer=nil else fill(255,255,0) sprite(exImg,exPos.x,exPos.y,exImg.width*(smokeTimer-ElapsedTime)/2/exTime) for i=1,#particles do ellipse(particles[i].x,particles[i].y,2) end end end end
The video demonstrates the explosions, and they look nice. If I were publishing this game, I would want to tune them a lot more, to get the strength of the explosion just right, which is a combination of the strength parameter in the Explode function, the size of the particles, and their mass.
But for now, I think it’s fine
Levels
If you look at the top of the Levels tab, you’ll see I have three functions, Level1, Level2 and Level3, each defining a different level. If you look in setup, you’ll see a line CreateScene(3), which chooses the Level3 level. If you change the number in brackets to 1 or 2, you’ll get the other levels.
This is obviously unfinished, but all it needs is to give users a way of choosing levels, and making sure all physics objects are destroyed before loading a new level. I haven’t done this part because finishing games and creating menu screens is boring, and I’m not going to publish this game, obviously. I’ve done all the exciting stuff.
Summary
I’m sure you’ll agree that it’s very possible to create a very good Angry Birds type game in Codea, if you program cleverly. I’m not not talking about my cleverness, but that of the Angry Birds designers, because they got the physics engine to do most of the work, and kept the animation work to a minimum (eg using simple text scores to provide an animation for objects that are destroyed, and just a couple of pictures to animate the pigs and birds). Even the circular shapes of the birds and pigs was probably chosen because this is one of the standard physics shapes.
I got close to what they did, only because they made it simple.
Code
The code is here. (Note that if you pull the bird down too low on the catapult, it will “collide” with the ground and begin exploding. I would have to fix it this were a serious game, but I didn’t).
Don’t forget to use a “long press” (press on Add New Project in Codea until you get the option to copy into new project) to get the code put into separate tabs for you.
Th code doesn’t work for me please explain:(