Detecting Collisions


How do you detect a collision between two objects? How do you decide what to do after a collision occurs?

There are two basic ways to detect collisions inside Flash. You can use the MovieClip.hitTest() method, which is useful in particular cases. As another option, you can rely on good old distance formulas, which are more flexible and not that hard to handle.

So, when do you use which method? With hitTest, you are testing either the intersection of a point with an object or the intersection of the bounding boxes of two movie clips. This is fine in a lot of cases, but what if you have two spheres that are colliding or a sphere colliding with the corner point of a box? Your collision detection won't be accurate using the hitTest method. In that case, you need to get down and dirty with some good old-fashioned calculations.

When do you use hitTest? It's great for simple collisions. It's also great for determining when your mouse is over a particular object. You actually used it already when you were setting up a custom cursor in Chapter 17, "Interface Techniques."

Start by exploring one way in which you can use the hitTest() method.

The hitTest method

The hitTest() method is new to Flash 5. It enables you to quickly and simply determine when two objects have intersected or overlapped . It's great for determining when a simple collision occurs or when your cursor is over a particular object.

You have the option of testing for just the bounding box of the target movie clip or you can test for the shape within the bounding box.

If you just want to test for the simple intersection of the bounding box of one object with another, you use this syntax:

 myMovie.hitTest(theOtherMovie); 

If the two objects intersect, the method returns a value of true. This is the method you can use to detect a simple collision.

If you want to get a little fancier and test for when you intersect an actual shape, you can specify the x and y coordinates of the hit area on the Stage and set the shapeFlag to true. You'll probably use this method most often when you're trying to determine if the movie clip or the mouse pointer are within a certain area. The syntax is as follows :

 myMovie.hitTest(x, y, shapeFlag); 

You've already used the second method in Chapter 17 when you created a custom cursor.

In the next exercise, you'll use the first hitTest() method to determine when a futuristic speeder intersects with an immovable wall.

Exercise 19.5 Using hitTest() to Detect a Collision

The rocket ship is controlled by key presses. Because you already know how to add those Actions, that part has been done for you.

  1. Open hittest.fla from the Chapter 19/Assets folder on the CD.

  2. The first thing you need to do is to give instance names to the two movie clips on the Stage. Select the speeder movie clip on the left, open the Instance panel (Window > Panels > Instance), and give it an instance name of Speeder. Give the wall movie clip an instance name of Wall . (See Figure 19.7.)

    Figure 19.7. Assign the speeder and wall movie clips instance names of Speeder and Wall, respectively, so that you can control them using ActionScript.

    graphics/19fig07.gif

  3. Select the Speeder and launch the Actions panel. The code in there should look very familiar. That is the same code, without any alteration, that you used to move the ball around the Stage with key presses in Exercise 17.2.

  4. You want to know when the movie clip you are in intersects with the wall movie clip. After the last if statement but before the curly brace that ends the on clip event, enter the following code:

     if(this.hittest(_root.wall)){     trace("I hit the wall.");  } 
  5. Test your movie. Make the speeder hit the wall by pressing the Right Arrow key.

    As soon as the speeder intersects with the wall, the Output window pops up with the message "I hit the wall." Because this is inside an onClipEvent(enterFrame), you'll keep seeing that same message until the speeder and the wall are no longer overlapping.

  6. Okay, that was fine, but what would you expect the speeder to do if it really hits the wall? Blow up, of course! As it happens, the speeder movie is a two-frame movie clip with an explosion in the second frame. This time, when the speeder hits the wall, stop it and blow it up. Figure 19.8 illustrates the speeder meeting its unfortunate end. Remove the trace statement and alter your code to match the following code:

     if(_root.speeder.hitTest(_root.wall)){     speedX = 0;      speedY = 0;      this.gotoAndStop(2);  } 
    Figure 19.8. By stopping the speeder and blowing it up, you add a little more interest to the file.

    graphics/19fig08.gif

  7. Test your movie. That was much more satisfactory, wasn't it?

