Articles Archive
Articles Search
Director Wiki
 

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.

Gary Rosenzweig is the Chief Engineer, founder, and owner of CleverMedia, a game and multimedia development company in Denver, Colorado. He is the author of ten books on Macromedia Director and Flash, including his latest, Special Edition Using Director MX.

Copyright 1997-2017, Director Online. Article content copyright by respective authors.