Single Frame Navigation Example

  1. /*  commented code for the above interactions */
  2.  
  3. // set up each shape so that it can be dragged
  4. shape1_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  5. shape1_mc.homePos = shape1_home_mc; // homePos is an property we dynamically add to the movie clip to keep track of its home object
  6. // the home pos property of each draggable movieClip points to another movie clip
  7. //    when the draggable clip is incorrectly dropped, we use the movieClip referenced
  8. //    by homePos to get the return coordinates.
  9. shape1_mc.correctPos = redObject_target_mc; // correctPos also a dynamic property to store the correct target position for each of our draggable shapes
  10.  
  11. // ditto for the rest of the shapes
  12. shape2_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  13. shape2_mc.homePos = shape2_home_mc;
  14. shape2_mc.correctPos = greenObject_target_mc;
  15.  
  16. shape3_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  17. shape3_mc.homePos = shape3_home_mc;
  18. shape3_mc.correctPos = redObject_target_mc; // we allow 2 correct answers for the red drop - therefore same code as shape1 above
  19.  
  20. // because we allow more than one object to be dropped on the red target square, let's block it from holding more than one.
  21. //    --- This is a usability issue.  We could allow both to be dropped on the target, but they would overlap each other up visually unless we come up
  22. //         with some scheme to lay them out side by side.  Not allowing mulitple drops on the same target is easier for now.
  23. // So, we add a dynamic property to the redObject_target_mc - let's call it "occupied" to tell if something has already been correctly dropped
  24. // on this object.   If so, we'll block it from accepting other drops.
  25. // initially it is unoccupied.
  26. redObject_target_mc.occupied = false;
  27.  
  28. //set up the reset button functionality
  29. // hide it first - will be made visible when the user successfully drags and object to its correctPos object
  30. reset_btn.visible = false;
  31. reset_btn.addEventListener( MouseEvent.MOUSE_UP, ResetDrag );
  32.  
  33. function ResetDrag( evt ){ // reset the drag environment
  34.     // move all objects back to their home positions
  35.     setObjectLocationTo(  shape1_mc,  shape1_mc.homePos );
  36.     setObjectLocationTo(  shape2_mc,  shape2_mc.homePos );
  37.     setObjectLocationTo(  shape3_mc,  shape3_mc.homePos );
  38.     // becaue we are preventing futher drags by removing the event listener when an object is correctly dropped,
  39.     //     we need to add them back on reset:
  40.     shape1_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  41.     shape2_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  42.     shape3_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  43.     // reset the occupied prorperty:
  44.     redObject_target_mc.occupied = false;
  45.     // reset the feedback field:
  46.     feeback_field.text =  "Drag the correct object to the indicated square.  Feedback will go here..."
  47.     // lastly, hide this button again!
  48.     evt.target.visible = false;
  49. }
  50.  
  51.  
  52. function setUpDrag( evt ){ // MOUSE_DOWN event detected on an object
  53.     evt.target.startDrag();
  54.     evt.target.addEventListener( MouseEvent.MOUSE_UP, dropDrag ); // what ever object we start dragging on, start linstening for MOUSE_UP on object to know when the drag stopped
  55.     //move the object we are dragging to the top of the display list, so it appears in front - i.e. "bring to front"
  56.     setChildIndex(evt.target, numChildren - 1);
  57. }
  58.  
  59. function dropDrag( evt ){
  60.     evt.target.stopDrag();
  61.     //remove the MOUSE_UP listener, since we are dropping the object, we only listen when we start dragging.
  62.     evt.target.removeEventListener( MouseEvent.MOUSE_UP, dropDrag );
  63.    
  64.     //to determine if the user drops on the desired target object, check 2 conditons:  
  65.     // 1. make sure we are not dropping it on nothing
  66.     // 2. make sure the parent movieClip containing the shape we are dropping on is the desired target for this object
  67.     //     note
  68.     //      we have dynamically assigned to the "correctPos" property on each draggable shape - see the code above.
  69.     //      The reason we need to check the dropTarget's parent object is because Flash detects objects
  70.     //          inside of movieClips as the dropTarget, which is ... not what we would like.
  71.     if( (evt.target.dropTarget != null ) && ( evt.target.dropTarget.parent  ==  evt.target.correctPos ) ){
  72.         //good - the user dropped on the correct target so center on correctPos object position
  73.             //   but first, because we don't want our redObject_target_mc to hold more than one object at a time
  74.         //   let's check to see if we are dropping correctly on the redObject_target_mc and then
  75.         //       if it is already occupied:
  76.        
  77.         // are we dropping a redObject_target_mc?  (we already know we've dragged a red object if
  78.         //      this is true because our fist if statement above passed as true)
  79.         if( evt.target.dropTarget.parent  == redObject_target_mc ){
  80.             //now, if it is already been dropped on, do not allow another drop
  81.             if( redObject_target_mc.occupied  ){
  82.                //OK we have dropped correctly on the redObject_target_mc but it is occupied,
  83.                //   so move any other red objects back
  84.                 // pass the dragged object and it's home position
  85.                 //     - see the definition of the function below
  86.                 feeback_field.text = "You cannot drop more than one red object in this design";
  87.                 setObjectLocationTo(  evt.target,  evt.target.homePos );
  88.             }else{ // it is not already occupied, so allow the drop but
  89.                 //      prevent futher drops on this target
  90.                 // pass the dragged object and it's correct position to the function below
  91.                 setObjectLocationTo(  evt.target,  evt.target.correctPos );
  92.                 feeback_field.text = "You correctly dropped "  +  evt.target.name + " on it's target object: " + evt.target.correctPos.name;
  93.                 //  block futher drops on this target
  94.                 redObject_target_mc.occupied = true;
  95.                 // lastly, this design does not allow an object to be dragged once it has been dropped on its correct target, so:
  96.                 evt.target.removeEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  97.             }
  98.         }else{ // we are not dropping on a red object target
  99.             // pass the dragged object and it's correct position to the function below
  100.             setObjectLocationTo(  evt.target,  evt.target.correctPos );
  101.             feeback_field.text = "You correctly dropped "  +  evt.target.name + " on it's target object: " + evt.target.correctPos.name;
  102.             // lastly, this design does not allow an object to be dragged once it has been dropped on its correct target, so:
  103.             evt.target.removeEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
  104.         }
  105.         // make the reset button visible if we have dropped  at least 1 object correctly
  106.         // we need this reset feature because we don't allow objects to be redragged when they are dropped correctly.
  107.         reset_btn.visible = true;
  108.     }else{ // user did not drop on the correct target, so move the object back to the position of it's home shape
  109.         // pass the dragged object and it's home position to the function below
  110.         setObjectLocationTo(  evt.target,  evt.target.homePos );
  111.         //before we can send feedback about an incorect drop, we need to make sure we didn't drop on "nothing" - ie. a blank area of the stage
  112.         var dropObjectName = "";
  113.         if(  evt.target.dropTarget == null ){ // we dropped on nothing
  114.             dropObjectName = "the stage";
  115.         }else{
  116.                 // this line generates an error if we do not check for null
  117.             dropObjectName =  evt.target.dropTarget.parent.name;
  118.         }
  119.         feeback_field.text = "You incorrectly dropped "  +  evt.target.name + " on: " + dropObjectName;
  120.     }
  121. }
  122.  
  123. function setObjectLocationTo( movedObject, placeHolder  ){
  124.     // becuase we reuse the same functionality in the dropDrag function 3 times,
  125.     //      we code it here once to improve readability and save space
  126.     // the idea is that we use 1 object's x and y coordinates to mark the
  127.     //      desired resting location of the one we are dragging
  128.     // i.e. it acts as a place holder.
  129.     // both objects - the object we are dragging and the place holder object
  130.     //      - should be movieClips for this to work
  131.     movedObject.x = placeHolder.x;
  132.     movedObject.y = placeHolder.y;
  133. }
  134.  

Gordon Graber 2009