The next action I want
to show you is the movieclip method hitTest().
hitTest is used to detect whether or
not 2 objects are touching each other.
Paste these actions underneath all the
others
this.onEnterFrame
= function() {
if (box_mc.hitTest(ball_mc._x, ball_mc._y)) {
trace("hit");
}
};
Test the movie and move the shapes around
until they are touching. You will see
that "hit" is displayed in
the output window. This time the enterFrame
action is being applied to _root (which
is refered to as "this" because
we are placing the action on a frame
in _root). _root is just like any regular
movieclip, and has has all the movieclip
methods available to it (eg attachMovie
- which we will get to soon). So, every
frame flash checks to see if the 2 shapes
are touching and if they are it displays
our message in the output window. Now
lets duplicate the ball_mc whenever the
2 shapes touch. To do this we will use
the duplicateMovieClip() method. Replace
the actions just above with this -
i=0;
this.onEnterFrame = function() {
if (box_mc.hitTest(ball_mc._x, ball_mc._y)) {
newBall=ball_mc.duplicateMovieClip("ballCopy"+i,i++);
newBall._x=ball_mc._x;
newBall._y=ball_mc._y;
}
};
Test your movie and move the shapes
around until they touch. You will see
that a copy of the ball_mc gets created
and placed on the stage where the collision
occured. Let's go through that code.
First we initialise a variable (i) and
set it to 0. Next we start our enterFrame
action and run the hitTest. If the hitTest
returns true, then we
duplicate the
ball_mc
give the copy an instance name of "ballCopy" plus
whatever i is equal to at the time (eg
ballCopy0, ballCopy1 etc)
place the copy at a depth of whatever
i is equal to and then increase the value
of i by 1 (i++)
We then place the new copy at the same
x and y position as the original ball_mc.
For more information on duplicateMovieClip
go here and to learn the difference between
levels, layers and "depth" go
here. It's important to note that only
one object can exist in a depth at a
time. We can use this to limit the number
of copies of the ball that can be shown
on the stage at once. Change the code
just above to this
i=0;
this.onEnterFrame = function() {
if (box_mc.hitTest(ball_mc._x, ball_mc._y)) {
newBall=ball_mc.duplicateMovieClip("ballCopy"+i,i++);
newBall._x=ball_mc._x;
newBall._y=ball_mc._y;
if(i>10){
i=0;
}
}
};
Test your movie and you will see that
once more than 12 copies of the ball
have been made then the original copies
start getting replaced. This is because
when i becomes greater than 10 we are
setting it back to 0
if(i>10){
i=0;
}
which means that the next copy will
be placed at a depth of 0 and will therefore
replace the first copy that was made.
That's duplicateMovieClip(). Now let's
look attachMovie which is similat except
it pulls a symbol from the library and
places it on the stage. Open your library
and click on the little blue + sign down
the bottom left. This will create a new
Symbol which should be a movieclip named "arrow_mc".
Click OK and you should be automatically
taken inside the new mc (movieclip).
Use the pen tool to draw an arrow point
up. When you are finished, select the
arrow and use the align panel to move
it to the center of the Symbol (which
is identified by the crosshair). Now
click once on the arrow_mc in the library
and from the drop down menu up the top
right of the library select "linkage".
In the window that opens, click on the "Export
for Actionscript" box. Leave the
Identifer as "arrow_mc" and
leave the "Export in first frame" box
checked. Click OK. What this does is
ensures that our arrow is included in
in the swf when we publish our movie
(by default, Flash removes any items
from the library that are not manually
placed on the stage - exporting for actionscript
stops our symbol being removed so that
we can place it on the stage using actionscript).
Let's place the arrow on the stage using
the attachMovie method. Change the moveStuff
function to this :
function moveStuff() {
arrowDepth=50;
arrowX=550;
arrowY=350;
if (Key.isDown(Key.LEFT)) {
this._x -= this.speed;
_root.attachMovie("arrow_mc","arrowMC",arrowDepth);
arrowMC._x=arrowX;
arrowMC._y=arrowY;
arrowMC._rotation=-90;
}
if (Key.isDown(Key.RIGHT)) {
this._x += this.speed;
_root.attachMovie("arrow_mc","arrowMC",arrowDepth);
arrowMC._x=arrowX;
arrowMC._y=arrowY;
arrowMC._rotation=90;
}
if (Key.isDown(Key.UP)) {
this._y -= this.speed;
_root.attachMovie("arrow_mc","arrowMC",arrowDepth);
arrowMC._x=arrowX;
arrowMC._y=arrowY;
arrowMC._rotation=0;
}
if (Key.isDown(Key.DOWN)) {
this._y += this.speed;
_root.attachMovie("arrow_mc","arrowMC",arrowDepth);
arrowMC._x=arrowX;
arrowMC._y=arrowY;
arrowMC._rotation=180;
}
if (this._x>StageWidth+(this._width/2)) {
this._x = 0-(this._width/2);
}
if (this._x<0-(this._width/2)) {
this._x = StageWidth+(this._width/2);
}
if (this._y>StageHeight+(this._height/2)) {
this._y = 0-(this._height/2);
}
if (this._y<0-(this._height/2)) {
this._y = StageHeight+(this._height/2);
}
}
Most of that is the same as before but
you will see that at the top we declare
a few variables
arrowDepth=50;
arrowX=550;
arrowY=350;
which store the x and y positions of
where we want to place the arrow and
also the depth in which the arrow will
be placed into. A little further down
you will see
_root.attachMovie("arrow_mc","arrowMC",arrowDepth);
arrowMC._x=arrowX;
arrowMC._y=arrowY;
arrowMC._rotation=-90;
which attaches a copy of the arrow_mc
symbol (remember, arrow_mc is the linkage
name of our arrow symbol) to _root, gives
it an instance name of arrowMC and places
it in a depth of whatever our arrowDepth
variable is set to (in this case, 50).
We then position the arrowMC on the stage
and rotate it to reflect which arrow
key has been pressed. Each time another
arrow is attached, it replaces the previous
one as it is being placed in the same
depth. Test your movie and you will see
that it is working fine except the arrow
stays there even when no arrow button
is being pressed. What we need to do
is remove the arrow when a keyUp event
occurs - lets do that now.
I also want to show you the getAscii()
method in action so let's do that at
the same time. Change the watchKeyboard
code to this:
watchKeyboard
= new Object();
watchKeyBoard.onKeyDown = function() {
if (Key.getAscii() == 32) {
box_mc._xscale=box_mc._yscale-=5;
}
};
watchKeyBoard.onKeyUp=function(){
arrowMC.removeMovieClip();
}
Key.addListener(watchKeyBoard);
Test your movie and press the arrow
keys and the spacebar a few times. You
will see that our arrow gets removed
whenever a keyUp event occurs. We do
this with the removeMovieClip() method.
Note - removeMovieClip can only be used
to remove clips that were placed on the
dynamically (ie with attachMovie or duplicateMovieClip).
You will also see that our box gets
smaller when you hit the spacebar. This
part of the code takes care of that
if (Key.getAscii()
== 32) {
box_mc._xscale=box_mc._yscale-=5;
}
so when a key is pressed we check the
ASCII value of the key. If the value
is 32 (the ASCII value of the spacebar),
then we reduce the xscale and yscale
of the box_mc by 5%.
That'll do for attachMovie.
|