Foundation Game Design with ActionScript 3.0, Second Edition (58 page)

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
8.31Mb size Format: txt, pdf, ePub
if(score < 5)
{
  if (character.hitTestObject(monster))
  {
    if(! collisionHasOccurred)
    {
      score++;
      output.text = String(score);
      collisionHasOccurred = true;
    }
  }
  else
  {
    collisionHasOccurred = false;
  }
  //Check for the end of the game
  if(score == 5)
  {
    trace("Game over");
  }
}

Compile the program again with this new code, and you'll notice that the score now stops being counted at 5 and the “Game over” message is displayed only once.
Figure 6-10
illustrates this.

Figure 6-10.
One more simple if statement stops the game when the score reaches 5.

You'll find that many Potentially Puzzling Programming Problems you'll need to solve in your games can be solved by applying very simple logic like this.

Picking up and dropping objects

It's time for the cat and monster to put aside their differences and make peace! In the next example, you'll see how you can make the cat pick up an object and carry it to the monster. This is very easy to implement using the techniques discussed so far in this chapter.

You'll find a working example of this effect in the in PickingUpObjects folder in the chapter's source files. Move the cat character over the star. Press the space bar. The cat will pick up the star. Carry the star over to the monster and press the space bar again. The cat will drop the star and “Thanks!!” will be displayed as a trace message.
Figure 6-11
illustrates this process.

Figure 6-11.
Pick up the star and carry it to the monster.

The program uses a Boolean variable called
characterHasStar
to determine whether or not the cat is carrying the star. It's initialized to
false
when it's created in the class definition.

public var characterHasStar:Boolean = false;

You might be forgiven for thinking that the
enterFrameHandler
is now the star of the show as far as making fun things happen in your games. After all, most of the new techniques shown in the last 40-odd pages involved placing directives inside it. But don't forget that you have a few other just-as-useful-if-somewhat- neglected methods waiting to do your bidding if you can find some work for them. This time, the
keyDownHandler
gets to shine in the spotlight. The text in bold below highlights the code in the
keyDownHandler
that makes this program work.

public function keyDownHandler(event:KeyboardEvent):void
{
  if (event.keyCode == Keyboard.LEFT)
  {
    vx = -5;
  }
  else if (event.keyCode == Keyboard.RIGHT)
  {
    vx = 5;
  }
  else if (event.keyCode == Keyboard.UP)
  {
    vy = -5;
  }
  else if (event.keyCode == Keyboard.DOWN)
  {
    vy = 5;
  }
  
if (event.keyCode == Keyboard.SPACE
    
&& character.hitTestObject(star))
  
{
    
if (!characterHasStar)
    
{
      
character.addChild(star);
      
star.x = 0;
      
star.y = 0;
      
characterHasStar = true;
    
}
    
else
    
{
      
stage.addChild(star);
      
star.x = character.x;
      
star.y = character.y;
      
characterHasStar = false;
      
if (monster.hitTestObject(star))
      
{
        
trace("Thanks!!");
      
}
    
}
  
}
}

To understand how this works, think about what conditions need to be met before the player character can either pick up or drop the star.

  • The player of the game needs to press the space key. You can check for this condition with a conditional statement that looks like this:
if(event.keyCode == Keyboard.SPACE)
  • The character object needs to be touching the star. You can check for this condition using a conditional statement that looks like this:
if(character.hitTestObject(star))

If those two things happen at the same time, you know that the player is either trying to pick up or drop the star. But the important thing is that
both conditions need to be true at exactly the same time.
Why? Well, obviously it wouldn't make sense if the cat could pick up the star if it weren't touching it. And the game also needs to know that the player
wants
to pick up the object, which is what pressing the space key tells it.

To check whether two conditions are true at the same time, you can combine them into a single conditional statement using the
and operator
. You looked at the and operator briefly in
Chapter 3
, but you haven't really seen it in action until now. The and operator is a double ampersand (&&).

It's used in the first new if statement in this line of code:

