Read Foundation Game Design with ActionScript 3.0, Second Edition Online
Authors: Rex van der Spuy
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 theenterFrameHandler
. 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 thecharacter
andbox
objects to theCollision
class'sblock
method. TheCollision.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 theCollision
class is in the same src folder as theBlockingMovement
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'sMath
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 aString
variable that's inside theCollision
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 thebox
first, and then thecharacter
, 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 theCollision
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. LikeMath.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!
TheCollision.block
method uses two arguments. They can be any Sprite objects in your game. In the previous example, they were thecharacter
andbox
objects.
Collision.block(
character, box
);
These arguments are sent to the method's parameters in the function definition (which you'll find in theCollision
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 methodfruitDisplay
. 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 thefruitDisplay
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 asString
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 namesparameterOne
andparameterTwo
, it will replace them with the valuesapple
andorange
ormango
andbanana
'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.
You can also create methods that return something back to the main program. Let's say you've got a method calledadd
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 calledresult
. The keywordreturn
then sends theresult
value back to the main program. You could use this method in your main program like this:
anyVariable = add(23, 13);
Theadd
method'sresult
value will be copied intoanyVariable
. 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 aNumber
, 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.)
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: