|
TUTORIAL: Building games in Flash 5
Part 3: Enemies and collisions.
Author:
David Doull
Date: 11/04/01
Download source files: tut3.zip
Step 3: Collision
detection
We now have one key thing to do to turn
this into a game. We need to add in collision detection.
We want to detect when a laser hits an
enemy spaceship and consequently make the spaceship explode
and disappear. Similarly we want to detect when an enemy spaceship
collides with the players spaceship, at which point the game
will end.
So how do we detect collisions in flash?
The spaceship, enemies and lasers are
all movieclips. So we need a simple way to detect collisions
between movieclips.
The answer is hitTest.
Flash 5 introduced a method called hitTest
which allows us to detect collisions between two movie clips
and its really easy to use.
If you have two movieclips with instance
names movie1 and movie2
then the code to detect a collision would be movie1.hitTest(movie2).
A few words about hitTest
There are actually two different ways
you can use hitTest.
Usage 1: You can use it
to detect the collision (or overlap) between two movie clips
using the syntax: movie1.hitTest(movie2)
This will be true if the bounding
boxes of the two movieclips are overlapping.
So
what's a bounding box? Think of it as an invisible rectangle
drawn around the edge of a movie clip. If you click on a movie
clip in flash you will see the bounding box highlighted (see
right). hitTest detects
when the bounding boxes of two movie clips overlap, not when
the graphics overlap.
The
image to the left shows the bounding boxes for the spaceship
and the enemy. The two bounding boxes are overlapping so if
we used hitTest to check for a collision it would be true
even though the actual graphics don't overlap.
This isn't really a problem because the
spaceship graphics mostly fill the bounding box and because
the game moves so fast that players are unlikely to notice
this lack of precision.
Usage 2:
You can use it to detect a collision between a movie clip
and a point. The syntax is movie1.hitTest(x,
y, shapeFlag) where x and y are the co-ordinates of
the point and shapeFlag is either true or false depending
of whether you want to detect a collision between the movie
clips graphic (true) or the movie clips bounding box (false).
This usage of hitTest can give you a more precise collision
detection but its not used much in games because we generally
want to detect the collision between two movie clips not a
point and a movie clip.
Using hitTest in our game
Let's write the code to detect the collision
between the lasers and the enemies.
Open up the actions window for the laser
(select the laser and choose Window > Actions).
The code for the lasers enterFrame onClipEvent
should currently be:
onClipEvent (enterFrame) {
this._x+=laserMoveSpeed;
if (this._x>600){
this.removeMovieClip();
}
}
between the two curly end brackets type
the following code:
for (i=1; i<=_root.numEnemy; i++){
if (this.hitTest( _root["enemy"+i])){
_root.score+=100;
_root["enemy"+i].gotoAndPlay( 2 );
}
}
This code checks to see if this laser
movie clip is colliding with any of the enemy spaceships.
It uses a for loop to check if this laser is colliding with
each one of the enemy movie clips. If this is true it increases
the score by 100 and tells the associated enemy to goto and
play its frame 2.
The first line sets up a for
loop. As explained before a for
loop is a loop that repeats the code between its {}'s
a set number of times. In this case the loop will repeat three
times (as the value for _root.numEnemy is 3), and each time
it repeats it will increase the variable i
by one.
The second line is an if test. It checks
to see if this movie clip
(i.e.: the laser) is colliding with a movie clip specified
by the code _root["enemy'+i]
As explained back in tutorial one, this is array style referencing
for a movie clip. So when i
is equal to 1 then _root.["enemy'+i]
will evaluate to _root.enemy1
when i is 2 it will evaluate
to _root.enemy2 and so on.
If the hitTest is true then the next
two lines are run. These lines actually deal with some things
we will set up in the next step.
The line _root.score+=100;
increases a variable called score by 100. We haven't set up
this variable yet, we will do it in the next step and you
will see how easy it is to add a score to your game.
The other line _root["enemy"+i].gotoAndPlay(2);
tells the enemy that has collided with the laser, to
goto its frame 2. What we are going to do is put an explosion
animation in the enemy movie clip at frame 2.
The original laser - tidying things up
Now, before we leave the laser we are
going to do one more thing.
You may have noticed that the original laser movie clip (called
laser) is never removed. This is because the removeMovieClip
method only applies to movie clips that were created using
duplicateMovieClip. As the original laser was drawn by us
it cant be removed using removeMovieClip and this is a good
thing! If we removed the original laser we wouldn't be able
to duplicate new lasers from the original.
So what happens to the original laser?
We'll it cant be removed so it keeps moving to the right for
ever. That seems a bit untidy, so we are going to add in an
if statement which ensures that the original laser does nothing
and only the duplicates fly across the screen and collide
with enemies.
Exactly under the line onClipEvent (enterFrame)
{ add the code:
if (this._name<>"laser"){
and after the second to last end curly bracket } put another
end curly bracket }.
This just adds in an if statement that makes the movie clip
check which version of the laser it is. If its the original
version (the one with the name laser)
then the code to move, remove and check for collisions wont
be run.
NB:
you might not have seen <>
before. It means NOT EQUAL TO, so our if statement will run
the code if the lasers name is not equal to laser.
In other words the code will be run if the laser is called
something other than laser,
such as laser2 or laser3.
You can get a source file with all the
code and graphics up to this point here : tutorial3_partc.fla
Next >>
|