if (event.keyCode == Keyboard.SPACE
&& character.hitTestObject(star))
{…

Great! In one line of code, you can check whether both the conditions for picking up or dropping objects have been met. But which one is it? Picking up or dropping?

That's pretty easy to figure out. If those two conditions are true, and the cat doesn't already have the star, you know that the star needs to be picked up. If the cat already has the star, you know the star should be dropped. All it requires is an additional nested if/else statement that checks whether the
characterHasStar
variable is
false
. Here's a simplified version of this logic:

if (the character doesn't have the star)
{
  Pick the star up…
}
else
{
  Drop the star…
}

Keep this in mind because this is what the actual code looks like:

if (!characterHasStar)
{
  character.addChild(star);
  star.x = 0;
  star.y = 0;
  characterHasStar = true;
}
else
{
  stage.addChild(star);
  star.x = character.x;
  star.y = character.y;
  characterHasStar = false;
  if (monster.hitTestObject(star))
  {
    trace("Thanks!!");
  }
}

Is this making a little more sense now?
Figure 6-12
illustrates how the all this logic translates into code.

Figure 6-12.
  The code that picks up and drops the star

But how is the code actually picking up and dropping the object? First, let's look at the directives that pick up the star.

character.addChild(star);
star.x = 0;
star.y = 0;
characterHasStar = true;

The code uses the
addChild
method to make the star a
child object
of the character.

character.addChild(star);

This is the same technique you used to add multiple images to a single Sprite. In this case, you're adding the star Sprite to the character Sprite. This essentially glues the star to the character. So, like a baby duckling, wherever the cat goes, the star is sure to follow.

The code then sets the x and y position of the star to 0.

star.x = 0;
star.y = 0;

Because the star has just become a child of the character, it now uses the character Sprite's internal coordinate system, not the stage's. An x and y position of 0 means that it's positioned at the character's top left corner, inside the character Sprite.
Figure 6-13
illustrates this.

Figure 6-13.
When the star becomes a child of the character, it becomes part of the character's local coordinate system.

Any x and y positions you now give the star will refer to these coordinates
inside
the character Sprite.

The last thing is to set the
characterHasStar
variable to
true
, which prevents the program from trying to pick the star up again if the character already has it.

characterHasStar = true;

The directives that drop the star are just as straightforward.

stage.addChild(star);
star.x = character.x;
star.y = character.y;
characterHasStar = false;
if (monster.hitTestObject(star))
{
  trace("Thanks!!");
}

The code first uses the
addChild
method to make the star a child of the stage again. This frees it from bondage to the cat.

stage.addChild(star);

The star is now part of the stage's coordinate system again, not the character Sprite's.

The
stage
object is the parent of
all
objects on the stage, including the
character
and
monster
. Objects that are children of the stage are at the top of the food chain and are footloose and fancy free. The star now no longer has to mindlessly follow the character around and can get into any of its own trouble that it wants to.

The next thing the code does is give the star the same x and y positions as the character.

star.x = character.x;
star.y = character.y;

This fixes it on the stage at its current position, which makes it look like it's being dropped.

The
characterHasStar
variable is set to
false
, which allows the character to pick the star up again later.

characterHasStar = false;

The last thing the code does is actually a bit of a bonus. It adds this if statement:

if (monster.hitTestObject(star))
{
  trace("Thanks!!");
}

It checks to see whether the monster is touching the star. If it is, “Thanks!!” is displayed as a trace message. Awww … friends at last! (You can find the complete code for this example in the PickingUpObjects folder in the chapter's source files.)

The bad news about hitTestObject

First, let me just say that I
love
the
hitTestObject
method! You can see from these examples what incredible power it can give you with just a few lines of code, a little imagination, and a bit of simple logic. I'm sure your head must be swimming with ideas for games already. If you have any doubts, let me just
confirm to you right now: yes, you already have all the skills you need to start making them! I won't stop you. Go ahead; take a break from this chapter and start building them if you feel inspired. A whole universe of possibilities exists!

Other books

Everflame by Peters, Dylan
The Adolescent by Fyodor Dostoevsky
The Courtesan by Carroll, Susan
The Recruit: Book One by Elizabeth Kelly
The Dark and Deadly Pool by Joan Lowery Nixon
The New World by Stackpole, Michael A.