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-2024, Director Online. Article content copyright by respective authors.