That's one way to detect and react to a collision. However, what if you want to be able to bounce off of what you collide with? That's a little more complex.

Distance Calculations and Collisions

Another way to calculate collisions between objects is to do a little math. If you're not already familiar with the Pythagorean theorem, now is the time for a refresher course. Figure 19.9 shows a right triangle with its sides and two corner points labeled.

Figure 19.9. If you imagine a right triangle between the ball and the wall, with the hypotenuse being the distance between the two objects, you can start to set up some interesting calculations.

graphics/19fig09.gif

A and B are both sides of the triangle. C is the hypotenuse. Good old Pythagoras, a pre-Socratic Greek philosopher, came up with a theorem that states that C 2 = A 2 + B 2 .

After you have this equation, you can start to rearrange it to get all kinds of interesting information. Let's say that you want to find the distance between point p and point q. A would be equal to the X-axis value of q (q.x) minus the X-axis value of p (p.x) or:

A = (q.x p.x)

If that's true, then the formula for B would be:

B = (q.y p.y)

If you substitute those values into the first formula, you get this:

C 2 = (q.x p.x) 2 + (q.y p.y) 2

So to get C, which is the distance between p and q, all you have to do is take the square root of both sides of the equation. So what? Think about it for a second. If q and p are the center points of two objects on a collision course, in Flash, you can get those values from the _x and _y object properties. That means you can always figure out how far apart the two objects are. Now you're getting somewhere.

Take a look at the image on the right in Figure 19.9. You have a circle approaching a wall. The line between the wall and the circle represents the direction that the circle is moving (the wall is stationary). If you imagine a right triangle between these objects, you'd see something like the image on the left in Figure 19.9.

The formula that you've been looking at up to now gives you the distance between two points, in this case, the center points for the colliding objects. However, what you really want to know is when the edge of the circle impacts with the wall. That means that you'll have to take into account the radius (half the width) of the circle.

After the ball hits the wall, what happens? Assuming the ball isn't of sufficient mass to knock the wall down and that it is going fast enough not to be stopped by the wall, it's going to bounce. In fact, it's going to be reflected off the wall based on the angle of incidence, which is the angle at which it originally struck the wall. The Law of Reflection states that the angle of incidence is equal to the angle of reflection, as shown in Figure 19.10. Note that if the ball approaches the wall from the right and bounces , the sign of Y remains the same, but the sign of X reverses from negative to positive.

Figure 19.10. As the ball approaches from the right, the speed of X is negative and the speed of Y is positive. After the ball hits the wall, only the speed of X changes, and it becomes positive.

graphics/19fig10.gif

Those are the basics you need to know before you start writing your own code.

In the next exercise, you're going to approach the coding in a slightly different fashion. Because the code that you'll be developing is going to get moderately complex, it's a good idea to start thinking about how to make it as modular as possible.

What you'll be doing is creating a throwable ball again, but this time, you want to be able to bounce the ball off the sides of your movie. So, not only do you need to track information about the ball, but also you need to know something about the walls that are constraining it.

A Throwable Ball for Collisions

You've already set up a throwable ball. You know the basics for creating the ball. You'll need a button in a movie clip that will let you drag the ball. You'll also need to capture whether the ball is being dragged, and you'll need to update the speed variables when the ball isn't being dragged.

What needs to happen in the ball itself? Just like in the previous exercises, the ball needs to track the new and old X and Y positions if it is being dragged. If the ball has been released, you need to update the X and Y positions based on the current speed.

But what about those walls? Before you start working on setting up the walls, get the throwable ball set up and working. Instead of attaching the actions to the ball itself, you're going to attach the actions that actually control the ball's x and y positions to a controller clip inside the Ball movie clip. Why? Because you are going to set up a function to control what happens when you hit one of the walls on the first frame of the ball itself. The function controlling the behavior of the object has to be in the same timeline or attached to the object that it's controlling.

