VCB424 Advanced Interactive Design IV

Hit test: Matching Game

A common activity in Flash-based interactives is dragging an object to a target area in order to trigger a specific effect. The sample to the right is a simple match game; must must drag the circles to the matching rings. Note how the solid circles snap in place if you release them within their rings. The "Done" button checks your accuracy—if all three circles in the proper place, you get a smiley face; otherwise you get a frowny face.

The key to accomplishing this is a "hit test," a method that Flash uses to determine whether two objects are in contact with one another.

Exercise

Create your own matching game.

Part One: Layout

  1. Open a new Flash file and save it as yourName_matchGame.fla.
  2. Create three different objects. They could be different colored shapes as I have in the example, or something more elaborate (like puzzle pieces).
  3. Convert each shape into a movie clip. Give them the instance names drag1, drag2, and drag3. Important: make sure you center the registration for each clip.
  4. Now make three target objects, like the colored rings above. Once again, center the registration.
  5. Covert each target object into a movie clip as well. Give them the instance names dropZone1, dropZone2, and dropZone3.
  6. Important: Send the three target objects behind the three dragable objects by choosing Modify > Arrange> Send to Back for each one (otherwise the dragable objects will get lost behind the targets instead of sitting on top of them).
  7. Mix up the arrangement of the three dragable objects (and/or target objects).
  8. Create two buttons: a "Done" button and a "Reset" button. Place them on stage.
  9. Create a positive feedback movie clip and a negative feedback movie clip. In other words, something that suggests "Yay you got them right" and "Loser you got it wrong!" In my sample above I made a smiley face and a frowny face. Place both movie clips on your stage and give them instance names like "smiley" and "frowny." Don't worry that they're visible right now, we'll hide them later with Actionscript.
  10. Option: Import one or more sound effects. Select the sounds in the library, right-click on them, and then set the Linkage to Export for Actionscript.

Part Two: Actionscript

  1. Create a new actions layer. In frame 1 of the actions layer add the following script:
  2. smiley._visible=false;

    frowny._visible=false;

    This will hide the feedback objects until needed. It also assumes that you named your feedback movie clips smiley and frowny. If you used different instance names, change the script to reflect the names you used.

  3. Now select drag1 and open the script window. Add the following code:
  4. // Get the movie clip's location and

    // store the coordinates as variables
    onClipEvent (load) {
    origX = this._x;
    origY = this._y;
    }

    As noted in the comment, this finds the starting x & y coordinates of the object and then stores those as variables called origX and origY. We'll use these variables further down...

  5. Now add this code to the same script:
  6. onClipEvent(enterFrame) {
    // Make the movie clip dragable
    this.onPress = function () {
    startDrag(this)
    }

    This bit makes the object dragable.

  7. Now a bigger chunk of code:
  8. // Stop dragging the object
    this.onRelease = this.onReleaseOutside = function () {
    this.stopDrag();

    // see if the dropZone contains the center of this mc
    if (_parent.dropZone1.hitTest(this._x,this._y,true)) {

    // center it on the drop zone
    this._x = _parent.dropZone1._x;
    this._y = _parent.dropZone1._y;

    } else {

    // if it's not in the drop zone,
    // return to the original location
    this._x = origX;
    this._y = origY;
    }
    }

    }

    This piece of code accomplishes several things. First it stops the dragging function. Next it checks to see if drag1 is centered over the appropriate drop zone object by using a hit test. If it is, it snaps to the drop zone's center. If not, it jumps back to its starting location (the origX & origY).

  9. Copy and paste this code onto the other two dragable objects (drag2 and drag3), but change the dropZone variables in each (so drag2 should look for dropZone2, and drag3 should aim for dropZone3).
  10. Test it out. At this point, the dragging & dropping functions should work. So how about those buttons?
  11. Select the Done button and open the script window. Add the following script:
  12. on (release) {

    // assume all are correct
    correct = true;

    // check to see that drag mc locations match
    // drop zone locations
    if ((drag1._x != dropZone1._x) or (drag1._y != dropZone1._y)) {
    correct = false;
    }
    if ((drag2._x != dropZone2._x) or (drag2._y != dropZone2._y)) {
    correct = false;
    }
    if ((drag3._x != dropZone3._x) or (drag3._y != dropZone3._y)) {
    correct = false;
    }

    // signal to the Output window
    if (correct) {
    smiley._visible=true;
    frowny._visible=false;
    } else {
    frowny._visible=true;
    smiley._visible=false;
    }

    }

    This code creates a variable called "correct" and sets it to "true." Then it looks to see of the three dragable objects are in the drop zones. If any one is not in the right place, the variable "correct" is changed to "false," and frowny appears. If all are true then the variable is left as is, and smiley is made visible.

  13. Select the Reset button and write the following script:
  14. on (release) {
    frowny._visible=false;
    smiley._visible=false;

    drag1._x = drag1.origX;
    drag1._y = drag1.origY;

    drag2._x = drag2.origX;
    drag2._y = drag2.origY;

    drag3._x = drag3.origX;
    drag3._y = drag3.origY;

    }

    This script hides both smiley and frowny, and then moves the objects back to their starting positions.

