Introduction:
The goal of this tutorial is to demonstrate an efficient way to detect collisions between multiple instances two movie clips.
When you're finished with this tutorial you will understand an efficient method for detecting collisions between multiple instances of one movie clip and multiple instances of another movie clip, and be able to apply that knowledge.
What you'll need to know to get the most out of this tutorial:
You should be comfortable using basic program flow (if statements and loops), as well as hitTest, attachMovie, and arrays. I'll be getting right to the point, so it's important you are up to speed on these things.
Let's get started.
What I'm going to walk you through in this tutorial is the creation of two movie clip symbols (a simple circle image and a square, we'll call these movie clips ball and box from here on out), randomly placing instances of the box movieclip along the x coordinate at the bottom of the screen, and randomly placing instances of the ball movieclip along the x coordinate at the top of the screen. The boxes will travel upward along whatever x coordinate they are placed, and the balls will travel downward along whatever x coordinate they are placed. We will then add collision detection code and remove any instances that collide.
First thing we'll do is create our movieclip symbols, in a new flash project create a movieclip symbol (add it directly do the library, don't place it on the canvas then convert to symbol), of a box and name it "box", don't forget to right click on the symbol in the library panel afterwards and select Linkage --> Export and use the name "box" again. Do the same thing for ball. Try to make them about an inch in width/diameter (if they are too small the chances of them colliding will be poor, if they are too big the chances of them not colliding will be poor, we want a good balance.)
Now that you have the 2 movieclip symbols right click on frame 10 in the main timeline and add a keyframe, then do the same for frame 1. Frame 1 will just be variable declarations, so we'll do that last once we know what all of the variables we'll be using are. In Frame 10 right click, select the actions panel, and put it in expert mode.
First code we'll add is to create the loop, nothing new for any of you I'm sure
gotoAndPlay(9);
Next we'll set up our method for attaching instances of each MovieClip to the approriate y positions (top/bottom) and randomly place them on the x coordinate.
delay--;
if(delay <= 0) {
delay = 30;
x++;
_root.attachMovie("ball", "ball"+x, x+100);
this["ball"+x]._x = random(200) + 150;
this["ball"+x]._y = 0;
numBalls = ballsOnScreen.push("ball"+x);
_root.attachMovie("box", "box"+x, x+150);
this["box"+x]._x = random(200) +150;
this["box"+x]._y = 400;
numBoxes = boxesOnScreen.push("box"+x);
}
Code Explanation
Each time the code in this frame runs we'll decrement delay by one, delay is what we'll use to time how often a new instance is placed. When delay reaches 0 it's time to place another instance of each movieclip on the screen. We have to reset delay to 30 so the timer starts over again next time this frames code is run. Increment x each time a new set of instances is dropped so each instance used has a unique name, "ball"+x or "box"+x. Next, attach an instance of the ball movieclip, giving it a random x coordinate between 150 and 349, and a y coordinate at 0 so it starts at the top of the screen. ballsOnScreen is an array we'll use to keep track of the ball instances that are currently attached, so when a new ball instance is created we need to add it's name to the array, and of course when one is removed we'll need to remove it from the array. Last, do the same exact thing for the boxes, except place them at the bottom of the screen, in this case that's y=400.
So now we have instances of the ball and box movieclips placed in the appropriate locations on screen. Next let's start adding the code to make them move.
for (i in ballsOnScreen) {
this[ballsOnScreen[i]]._y += 7;
if(this[ballsOnScreen[i]]._y> 400) {
this[ballsOnScreen[i]].removeMovieClip();
ballsOnScreen.splice(i, 1);
}
}
Code Explanation
For..in loop cycles through the ballsOnScreen array, each ball instance in the array is moved 7 pixels down the y coordinate. Then an if statement checks to see if any of the ball instances have gone off the screen, and removes instances that have by removeMovieClip(), and we also remove that instance name from the ballsOnScreen array so it is kept up to date one what ball instances are currently on screen.
Pretty easy, we're going to do the same thing for the boxesOnScreen array, but we'll also add our collision detection to this for loop.
for (j in boxesOnScreen) {
this[boxesOnScreen[j]]._y -= 7;
if(this[boxesOnScreen[j]]._y <0) {
this[boxesOnScreen[j]].removeMovieClip();
boxesOnScreen.splice(j, 1);
}
for(k in ballsOnScreen) {
if (this[boxesOnScreen[j]].hitTest(this[ballsOnScreen[k]])) {
this[boxesOnScreen[j]].removeMovieClip();
boxesOnScreen.splice(j, 1);
this[ballsOnScreen[k]].removeMovieClip();
ballsOnScreen.splice(k, 1);
}
}
}
Code Explanation
Up to the second for..loop everything is the same as the last code snippet that made the ball move, here we are just making the box move and checking if it has gone off the screen. In the second for..loop we'll run our hitTests between each box instance in the boxesOnScreen array and each ball instance in the ballsOnScreen array. If any of the instances collide we remove that instance using removeMovieClip, and we update the arrays.
We are practically done now! All we have left to do is the variable initiation in Frame 1, so go to frame 1, and insert the following actionscript there.
delay = 6; //set to 6 instead of 30 to prevent a long delay upon loading the flash program. ballsOnScreen = new Array(); boxesOnScreen = new Array(); numBalls = 0; numBoxes = 0; x = 1;
We're done!
discuss this topic to forum
