interactive scripting - CGR C/092 - fall 2004
Philip van Allen - v a n a l l e n @ a r t c e n t e r . e d u

room 142, Monday 4:00pm-7:00pm
all materials on this web site © copyright 2004, Philip van Allen
 
week 08c - proj 3, keyboard, collision detection, move clips

collision detection : 


find out when objects run into each other

Reference: Textbook pgs. 666-668

A common interaction design task is to determine when to objects on the screen have collided. For example, did the user drag and drop a movieClip onto the right place? Or did a rocket hit the enemy ship? This is called collision detection, and Flash has a built-in movieClip method to check for collisions. It's called hitTest().

There are two forms of hitTest(). The first checks a movieClip against an X,Y point on the stage and returns TRUE if the point is inside the movieClip (FALSE if not). The other form compares one movieClip to another movieClip, and returns TRUE if they overlap.



movieClip vs. point : 

check a movieClip against a point on the stage

This technique determines if a specified point is inside the bounds of a movieClip. In one case, the check is for the bounding rectangel that contains the graphics of the clip. In the other case, the comparison is only for non-transparent pixels of the graphics in the movieClip. So if the clip is irregularly shaped, the hitTest will only be true it the specified point is over part of the actual graphic.

The form of hitTest for this approach is:

movieClip.hitTest(x, y, shapeFlag);

Arguments:

  • x is the coordinate for the horizontal position of the point
  • y is the coordinate for the vertical position of the point
  • shapeFlag is an optional argument that determines if the test is for the bounding rectangle of the movieClip (FALSE, which is the default if the argument is left out), or the actual pixels of the graphics in the movieClip (TRUE).

The following example demonstrates the use of hitTest() with the shapeFlag set to true. Drag the square over the other blue shape. A hit is generated only when the registration point of the square movieClip is over the pixels of the blue shape.

hit_point.fla

The code in the blue shape tests the x,y position of the square, and sets the dynamic text variable hitText to "Hit" if there is a collision (i.e. if hitTest() returns true), "No Hit" if there is no collision.

onClipEvent(mouseMove) {
    if (this.hitTest(_root.square._x, _root.square._y, true)) {
        _root.hitText = "Hit";
    } else {
        _root.hitText = "No Hit";
    }
}

 

 

movieClip vs. movieClip : 

check one movieClip against another movieClip

This technique determines if any pixels of one movieClip overlap any pixels of another movieClip. The form of hitTest() is the following:

movieClip.hitTest(movieClipToCompare);

Arguments:

  • movieClip is the one of the clips to be compared
  • movieClipToCompare is the other clip

An example of this is below:

  • if the paddle sees a collision with the the falling arrow (and it's the first time)
    • it tells the arrow to go to an explosion frame in the arrow's timeline
    • it increments the current score (which is a variable of a dynamic text field)
    • it tells the arrow that it's been hit so it won't generate multiple scores while the arrow passes over it
  • if the arrow reaches the bottom of the screen
    • it resets to the top of the screen at a random x position
    • it switches back to the normal frame on its timeline
    • it resets its hit state so a score can be made again for this pass

game_simple.fla

 

 
code walk : 

for the paddle

The code for the paddle movieClip:

onClipEvent(load) {
    _root.scoreText = 0; // init the dynamic text score field
}
onClipEvent(enterFrame) {
    if(Key.isDown(Key.RIGHT)) { // right arrow key
        this._x += 10; // move the paddle right
    } 
    if (Key.isDown(Key.LEFT)) { // left arrow key
        this._x -= 10; // move the paddle left
    }
    if (this.hitTest(_root.arrow)) { // there's a collision
        if (_root.arrow.hit != true) { // we haven't hit before
            _root.arrow.gotoAndStop("explode"); // show the explosion
            _root.scoreText++; // update the dynamic text field
            _root.arrow.hit == true; // so we don't get multiple scores
        }
    }
}

The code in the load event handler initializes a dynamic text field with a variable name of scoreText.

_root.scoreText = 0;

The first set of code in the enterFrame event handler moves the paddle to the right or left. It checks to see if either the left or right arrow keys is held down, and moves the current movieClip left or right accordingly.

if(Key.isDown(Key.RIGHT)) { // right arrow key
    this._x += 10; // move the paddle right
} 
if (Key.isDown(Key.LEFT)) { // left arrow key
    this._x -= 10; // move the paddle left
}

The next line of code does the collision test, returning true if the current movieClip has collided with the arrow movieClip.

if (this.hitTest(_root.arrow)) {

The next line checks to see if there has already been a collision with the arrow. If we didn't do this check, the score would be incremented multiple times as the arrow passed over the paddle, causing collisions to be detected each frame that passes while the arrow is over the paddle. So the explosion and score increment only occur if the "hit" variable of "_root.arrow" has not be set yet. Inside the if code block, the "hit" variable is set, preventing additional scores until the arrow is reset.

if (_root.arrow.hit != true) {

The next two lines update the screen to show the arrow exploding by sending the arrow movieClip to a different frame. It also shows the new score by incrementing the dynamic text variable "scoreText".

_root.arrow.gotoAndStop("explode");
_root.scoreText++;

The last line of code inside this if statement sets the "hit" variable of the arrow to true so only one score can be made for hitting the arrow.

_root.arrow.hit = true;

 

 
code walk : 

for the arrow

The code for the arrow:

onClipEvent (load) {
    var hit = false; // init the collision flag to not-yet-hit
}
onClipEvent (enterFrame) {
    this._y += 10; // move the clip down
    if (this._y >= 400) { // if we're at the bottom, reset everything
        this._y = 0; // go back to the top
        this._x = (Math.random() * 500) + 25; // set a random horizontal position
        this.gotoAndStop("normal"); // look like an arrow again
        hit = false; // reset so a new score is possible
    }
}

The code in the load event handler initializes the "hit" variable to false, so a score can be made for colliding with the arrow.

var hit = false;

The first line of code in the enterFrame event handler moves the arrow down by 10 pixels

this._y += 10;

The if statement tests for the bottom of the screen so the sequence can start over again. The code resets the position of the arrow to the top of the screen, at a random "x" position from 25 to 525.

if (this._y >= 400) {
    this._y = 0;
    this._x = (Math.random() * 500) + 25;

The next line returns the arrow clip to its normal frame so it does not look like an explosion when it starts at the top of the screen.

this.gotoAndStop("normal");

The last line resets the "hit" variable to false so a new score is possible if a collision occurs.

hit = false;

 

 

all materials on this web site © copyright 2004, Philip van Allen

top