Theme and Variations

  1. Okay, what about the sound effect? If you have a sound loaded up and ready to go, add the following script to each of the dragable objects (new code is in red):
  2. // Stop dragging the object
    this.onRelease = this.onReleaseOutside = function () {
    this.stopDrag();

    // see if the dropZone contains the center of this mc
    if (_parent.dropZone1.hitTest(this._x,this._y,true)) {

    // center it on the drop zone
    this._x = _parent.dropZone1._x;
    this._y = _parent.dropZone1._y;

    // create a sound effect when it's dropped in the drop zone
    mySound = new Sound();
    mySound.attachSound("boing", true);
    mySound.start();


    } else {

    // if it's not in the drop zone,
    // return to the original location
    this._x = origX;
    this._y = origY;
    }
    }

    }

    In this case I set the linkage name of the sound to "boing." Your script should reflect whatever linkage name you used (right-click on the sound in the library to set the linkage name).

  3. Eliminating the snap-back. What if you don't want the objects to return to their starting positions every time they're released? What if you want them to stay put? Simply change the last part of the code from:
  4. this._x = origX;

    this._y = origY;

    to:

    this._x = this._x;

    this._y = this._y;

    Basically, just says "stay put."

  5. Possible wrong answers. Maybe you would like to set it up so that it is possible to drag and drop an object on the wrong target to make the game a little harder. In this case one would have to press the "Done" button in order to determine if he/she had the right answer(s). Change the code for the dragable objects to this (new code is in red):
  6. this.onRelease = this.onReleaseOutside = function () {
    this.stopDrag();

    // see if the dropZone contains the center of this mc
    if (_parent.dropZone1.hitTest(this._x,this._y,true)) {

    // center it on the drop zone
    this._x = _parent.dropZone1._x;
    this._y = _parent.dropZone1._y;

    } else if (_parent.dropZone2.hitTest(this._x,this._y,true)) {
    this._x = _parent.dropZone2._x;
    this._y = _parent.dropZone2._y;

    } else if (_parent.dropZone3.hitTest(this._x,this._y,true)) {
    this._x = _parent.dropZone3._x;
    this._y = _parent.dropZone3._y;


    } else {
    // return it to its original location
    this._x = origX;
    this._y = origY;
    }
    }

    }

  7. Invisible drop zones. Sometimes you may want the target area for a dragable area to remain hidden. For example, in the piece to the right, the puzzle pieces snap to invisible drop zones. To create an invisible drop zone simply create a shape filled with white (or your chosen background color) and convert it to a movie clip. Everything else can remain the same.

 

Part Three: Finishing Touches.

  1. Try it out, does it work?
  2. Make your matching game more interesting than circles. Experiment with the variations above.
  3. Export a .swf file.
  4. Embed the .swf file into an html page (called matchGame.html for example).
  5. FTP the .swf, .html, and .fla files to your server space. Make a link to the html file from your home page.

Point Breakdown

4 pts

Portfolio quality design; great match game

3 pts

Good looking; above average work.

2 pts

It works, but it's nothing fancy.

1 pts

Something's not working right.

0 pts

Poor showing; mostly incomplete or full of errors.

 

Course Outline

Syllabus

Student Resources