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

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
9.62Mb size Format: txt, pdf, ePub

Figure 6-28.
The cat is blocked by the box on all sides.

The code that makes all this work is simplicity itself. Most of it is identical to the other examples in this chapter. All the magic happens in the
enterFrameHandler
. The following bold code is what does all the work:

public function enterFrameHandler(event:Event):void
{
  //Move the player
  character.x += vx;
  character.y += vy;
  //Collision code
  
Collision.block(character, box);
  //Display the collision side in the output text field
  
output.text = Collision.collisionSide;
}

Yes, it's really just one line of code!

Collision.block(character, box);

It's sending the
character
and
box
objects to the
Collision
class's
block
method. The
Collision.block
method is doing all the work of preventing the objects from overlapping. You don't need to worry about how it does this; you just need to use this single line of code if you want to block movement between any two game objects. It works in this program because the
Collision
class is in the same src folder as the
BlockingMovement
class.
Figure 6-29
shows how these two classes work together.

Figure 6-29.
The character and box objects are sent to the Collision class's block method.

Collision.block is a special kind of method called a
static method
. Static methods are methods that belong to external classes that you can use inside your main program.

To use a static method in your program, simply use the name of the class that the method belongs to, followed by a dot, and then the method name with the parentheses. Here's an example:

ClassName.methodName();

You've seen static methods before; you just weren't aware of it at the time. In
Chapter 4
, you used one of AS3.0's special built- in methods:

Math.random()

Look familiar? Yes, it's a static method!
random
is a method that is part of AS3.0's
Math
class. It does the specialized job of giving you a random number between 0 and 1, and
you can use it anywhere in the program inside any other class. Static methods used like this are often called
utilities
. They do a useful little job for you in your program, and you don't need to worry about how they work as long as they provide the result you need.

You can make any class's method static by adding the keyword
static
to the method definition, like this:

static public function block(r1:Sprite, r2:Sprite):void

{…

The other extra feature of this code is that it tells you on which of the character's sides the collision is occurring on.

output.text = Collision.collisionSide;

This code is reading a
String
variable that's inside the
Collision
class and displaying it in the output text field.

There's one extra bonus to this code. With a tiny change, you can make the character push the box around the stage. All you need to do is switch the order of the objects in the method's arguments. Put the
box
first, and then the
character
, like this:

Collision.block(
box, character
);

Recompile the program and watch what happens. The cat can now push the box around the stage, as shown in
Figure 6-30
.

Figure 6-30.
Switch the order of the arguments in the Collision.block method to let the cat push the box around the stage.

How is this possible? By changing the order of the arguments, the effect of the code is on the box, not the character. The only difference is that because the character is moving, the box has to continuously reposition itself in front of the direction the character is traveling in to prevent the two objects from overlapping.

And that's how you use the
Collision
class!

If you are just happy that the new code works and aren't really too worried about the fine details, feel free to skip to the next chapter. The main thing is that you have a great little tool you can use in any of your games. If you now have a general idea of how vector based collision detection works, why you might need to use it, and how to use a static method in a custom class, that's all you need to know. Like
Math.random
,
Collision.block
is a utility that you can use whenever you want to, and you don't need to know how it works.

But if you're a code junkie, read on!

Another look at methods, arguments, and parameters

The
Collision.block
method uses two arguments. They can be any Sprite objects in your game. In the previous example, they were the
character
and
box
objects.

Collision.block(
character, box
);

These arguments are sent to the method's parameters in the function definition (which you'll find in the
Collision
class, and you'll look at soon). The parameters are highlighted.

static public function block(
r1
:Sprite,
r2
:Sprite):void
{…

I discussed how to use method parameters in
Chapter 3
, but let's review them again before you continue.

Imagine that you want to write a method that has the task of displaying the names of fruit. Let's call the method
fruitDisplay
. You want to be able to give it the names of any fruit, and the method should then accept those names and display them as a trace message.

The method doesn't know what the names of the fruit will be; you could send it any fruit imaginable. All it knows is that you'll be giving it two names. You could write some code that looks something like this:

fruitDisplay("apple", "orange");

The names of the fruit are provided inside the parentheses that follow the name of the method, which is known as the argument. You supplied the names of the fruit as strings (words surrounded by quotes), and separated them with a comma. Now it's the job of the method's function definition to do something useful with this information.

Here's what the
fruitDisplay
method's function definition looks like:

public function fruitDisplay
  (parameterOne:String, parameterTwo:String):void
{
  trace(parameterOne,  parameterTwo);
}

If you ran this code in a program, you'd see the following trace message:

apple orange

You can change the arguments in the method call at any time in the program to display different fruit. For example, you might decide that you're tired of apples and oranges, and write this line of code a little later in the program:

fruitDisplay("mango", "banana");

You'd then see the following trace message:

mango banana

You didn't change the method in any way; all you did was change the arguments in the method call. When the arguments are sent to the method's function definition, they're copied into the parameters, which are highlighted here:

function fruitDisplay
  (
parameterOne:
String,  
parameterTwo
:String):void
{
  trace(parameterOne,  parameterTwo);
}

The parameters are just variables that can be used anywhere in the function definition. Because you're expecting them to accept string values, you've set their variable type as
String
the same way you would for any other variables.

The values of the two parameters contain whatever values are passed to them in the method call. That means that whenever the method uses the variable names
parameterOne
and
parameterTwo
, it will replace them with the values
apple
and
orange
or
mango
and
banana
'or whatever else you choose to send it. The beauty of this system is that you can reuse the method for many different related tasks without having to know the specific values of the variables.

Here's another example. Let's create a method that adds three numbers and displays the result. Here's what it might look like:

public function add(one:int,  two:int, three:int):void
{
  trace(one + two + three);
}

You can then use this method with a method call that might look like this:
add(4,10,6);

It will display this trace message.
20

Any three numbers you supply will give you a different result. I'm sure you can start to see how useful this can be.

Methods that return a value

You can also create methods that return something back to the main program. Let's say you've got a method called
add
that adds two numbers together. It could look like this:

public function add(numberOne:Number, numberTwo:Number):Number
{
  var result:Number = numberOne + numberTwo;
  
return
result;
}

The method adds the two parameters together and stores the result in a variable called
result
. The keyword
return
then sends the
result
value back to the main program. You could use this method in your main program like this:

anyVariable = add(23, 13);

The
add
method's
result
value will be copied into
anyVariable
. In this case,
anyVariable
will now equal 36.

To use a return value in a method, the method's function definition has to specify what type of value that method will return. In this example, it returns a
Number
, which you can see as the last item in the function definition, highlighted here:

public function add(numberOne:Number, numberTwo:Number):
Number

Methods can return any type of value back to the main program, like String or Sprite objects. Just make sure that you specify the correct return type in the function definition, just like in the previous code. (You'll find a working example of this system in the ReturningAValue project folder in the chapter's source files.)

Using the block method's arguments with the Collision class

As you've seen, if you want to stop the character object from walking through the box, you can write the method call so that it looks like this:

Collision.block(character, box);

It might work for this program, but what if you've got another game where you want to prevent a mouse from crossing a stream? Without changing anything in the method's function definition, you can just use this line of code:

Other books

Every Vow You Break by Julia Crouch
Voice of the Whirlwind by Walter Jon Williams
How to Be a Voice Actor by Alan Smithee
Wasted by Nicola Morgan
Angel's Blade by Erin M. Leaf