So, what to do about that enterFrame handler? You can just drop a controller clip into the Ball movie and assign the actions you would normally have in the enterFrame handler to the controller clip.

In the next exercise, you lay the groundwork for this exercise by building the throwable ball. You won't be adding in friction right now. We want to keep the equation simple.

Exercise 19.6 Setting Up the Throwable Ball in a New Way

In this section of the exercise, you use a slightly different method of setting up your throwable ball.

  1. Open collision.fla from the Chapter_19/Assets folder on the CD.

  2. Select frame 1 of the main timeline and initialize the SPEEDRATIO variable. Don't worry about friction for the moment. Enter the following code in the Actions panel:

     SPEEDRATIO = .3; 

    The Ball movie clip is already in a layer named Ball on the Stage.

  3. Open the Ball movie clip in Symbol-Editing mode. This is just a movie clip with an embedded button. The code, which has already been added to the button, looks exactly like the code you've used several times already:

     on(press){     this.startDrag();      dragging = true;  }  on(release){     this.stopDrag();      dragging = false;      speedX = (newX - oldX)*_root.SPEEDRATIO;      speedY = (newY - oldY)*_root.SPEEDRATIO;  } 

    Now you'll do something a little different. You're going to create a new empty movie clip symbol, which you'll center on top of the button in the Ball movie clip.

  4. Choose Insert > New Symbol. Name it Controller and click OK.

  5. Return to the Ball movie clip and add a new layer named Controller. Drag a copy of the Controller movie clip onto the Stage. Center it over the button.

  6. With the controller movie clip selected, launch the Actions panel. Most of the Actions you'll be adding here should be very familiar. There are two significant differences: Instead of referring to this, you'll be referring to _parent, and you'll be calling the checkWalls() function, which you haven't written yet.

    Tip

    One of the most frequent mistakes that you'll makeand it's easy to dois to accidentally put your object actions in a frame (or vice versa) instead of on the object itself. Always check the tab in the Actions panel. It says either Frame Actions or Object Actions.

  7. You need to use _parent in this case to refer to the movie clip (Ball) inside of which the controller exists. Add the following to the Actions list:

     onClipEvent(enterFrame) {     if (!_parent.dragging) {         _parent._x += _parent.speedX;          _parent._y += _parent.speedY;          _parent.checkWalls();      }      _parent.oldX = _parent.newX;      _parent.oldY = _parent.newY;      _parent.newX = _parent._x;      _parent.newY = _parent._y;  } 
  8. The only thing that is really new here is the call to the checkWalls() function. You'll be writing that next. For now, test your movie. You should be able to fling the ball around.

Locating Boundaries

If you're going to bounce the ball off of the walls, you need to know where the walls are, right? You'll need to provide Flash with the minimum and maximum X and Y values for the walls. These values are going to be constants; they won't change, so why not start by setting them up on the main timeline?

Setting Up Your Constants

The logical place to start is to think about what constant values you'll need to track. Well, you need to know where the walls are, right? The first thing you'll do is set four variables that will contain the minimum and maximum X and Y values for the walls:

  • WALLLEFT. The minimum X value.

  • WALLRIGHT. The maximum X value.

  • WALLTOP. The minimum Y value.

  • WALLBOTTOM. The maximum Y value.

These values won't change, so a sensible place to initialize these variables would be on the first frame of the main timeline.

Exercise 19.7 Setting Up Constants

For this exercise, the assumption is that you are working with the default movie size of 550 pixels x 400 pixels.

  1. Select frame 1 of the main timeline and after the line where you initialized SPEEDRATIO, enter the following in the Actions panel:

     WALLLEFT = 0;  WALLRIGHT = 550;  WALLTOP = 0;  WALLBOTTOM = 400; 

    Tip

    You might be wondering why the variable names in this case are in all capital letters . It's because they are constants, which are values that never change. Using a standard to denote constants makes them easier to find in your code so that you don't inadvertently change them. This is definitely a "do as I say, not as I do" kind of tip. I have to really think about it to make sure I do this.

  2. Save your movie.

