Missile Command - Adding in Some Bombs using Scratch
This is part 4 of a multipart series on creating a version of Missile Command using the educational tool, Scratch.
It has been an awfully long time since I updated this blog! Sorry. With the new year comes a new vigour which I will definitely keep up. Moving on, though, I think the ability to fire bombs has been put off for far too long and with that in mind, this post will describe one way in which we can achieve that.
What I really wanted to be able to do is to fire off a missile and then forget about it. By that I mean, I didn’t want to have to wait for the explosion to finish before I could fire another. Equally, I didn’t want to be able to flood the screen with explosions and make the game too easy. So, I settled on the idea of there being three missiles at a time.
The first thing to do, is to create the explosion. When I first tried this, and especially if you are familliar with the game, I had the idea that there would be a circle which would grow larger before diminishing.
Idea #1: Create a circle using the pen command, then fill it, before drawing another slightly larger, and repeating. Yawn! It was so slow and didn’t work especially well, so I carefully filed that in the recycle bin.
Idea #2: Create a small explosion as a sprite and then change its size, first getting larger and then reducing, before making it disappear. This worked much better and is the method I am going to show you.
Creating the Explosion Image
Step number one is to create the actual explosion. How you do yours is up to you; for example, you could find an image from the internet or you could draw one. In my case, I wanted it to be multi-fire coloured and would go with circles. Here’s my attempt:
If you look closely, you can see that it is quite small. My first plan was to start with a large image, reduce it right down, and then bring it back to it’s original size, but the picture became really blocky and looked more like I was firing coloured cardboard boxes! This approach with starting small and then enlarging seemed to work better.
You will need three of these, but for now, create one, and name it missile-1.
Making the Explosion Animate
This is the exciting bit - making it come alive! Firstly, take a look at the code below:
To begin, we reduce the size of the sprite by half (that’s the 50% portion) and then we show it. That way, it starts its appearance from a small beginning - remember, it is seemingly tiny to start with.
Next, come two blocks - one to make it grow larger, the next to reduce it back to the original size - and finally, it is hidden from view.
Both of the growing/reducing blocks are very similar so I will only focus on one - the other is simply the inverse operation. In short, we first wait for 0.05 of a second, and then increase the size of the sprite by ten. The documentation isn’t too clear by what they mean here but I think they mean by ten percent. We then do this a further nine times (making ten in total).
Reducing the image is exactly the same, except we reduce it by ten instead of increasing it with the net effect being that we make the explosion grow larger and then smaller. Simple!
You can test this by double clicking on your block. Can’t see anything? Perhaps the sprite has an x and y co-ordinate (the place where it will display on screen) off-screen? You can set it back to the middle with:
Linking the Mouse Click With an Explosion
Did I say mouse click? I meant big red button - or whatever it is you use to fire real missiles! If you recall from a previous post, we already link the mouse pointer with the cross hairs. All we need to do to make our explosion occur at the place where the mouse is, is the following:
Can you see the bit in blue? Here, we are setting the x and y co-ordinates of the sprite to be those of the mouse’s x and y position. Again, move the mouse and double click the block - it should hopefully change the position of your explosion.
Making Things Go Bang Where The Mouse Is
I am certain that some of your would have gone click-crazy and tried to fire off lots of missiles, but only one appears, right? The issue is that we aren’t running the game in a loop which means that once we have animated the sprite, the program ends. After all, it has no reason to continue. What might this look like?
You can see that we now go forever (or until the electricity gets cut off). Showing the sprite, changing it, hiding it, ad infinitum.
Limiting the Number of Explosions
But again, this isn’t really what we want. Ideally, we do want it to create another explosion, but only when we click the mouse button. Moreover, we don’t want more than three to occur at any one time - remember the rule I decided on at the beginning - and finally, we don’t want in interrupt the explosion itself. Thinking about this last point, how weird would it be if it began to explode. Then stopped part way through. Then started again somewhere else? We will tackle this bit by bit. Individually, it is all quite straight forward, but on mass, it would be like stuffing your face with marshmallows. Or maybe not. Imagine I (I being the crosshairs or the person firing projectiles) could talk to the missile. It might go a little like this:
Me: Hey, you! (pointing at the missile) Missile: Who me?
Me: Yes! I want you to fire up into space and explode.
Missile: Ok. 3-2-1 Blast off. Boom.
But, it would also be able to ignore me:
Me: Hey missile number 1. Fire off into space, please.
Missile: OK. 3…2
Me: And fire again!
Missile: 1…
Me: Come on! Again! Missile: Blast off.
Me: Oi!
Missile: Boom.
Notice how the second time, my repeated requests were ignored? That would be like the user clicking the mouse button again. Also, no matter what, it runs through it’s sequence - not even an episode of Made in Chelsea would distract it.
OK, so how do we do this? Well, firstly, we need to do a bit of shouting and for that, we need to use the broadcast command. This allows us to send a message which anyone (anything, I suppose!) can listen for and act upon.
In this case, I want missile-1 (remember we named our explosion sprite to be that?) to listen for something shouting “fire-1“ - referring to it’s name. Jump to the script where we make the crosshairs follow the mouse pointer, and change it to look like this:
You can see that I am checking for someone pressing the mouse button with the if statement. Mouse down simply means, mouse button pressed down. And then in missile-1, the sprite’s script, we need to listen out for it:
So the two key commands are broadcast and when I receive. This latter command is just another way of saying, when I hear the message I specify (fire-1). Try running it. In particular, try clicking the mouse a few times. What do you notice? As you might have guessed, we are able to stop and start explosions, sometimes in mid flow, but we now have a system where one part of our game communicates with another. that is, the crosshairs communicating with our missile. The main part we don’t yet have is the ability to limit the number of missiles exploding. It’s almost as if we need some way of counting the explosions as they happen but then reducing that count when they have finished. Very tricky. Or is it?
To solve this, what we need is a kind of list (like a todo list), of which missiles can be fired. When they have finished doing their spectactular thing, we add them back onto the list. Provided the list has at least one item (missile number) on it, we will allow the user to fire off another missile. But, and this is important, only a missile that hasn’t been fired - remember, we don’t want to interrupt any in part-explosion.
So where do we begin? With the list, of course. Go to the red tab (the one which has variables on it) and click on make a list.
Up should pop a window where you need to type in a name for your list. Use the word: missiles and make sure that it has it set for all sprites before clicking OK. Since we can stop and start our program at will, it is important to make sure that our list is reset each time we play, and to do that, we need to empty it and then add the three missiles that can be fired. We can achieve that like this:
Let’s take a moment to explain each part. Firstly, we repeat…until. That means, keep going until a condition (a state, if you like) is true. In this case, we keep going until the length of our list is zero, or empty. And what do we do each time it isn’t empty? We delete the first thing in the list. Not missile number 1, but instead, whatever sits at the top of the list. Here, I can show you what the list might look like so that the idea is more concrete in your mind. In this case, there are three missiles ready to be fired.
Once it is empty, we then add first missile 1, then 2 and finally 3. These are all represented as numbers for simplicity. What this basically means is that all three missiles can be selected for firing, should the user click the mouse button. Next, we need to say, give me the first item on the list and depending on which number that is, fire that missile. Once we have done that, remove that item from the list.
Don’t create this part yet - I introduced it so that you had an overview of what we wanted to achieve. First, for this, we need somewhere to store whatever number sits in the initial position on our list, so let’s create a variable. Click on Make a variable and set its name to: missile-to-fire. You should select for this sprite only, since we will only use this variable here.
A variable, if you are unsure, is a bit like a box to store values in, with a name. Altogether, it should now look a little like this in the Crosshairs script.
Try running it to see what happens. In particular, keep an eye on the list which you should see at the top of your screen. It begins with all three missiles listed, then each time you click the mouse button, the list goes down by one and a missile fires. But then, it carries on…hmm. We need to do two more things:
- Make sure that once a missile has completed firing, it gets added back to the list indicating it is ready again, and
- Only fire missile 1 if it is missile 1 that is ready.
Adding the missile back to the list is easy. Go to the missile-1 sprite and add this at the bottom.
Only firing missile number 1 is also fairly straight forward. Back to the cross hairs script, we just need to add in an if condition which basically says, if we pulled a number 1 off of the list (that sounds rude, come to think of it!), then broadcast fire-1 (i.e. the message telling missile 1 to launch). Let’s add that in:
Give this a go to see how it works.
The Finishing Touches
Almost there now! I feel a bit like Rolf Harris when he would say, “Can you guess what it is yet?” The last thing to do is to replicate all of this for another two missiles. Surely you were wondering when I would mention this? :-) Change the main crosshairs script to this:
And then create a further two sprites for the other two missiles. Remember to name them missile-2 and missile-3, and to change the both the message that they listen for and the number that gets added at the end. You can see how I duplicate the sprite, below, once you right-click on it.
Let’s recap on how this all works and why. We are only able to fire three missiles, because we can only fire things that are on our missile todo list and that has at most, three items. We can’t interrupt a missile firing because as soon as we ask it to fire, that missile’s number is removed from the list, and we can’t send it another broadcast message until it reappears on the list. That doesn’t happen until the very end of that missile’s script. Lastly, numbers appear and disappear from the list we created depending on when we click the mouse button and when explosions cease to be visible. Phew!
Extending This
There are two things that I didn’t cover that would be nice for you to try without me. Firstly, what if the list is empty when we extract the item from position one? Perhaps we should only do the firing process if we pull off a number.
Secondly, must we keep doing if….if….if…? I wonder if it could be better written to use the if…else…statement? If you get stuck, just look at my example. Happy shooting!
Hi! Did you find this useful or interesting? I have an email list coming soon, but in the meantime, if you ready anything you fancy chatting about, I would love to hear from you. You can contact me here or at stephen ‘at’ logicalmoon.com