Building a Game: Sprite Invaders: Part 3
March 22, 2000
by Gary Rosenzweig
This is the third part in a three-part series of how to make the Sprite Invaders game. Complete code for this game can be found in my new book, "Advanced Lingo for Games," which is now available online and in stores.
So far, we have learned how to make the invaders themselves move back and forth and down, and how to allow the player to move the ship and fire. This week, we let the invaders shoot back, adding scoring, and finish up the game. Figure 1 shows some of these features.

A sample movie is available for download in Mac or PC format. This movie is a Director 7 file.
In order to allow the invaders to fire back, we need to add something to the invaders' behavior. In the on exitFrame handler, we will give each invader a 1 in 300 chance of firing a bullet at any given time. This probability was determined by trial and error: it just seems like the right amount to make challenging game play.
-- fire 1 out of 300 times if random(300) = 1 then sendSprite(55, #fire, sprite(me.spriteNum).loc) end if
Sprite 55 is where the bank of invader bullet sprites is located. Like the bank of sprite for the player, which begins at sprite 6, these sprite will send the fire message down the line until a sprite is encountered that is not busy. It will then fire downward until it hits the bottom of the screen, or encounters the player's ship.
property pSpeed
property pMoving
on getPropertyDescriptionList me
list = [:]
addProp list, #pSpeed, [#comment: "Speed", #format: #integer, ¬
#default: 16]
return list
end
on beginSprite me
reset(me)
end
on reset me
sprite(me.spriteNum).locV = -100
pMoving = FALSE
end
on fire me, loc
if pMoving then
-- busy, send to next sprite
sendSprite(sprite(me.spriteNum+1),#fire,loc)
else
-- set loc, mode
sprite(me.spriteNum).loc = loc
pMoving = TRUE
end if
end
on exitFrame me
if pMoving then
-- move down
y = sprite(me.spriteNum).locV
y = y + pSpeed
sprite(me.spriteNum).locV = y
if y > (the stage).rect.height then
-- hit bottom
pMoving = FALSE
else
didIHit(me) -- hit gun?
end if
end if
end
on didIHit me
if sprite 5 intersects me.spriteNum then
-- hit gun?
alert "Game Over."
halt
end if
end
When the message shipHit is sent to the player, that's the end of the game. In this case, we just trigger an alert box and stop the movie. You'll want to probably do something like send the movie to a frame that proclaims "game over".
The next step is to add scoring. The best place for this is in the frame script. There, add a property called pScore and set it to 0 in the on beginSprite handler. Then, add a handler that adds to the score.
-- message sent when an invader is hit
on addScore me
pScore = pScore + 1
showScore(me)
end
on showScore me
text = ""
put "Score:"&&pScore&RETURN after text
member("Score").text = text
end
You should also call the on showScore handler in the on beginSprite handler right after setting the score to 0. This will insure that the "Score" member starts by showing the score of 0. Here is the on beginSprite handler.
on beginSprite me pScore = 0 showScore(me) end
Another way for the game to end is if the invaders reach the bottom of the screen. You can check for this in the on changeDirection handler of the invaders' behavior. This is the only place where the invaders actually move down, so it is safe to only check for the invaders hitting the bottom here. This is the code to add.
if y > sprite(5).rect.top then alert "Game Over." halt end if
Once again, it is probably best to go to a "Game Over" frame rather than the alert dialog and the halt command. Actually, the slightly more complex sprite invaders game in my book adds the element of multiple ship lives, so you get the change to continue playing until you have been killed several times.
Adding sounds to this game is very easy. Simply insert the proper puppetSound command at the proper time. In the example movie I have added three sounds. The first is the sound of an invader being hit, the second is the sound of a ship's bullet firing, and the last is the sound of the ship exploding.
The game is now pretty complete. The one last thing missing is what happens when the player destroys all of the invaders. We can check for that every time an invader is shot. The on addScore behavior can call a new on checkEndLevel handler that loops through all of the invader sprites and sees if none are left alive.
on checkEndLevel me
-- loop through all sprites
repeat with i = 30 to 53
-- if one is still alive, look no further
if not sprite(i).pHit then exit
end repeat
-- not invaders left, level is over
alert "End of Level."
halt
end
While the example movie simply halts at the end of a level, what you'll want to do is to go to a "level over" frame. Then, when the player hits a "continue" button, the game jumps to a new frame. This frame will have the same setup as your original game frame, but the speed of each invader will be a little faster. You can set the speed of the invader when you drop the behavior on it.
Thus, with a series of frames, you can set up a Sprite Invaders game that increases in difficulty. You should make the final level so difficult that no one can get past it. However, to be safe, you will want to the final "level over" frame to loop back to this most-difficult level. This way, if a player completes all levels, they just keep going back to the hardest level until they mess up.
More information about Gary Rosenzweig's new book, "Advanced Lingo for Games", can be found at http://clevermedia.com/resources/bookstore/book4.html. It can be purchased there, or in your local bookstore.
Copyright 1997-2025, Director Online. Article content copyright by respective authors.