Now that you've established where your walls are, it's time to start thinking about how to handle the collisions. Here's where all that nasty math stuff comes in. Actually, it's not all that bad.

Figuring Out the Distance Calculations

Now is the time to think about what information you know and what information you need. You're already collecting information about how fast, and in what direction, the ball is moving. You know how to determine the X and Y coordinates of the ball for any given time. In addition, you know where the walls are. You can start by working with the left wall.

You want to know when the ball intersects with the left wall, but you want to know when the edge of the ball, not the center, intersects with the wall. That means that you're going to need to account for half of the ball's width, or radius, in the equation. In fact, depending on whether you're moving in a positive or negative direction, you'll need to either add or subtract the value of the radius. Figure 19.11 (wall collision.fla) illustrates this concept.

Figure 19.11. The combined position of the wall and the radius of the ball determine when a collision occurs.

graphics/19fig11.gif

So, you should see your conditional statement developing here: If this._x is less than the wall plus the radius, you need to do something.

What are you going to do? Well, for one thing, you need to change the direction that the ball is moving. If you remember the discussion earlier, the angle at which the ball hits the wall is known as its angle of incidence . The angle of reflection , the angle at which the ball leaves the wall, is the opposite of the angle of incidence. Don't panic; you don't have to start calculating angles. You just have to reverse either speedX or speedY, depending on which wall you're hitting .

You also can give the ball a little extra snap to its bounce by resetting its position before you reverse the direction. Why would you want to do this? While Flash is constantly updating the position of the ball, the ball still can get ahead of the calculations and go past the wall slightly. By immediately resetting the position of the ball so that its edge is on the proper side of the collision boundary, you keep the illusion of the bounce effect crisp and clean.

In the next exercise, you'll set up the function with conditional statements to determine whether the ball hit a wall, and then make it bounce.

Exercise 19.8 Bouncing off the Wall

