Lesson 6 - Messages to The Bullet
Now at least our invadirs movie is starting to look like a game. It's even visually recognisable as space invaders even though there is no gameplay yet. If you've got this far and your brain is still working, then I'm quite sure that you're really eager to take the project a step further so that you can actually shoot and destroy the aliens. Take it easy though, some things should not be rushed into, and OO design is one of them.
You've already got the invaders to move horizontally. The bullet isn't going to be all that different. It's going to be moving vertically instead, and of course it's not going to bounce off the top and bottom of the screen (unless you really want it to). Drag the bullet into frame 1, channel 2 in the score and give it this script:
property mySprite on beginsprite me set mySprite to the spritenum of me end on exitFrame me set myV to the locV of sprite mySprite set the locV of sprite mySprite to myV - 1 end
Name the script "bullet script". Notice that instead of locH we are using locV , referring to vertical location. For clarity I have called the local variable myV , but you could call it pizza or fireman if you liked.
When you run the movie, you will see the bullet rising up the
screen and eventually disappearing. This closely resembles the
first invader script, but in what ways will it differ as we refine
it? Here is a quick rundown.
Now we touch upon another important area of software design, the concept of states. The bullet is going to have two quite distinct states, shooting and not shooting. Did you notice the word not? Remember how I said that the word not is intimately connected with logic? Remember true and false? In this case, Shooting is either true or false.
Lingo provides two constants true and false, numerically equivalent to 1 and 0 respectively. A variable which only has one of two values is called a flag or boolean variable. The word 'boolean' is named after the mathemetician George Boole, the first person to explore logic thoroughly. All digital hardware and software designs are fundamentally based on his work. If you think true and false is not really a very expressive range of options, consider that everything you see on your computer is stored as millions of booleans, usually called binary digits or bits for short. Take them seriously, they are not as innocent as they might seem!
So we're getting somewhere. If the bullet is shooting it should move up the screen checking to see if it has hit anything or gone offscreen altogether. If not, it should just hang around waiting to shoot. This 'shooting' thing sounds like something we want the sprite to remember, so we therefore know that it's going to be a property.
property mySprite, shooting
on beginsprite me
set mySprite to the spritenum of me
set shooting to false
end
on exitFrame me
if shooting then
set myV to the locV of sprite mySprite
set the locV of sprite mySprite to myV - 1
end if
end
Good, but how do we get the bullet to shoot? So far we have been using messages which are sent by Director itself; exitframe and beginsprite. These are not by any means the only messages that Director sends, but if you really want to unleash the power of Lingo, you're going to have to create some messages of your own.
I propose we imagine that there is a shoot message which is going to get sent to the bullet. I'm not interested in where the message comes from just yet, only that the bullet is going to have to respond to it. This means making a new handler in the bullet script. You can put the handler before or after either of those that are already there, just don't type it in the middle of another handler.
on shoot me set shooting to true end
There, that was easy. Rewind your movie, drag the bullet sprite to the bottom of the screen and run the movie. Nothing special happening yet? Good. Now read on.
One of the most useful parts of Director, and one which is well worth understanding is the message window. You can get this window open with the window menu. It should say "--Welcome to Director--" at the top. (If not, don't worry).
The message window is a place where you can type Lingo, but unlike in scripts, Lingo in the message window is executed at the moment you press return (or 'enter' on Windows). Try typing
beep
and press return. You should hear a system beep immediately. You can then put the cursor at the end of the line you just typed and press return again and hear the same beep.
The message window is a great place to test lines of Lingo out before you put them inside scripts. You can learn a lot about Director by playing around in the message window. Just remember that like the other authoring windows, it will not be there in the finished movie. Nevertheless it is a very immediate and direct way of sending messages into the Director environment. This can be useful for finding errors, experimenting with Lingo which you are not sure about and so on. If you get an error message, who cares! Read it and try and see why. Error messages are there to help you.
As it happens, sending messages is exactly what we are interested in right now. Your movie is running, your invaders are marching back and forth, your cannon is following the mouse as it should but the bullet (in sprite channel 2) is just sitting there. Go to the message window and type
shoot sprite 2
...and if all is well, you should see the bullet rise gracefully and disappear off the top of the screen. If we want to be able to shoot it again, we will have to trap the moment it disappears with an if...then test. It would be nice to have the bullet appear in the right place also. Lastly we should take care that the bullet can only be shot when it is not already shooting.
Here is how the script should look when all this has been added:
property mySprite, shooting
on beginsprite me
set mySprite to the spritenum of me
set shooting to false
end
on exitFrame me
if shooting then
set myV to the locV of sprite mySprite
if myV < 0 then
set shooting to false
set the locV of sprite mysprite to -999
return
end if
set the locV of sprite mySprite to myV - 1
end if
end
on shoot me
if shooting then
return
end if
set shooting to true
set the loc of sprite mysprite to the loc of sprite 1
end
Inside the original if...then test there is now another if...then test which will only occur if the original condition is met ( shooting = true ). This tests whether the bullet has gone offstage and if it has, assigns a value of false to the state variable shooting . It also moves the bullet offstage and the return instruction takes care that the handler is then left altogether without any further activity. return is used again in the shoot handler; If the bullet is already shooting, we don't want to allow it to be shot again.
return is very useful when you want to leave a handler without executing obsolete lines of code. Remember those processor cycles!
If it is ready to shoot, it's location is set to the location of the cannon. Notice that we are using loc instead of locH and locV . This allows the positioning to be achieved in one line instead of two.
loc is another lingo sprite property and when all is said and done, is usually easier to work with than locH and locV seperately. It refers to two values, horizontal and vertical in the form
point(h, v)
Make sure your movie is saved and then let's proceed...