/* commented code for the above interactions */
// set up each shape so that it can be dragged
shape1_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
shape1_mc.homePos = shape1_home_mc; // homePos is an property we dynamically add to the movie clip to keep track of its home object
// the home pos property of each draggable movieClip points to another movie clip
// when the draggable clip is incorrectly dropped, we use the movieClip referenced
// by homePos to get the return coordinates.
shape1_mc.correctPos = redObject_target_mc; // correctPos also a dynamic property to store the correct target position for each of our draggable shapes
// ditto for the rest of the shapes
shape2_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
shape2_mc.homePos = shape2_home_mc;
shape2_mc.correctPos = greenObject_target_mc;
shape3_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
shape3_mc.homePos = shape3_home_mc;
shape3_mc.correctPos = redObject_target_mc; // we allow 2 correct answers for the red drop - therefore same code as shape1 above
// because we allow more than one object to be dropped on the red target square, let's block it from holding more than one.
// --- 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
// with some scheme to lay them out side by side. Not allowing mulitple drops on the same target is easier for now.
// 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
// on this object. If so, we'll block it from accepting other drops.
// initially it is unoccupied.
redObject_target_mc.occupied = false;
//set up the reset button functionality
// hide it first - will be made visible when the user successfully drags and object to its correctPos object
reset_btn.visible = false;
reset_btn.addEventListener( MouseEvent.MOUSE_UP, ResetDrag );
function ResetDrag( evt ){ // reset the drag environment
// move all objects back to their home positions
setObjectLocationTo( shape1_mc, shape1_mc.homePos );
setObjectLocationTo( shape2_mc, shape2_mc.homePos );
setObjectLocationTo( shape3_mc, shape3_mc.homePos );
// becaue we are preventing futher drags by removing the event listener when an object is correctly dropped,
// we need to add them back on reset:
shape1_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
shape2_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
shape3_mc.addEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
// reset the occupied prorperty:
redObject_target_mc.occupied = false;
// reset the feedback field:
feeback_field.text = "Drag the correct object to the indicated square. Feedback will go here..."
// lastly, hide this button again!
evt.target.visible = false;
}
function setUpDrag( evt ){ // MOUSE_DOWN event detected on an object
evt.target.startDrag();
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
//move the object we are dragging to the top of the display list, so it appears in front - i.e. "bring to front"
setChildIndex(evt.target, numChildren - 1);
}
function dropDrag( evt ){
evt.target.stopDrag();
//remove the MOUSE_UP listener, since we are dropping the object, we only listen when we start dragging.
evt.target.removeEventListener( MouseEvent.MOUSE_UP, dropDrag );
//to determine if the user drops on the desired target object, check 2 conditons:
// 1. make sure we are not dropping it on nothing
// 2. make sure the parent movieClip containing the shape we are dropping on is the desired target for this object
// note
// we have dynamically assigned to the "correctPos" property on each draggable shape - see the code above.
// The reason we need to check the dropTarget's parent object is because Flash detects objects
// inside of movieClips as the dropTarget, which is ... not what we would like.
if( (evt.target.dropTarget != null ) && ( evt.target.dropTarget.parent == evt.target.correctPos ) ){
//good - the user dropped on the correct target so center on correctPos object position
// but first, because we don't want our redObject_target_mc to hold more than one object at a time
// let's check to see if we are dropping correctly on the redObject_target_mc and then
// if it is already occupied:
// are we dropping a redObject_target_mc? (we already know we've dragged a red object if
// this is true because our fist if statement above passed as true)
if( evt.target.dropTarget.parent == redObject_target_mc ){
//now, if it is already been dropped on, do not allow another drop
if( redObject_target_mc.occupied ){
//OK we have dropped correctly on the redObject_target_mc but it is occupied,
// so move any other red objects back
// pass the dragged object and it's home position
// - see the definition of the function below
feeback_field.text = "You cannot drop more than one red object in this design";
setObjectLocationTo( evt.target, evt.target.homePos );
}else{ // it is not already occupied, so allow the drop but
// prevent futher drops on this target
// pass the dragged object and it's correct position to the function below
setObjectLocationTo( evt.target, evt.target.correctPos );
feeback_field.text = "You correctly dropped " + evt.target.name + " on it's target object: " + evt.target.correctPos.name;
// block futher drops on this target
redObject_target_mc.occupied = true;
// lastly, this design does not allow an object to be dragged once it has been dropped on its correct target, so:
evt.target.removeEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
}
}else{ // we are not dropping on a red object target
// pass the dragged object and it's correct position to the function below
setObjectLocationTo( evt.target, evt.target.correctPos );
feeback_field.text = "You correctly dropped " + evt.target.name + " on it's target object: " + evt.target.correctPos.name;
// lastly, this design does not allow an object to be dragged once it has been dropped on its correct target, so:
evt.target.removeEventListener( MouseEvent.MOUSE_DOWN, setUpDrag );
}
// make the reset button visible if we have dropped at least 1 object correctly
// we need this reset feature because we don't allow objects to be redragged when they are dropped correctly.
reset_btn.visible = true;
}else{ // user did not drop on the correct target, so move the object back to the position of it's home shape
// pass the dragged object and it's home position to the function below
setObjectLocationTo( evt.target, evt.target.homePos );
//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
var dropObjectName = "";
if( evt.target.dropTarget == null ){ // we dropped on nothing
dropObjectName = "the stage";
}else{
// this line generates an error if we do not check for null
dropObjectName = evt.target.dropTarget.parent.name;
}
feeback_field.text = "You incorrectly dropped " + evt.target.name + " on: " + dropObjectName;
}
}
function setObjectLocationTo( movedObject, placeHolder ){
// becuase we reuse the same functionality in the dropDrag function 3 times,
// we code it here once to improve readability and save space
// the idea is that we use 1 object's x and y coordinates to mark the
// desired resting location of the one we are dragging
// i.e. it acts as a place holder.
// both objects - the object we are dragging and the place holder object
// - should be movieClips for this to work
movedObject.x = placeHolder.x;
movedObject.y = placeHolder.y;
}