In this exercise, you'll create the checkWall() function that determines whether the ball hit a wall and that controls what happens to it when it does.

  1. The function that you create will exist inside the Ball movie clip itself. Double-click the Ball movie clip in the Library to open it in Symbol-Editing mode and add a new layer named Functions.

  2. With frame 1 of the Function layer selected, open the Actions panel and declare your new function by entering the following code:

     function checkWalls() { } 
  3. Start by setting up the left wall. Enter the following code between the asterisks :

     function checkWalls() { //*****************************************************      if (this._x < (_root.WALLLEFT + radius)) {     //reset the position of the ball inside the bounds      this._x = ((_root.WALLLEFT + radius) - this._x) + _root.WALLLEFT      + radius;      //Reverse the speed      speedX *= -1;      }  //*****************************************************  } 
  4. You're probably wondering where the value of the radius variable is coming from. The answer is that right now, it doesn't exist. You have to add that in. It's acceptable to add it after the function because this function is called repeatedly as part of the controller's onClipEvent(enterFrame). The ball will never hit the wall before the radius has been determined. If you're really worried about it, you can put the radius calculation before the function. It doesn't matter. After the last curly brace, enter the following code:

     //determine the radius of the ball  radius = this._width/2; 
  5. Now is a good time to test your movie and make sure that you've entered the equations correctly. Try flinging the ball against the left wall. It should have a nice springy bounce.

  6. Okay, now it's time to add the rest of the walls. Copy the first if statement and paste it just above the last curly brace, but still inside the function. Make the following changes:

    • Subtract the radius instead of adding it (three occurrences)

    • Change WALLLEFT to WALLRIGHT (three occurrences)

    • Change the < to >

      Your code up to this point should look like this:

       //create the function  function checkWalls() {     if (this._x < (_root.WALLLEFT + radius)) {     //reset the position of the ball inside the bounds      this._x = ((_root.WALLLEFT + radius) - this._x) + _root.WALLLEFT      + radius;      //Reverse the speed      speedX *= -1;      }      if (this._x > (_root.WALLRIGHT - radius)) {     //reset the position of the ball inside the bounds      this._x = ((_root.WALLRIGHT - radius) - this._x) + _root.WALL      RIGHT - radius;      //Reverse the speed      speedX *= -1;      }  }  //determine the radius of the ball  radius = this._width/2; 
  7. Next you can copy both if statements and paste them just above the last curly brace. Make the following changes:

    • Change each occurrence of x to y (don't make me say it; do it only for the last two if statements!).

    • Change WALLLEFT to WALLTOP (three occurrences).

    • Change WALLRIGHT to WALLBOTTOM (three occurrences).

      Your completed code should look like this:

       //create the function  function checkWalls() {     if (this._x < (_root.WALLLEFT + radius)) {     //reset the position of the ball inside the bounds      this._x = ((_root.WALLLEFT + radius) - this._x) + _root.WALLLEFT      + radius;      //Reverse the speed      speedX *= -1;      }      if (this._x > (_root.WALLRIGHT - radius)) {     //reset the position of the ball inside the bounds      this._x = ((_root.WALLRIGHT - radius) - this._x) + _root.WALL      RIGHT - radius;      //Reverse the speed      speedX *= -1;      }      if (this._y < (_root.WALLTOP + radius)) {     //reset the position of the ball inside the bounds      this._y = ((_root.WALLTOP + radius) - this._y) + _root.WALLTOP      + radius;      //Reverse the speed      speedY *= -1;      }      if (this._y > (_root.WALLBOTTOM - radius)) {     //reset the position of the ball inside the bounds      this._y = ((_root.WALLBOTTOM - radius) - this._y) + _root.WALL      BOTTOM - radius;      //Reverse the speed      speedY *= -1;      }  }  //determine the radius of the ball  radius = this._width/2; 
  8. Save and test your file. The ball should bounce, with believable angles, off all four walls.

Okay, that's pretty cool. However, what if you want obstacles inside the walls off of which the ball can bounce? That adds yet another layer of complexity.

Adding Obstacles into the Equation

Now the real fun starts. You're going to add some rectangular obstacles to the Stage for the ball to bounce off. However, you're not going to use your drawing tools to place them on the Stage. You're going to create a Box object that you can replicate as many times as you want.

Boxes aren't complex objects. The only parameters you need to keep track of are the left side, the right side, the top, and the bottom. How hard can that be? Well, you need to think about how you plan to get that box drawn on the Stage. The most obvious way to do this is to use attachMovie(). Thus, you'll need to create a Box movie clip in the Library and set its linkage.

Creating a Box

After your Box movie clip is ready to go, you're ready to write the function to create your object. Start by creating a Box movie clip.

Exercise 19.9 Creating the Box Movie Clip

You're going to create a simple box and set up its linkage properties.

  1. You can continue working with the file from the last exercise or you can open collisionWithBox.fla in the Chapter_19/Assets folder.

  2. From the main menu, select Insert > New Symbol. Make it a movie clip, give it a name of Box, and click OK.

  3. Select the Rectangle tool and draw a rectangle on the Stage. You can choose to fill the rectangle; it doesn't matter.

  4. Select the rectangle you just drew and use the Info panel (Window > Panels > Instance) to resize it to 100x100 pixels. Use the Info panel to reposition the rectangle so that its upper-left corner is centered on the Registration point.

  5. Open the Library and select the Box movie clip. Right or Control-click the Box movie clip and select Linkage from the Options list. Change the following settings:

    Export this Symbol: selected

    Identifier: box

  6. Click OK.

Next you're going to create the function that creates the Box object. The Box object will take four parameters:

  • left. The left wall (minimum X) of the box.

  • right. The right wall (maximum X) of the box.

  • top. The top (minimum Y) of the box.

  • bottom. The bottom (maximum Y) of the box.

It will use these parameters and a variable named DEPTH to attach the new Box objects to the Stage and determine their width and height.

Exercise 19.10 Creating the Box Object

You're going to create the function that builds your Box object on the main timeline.

  1. Make sure you are on the main timeline and select frame 1 in the Actions layer. Your code currently looks like this:

     SPEEDRATIO = .3;  WALLLEFT = 0;  WALLRIGHT = 550;  WALLTOP = 0;  WALLBOTTOM = 400; 

    Nothing too earth-shattering here. Unlike previous exercises, you'll be inserting the next block of code before the code you've already entered. Why? As a standard practice, I place all functions at the top of the code stack. It makes them easier to find and edit later.

  2. Add some blank lines before the first line of code and enter the following code to begin the function that builds the Box object:

     function Box (left, top, right, bottom) { } 

    Next you need to take those parameters being passed in and do something with them.

  3. Pass the parameters into variables that are local to a single instance of the box. Add the following code between the curly braces of the function:

     this.left = left;  this.top = top;  this.right = right;  this.bottom = bottom; 
  4. So far, so good. Now you need to set up the attachMovie method. Before the last curly brace, add the following code:

     _root.attachMovie("box", "box"+_root.DEPTH, _root.DEPTH);  this.mc = _root["box"+_root.DEPTH];  ++_root.DEPTH; 

    Take a look at the second line of code you just entered. What's going on there? You are passing the movie clip you just created, by reference, into this.mc. Because these are attached movies, you need a way to reference their properties.

  5. You need to size the box you're attaching to the Stage and set up the DEPTH variable. To size the box, you have to tell it where its left side and top are. From there, you just need the width and the height. Add the following code before the final curly brace:

     this.mc._x = this.left;  this.mc._y = this.top;  this.mc._width = this.right - this.left;  this.mc._height = this.bottom - this.top; 
  6. Just after the last curly brace, add this code:

     DEPTH = 0; 
  7. You might be thinking you're done at this point, but you're not. You haven't actually created a box yet. After the very last line of code, enter the following:

     BOXES = new Array();  BOXES[0] = new Box (100, 100, 200,300); 

    The cool thing about this is you can add as many boxes to the Stage as you want, but you can get it working with just one first. Now your code should look like this:

     function Box (left, top, right, bottom) {     this.left = left;      this.top = top;      this.right = right;      this.bottom = bottom;      _root.attachMovie("box", "boxes"+_root.DEPTH, _root.DEPTH);      this.mc = _root["box"+_root.DEPTH];      ++_root.DEPTH;      this.mc._x = this.left;      this.mc._y = this.top;      this.mc._width = this.right - this.left;      this.mc._height = this.bottom - this.top;  }  DEPTH = 0;  SPEEDRATIO = .3;  WALLLEFT = 0;  WALLRIGHT = 550;  WALLTOP = 0;  WALLBOTTOM = 400;  BOXES = new Array();  BOXES[0] = new Box (100, 100, 200,300); 
  8. Save and test your movie. (See Figure 19.12.) If you're having problems, check your code against the preceding code.

    Figure 19.12. Your newly created Box object uses the attachMovie() method to attach the new instance of the Box movie clip to the movie.

    graphics/19fig12.gif

Okay, your box is there, but it doesn't make for much of an obstacle . You guessed it. You have to write another function to check for box collisions.

Checking for Box Collisions

Checking for collisions with boxes on the Stage is a little more complex than checking for walls. You now have to keep track of where the ball was versus where it is now in different coordinate spaces. For example, the pseudo-code to check for a ball approaching the box on the Stage from the left side of the screen would look something like this:

 If the old x position is less than the left wall, AND the current x  position is greater than the left wall, AND the current y position is IN  BETWEEN the top and bottom walls, you've had a collision with the left  wall  reset the x position of the ball and reverse the speed of X. 

So what does that look like in reality? The actual conditional statement looks like this:

 if (oldX < current.left && this._x > current.left && this._y >  current.top && this._y < current.bottom){     this._x = current.left - this._x + current.left;      speedX *= -1;  } 

The code inside the if statement won't run unless all the conditions being tested are true. So now that you know the basics, it's time to start writing the function.

Exercise 19.11 Creating the checkBoxes() Function

The checkBoxes() function is going to exist in the same frame of the checkWalls() function inside the Ball movie clip.

  1. Double-click the Ball movie clip to open it in Symbol-Editing mode. Launch the Actions panel and select frame 1 of the Functions layer.

  2. Add some space after the last curly brace and before you set the radius variable.

  3. Set up the shell for the function by entering the following code:

     function checkBoxes() { } 
  4. Even though you've only set up one box, you know that you can set up more than that. Thus, create a loop, and the appropriate variables, that will account for all the possible boxes. You can do this by entering the following code:

     for (var i=0; i<_root.BOXES.length; ++i){     var current = new Object();      current.left = _root.BOXES[i].left - radius;      current.right = _root.BOXES[i].right + radius;      current.top = _root.BOXES[i].top - radius;      current.bottom = _root.BOXES[i].bottom + radius;  } 
  5. Set up the check for the collision with the left wall. After that one's working, it's all cut and paste and minor changes.

  6. You've already had a look at the code you need to enter, so enter the following code between the curly braces of the checkboxes() function:

     if (oldX < current.left && this._x > current.left && this._y >  current.top && this._y < current.bottom){     this._x = current.left - this._x + current.left;      speedX *= -1;  } 
  7. You're not ready to test your movie yet. You haven't called the function. Still in the Ball movie clip, you need to select the controller movie clip and add the following code just after the call to the checkWalls() function in the onClipEvent(enterFrame) handler:

     _parent.checkBoxes(); 
  8. Use the conditional (if) statement you just created as the template for the other three conditionals you'll need. You still need to check for the right wall, the top of the box, and the bottom of the box. Go ahead and try to create those on your own. If you need a cheat sheet, check Listing 19.2.

  9. After you have your code set up, save and test your movie. Check your syntax before you test.

  10. After you're satisfied with what you have, play around with setting up additional boxes on the Stage. The code is really bulletproof; you can have a lot of fun. (See Figure 19.13.) Here's a sample pattern of boxes you can play with:

     BOXES[0] = new Box (80, 80, 160, 160);  BOXES[1] = new Box (240, 80, 320, 160);  BOXES[2] = new Box (400, 80, 480, 160);  BOXES[3] = new Box (160, 240, 240, 320);  BOXES[4] = new Box (320, 240, 400, 320); 
Figure 19.13. Because the box is an object, you can attach as many instances of it as you like to your movie by adding new Box objects to the Boxes array.

graphics/19fig13.gif

Listing 19.2 The Completed ActionScript for the checkBoxes Function
 function checkBoxes(){     for (var i=0; i<_root.BOXES.length; ++i){         var current = new Object();          current.left = _root.BOXES[i].left - radius;          current.right = _root.BOXES[i].right + radius;          current.top = _root.BOXES[i].top - radius;          current.bottom = _root.BOXES[i].bottom + radius;          if (oldX < current.left && this._x > current.left && this._y          > current.top && this._y < current.bottom){             this._x = current.left - this._x + current.left;              speedX *= -1;          }          if (oldX > current.right && this._x < current.right && this._y          > current.top && this._y < current.bottom){             this._x = current.right - this._x + current.right;              speedX *= -1;          }          if (oldY < current.top && this._y > current.top && this._x >          current.left && this._x < current.right){             this._y = current.top - this._y + current.top;              speedY *= -1;          }          if (oldY > current.bottom && this._y < current.bottom &&          this._x > current.left && this._x < current.right){             this._y = current.bottom - this._y + current.bottom;              speedY *= -1;          }      }  } 


Inside Flash
Inside Flash MX (2nd Edition) (Inside (New Riders))
ISBN: 0735712549
EAN: 2147483647
Year: 2005
Pages: 257
Authors: Jody Keating

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net