actionscript-3movieclipflash-cs3

why the movie clip went wrong?


i am doing a simple true and false drag drop game here.

i make all of objects on stage as movie clip:

questions(q1, q2, q3),
drop target(q1Match, q2Match, q3Match)
drag object(answer) eg. q1a1 and q1a2 for question 1,and
response for right and wrong answer (oui, non).

User can go to next question after answering, skip question and go back to answer previous unanswered question.

I got problem when user go back to answer previous unanswered question.

Say user skip question 2 then answer it right for question 3. User go back to answer question 2. When user drag wrong to drop target, the response will show the "oui" movie clip saying it is the right answer. Seems like it carry the memory of answering it right on question 3.

import flash.display.MovieClip;
import flash.events.MouseEvent;

oui.visible = false;
non.visible = false;

q1.visible = true;
q2.visible = false;
q3.visible = false;

q1Match.visible = true;
q2Match.visible = false;
q3Match.visible = false;

q1a1.visible = true;
q1a2.visible = true;

q2a1.visible = false;
q2a2.visible = false;

q3a1.visible = false;
q3a2.visible = false;

back_btn.visible = false;

var num:int = 0;

nx_btn.addEventListener(MouseEvent.CLICK, nextQuestion);

function nextQuestion(event:MouseEvent):void{
switch (num){   

case 0: 

oui.visible = false;
non.visible = false;

q1.visible = false;
q1Match.visible = false;

q1a1.visible = false;
q1a2.visible = false; 

q2.visible = true;  
q2Match.visible = true;

q2a1.visible = true;
q2a2.visible = true; 

back_btn.visible = true;
back_btn.buttonMode = true;

break;

case 1:

oui.visible = false;
non.visible = false;

q2Match.visible = false;
q2.visible = false;

q2a1.visible = false;
q2a2.visible = false; 

q3.visible = true;
q3Match.visible = true; 

q3a1.visible = true;
q3a2.visible = true; 

break;

case 2:

oui.visible = false;
non.visible = false;

q3.visible = false;
q3Match.visible = false;

q3a1.visible = false;
q3a2.visible = false; 

gotoAndStop(3);
break;
}
num++;
} 

back_btn.addEventListener(MouseEvent.CLICK, prevQuestion); 

function prevQuestion(event:MouseEvent):void{

switch (num){

case 0:

oui.visible = false;
non.visible = false;

back_mc.visible = false;

break;

case 1: 

oui.visible = false;
non.visible = false;

q2.visible = false;
q2Match.visible = false;

q2a1.visible = false;
q2a2.visible = false;

q1.visible = true;
q1Match.visible = true;

q1a1.visible = true;
q1a2.visible = true;

back_mc.visible = false; 

break;

case 2:

oui.visible = false;
non.visible = false;

q3.visible = false;
q3Match.visible = false;

q3a1.visible = false;
q3a2.visible = false;

q2.visible = true;
q2Match.visible = true;

q2a1.visible = true;
q2a2.visible = true;

back_mc.visible = true;
back_mc.buttonMode = true;

break;
}
num--;
}

var dragArray:Array = [q1a1, q1a2, q2a1, q2a2, q3a1, q3a2];
var matchArray:Array = [q1Match, q2Match, q3Match];

var currentClip:MovieClip;
var startX:Number;
var startY:Number;

for(var i:int = 0; i < dragArray.length; i++) {
dragArray[i].buttonMode = true;        
dragArray[i].addEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);       

function item_onMouseDown(event:MouseEvent):void {
    currentClip = MovieClip(event.currentTarget);
    startX = currentClip.x;
    startY = currentClip.y;
    addChild(currentClip);
    currentClip.startDrag();
    stage.addEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp);
}

function stage_onMouseUp(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp);
currentClip.stopDrag();
var index:int = dragArray.indexOf(currentClip);
var matchClip:MovieClip = MovieClip(matchArray[index]); 

oui.visible = false;
non.visible = false;

if(q1a1.hitTestObject(q1Match)) {
        q1a1.x = q1Match.x;
        q1a1.y = q1Match.y;
        q1a1.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
        q1a2.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);  
        q1a1.buttonMode = false;
        q1a2.buttonMode = false;

        oui.visible = true;
        non.visible = false;
}

if(q1a2.hitTestObject(q1Match)){
        q1a2.x = startX;
        q1a2.y = startY;

        non.visible = true;
        oui.visible = false;
    }

if(q2a2.hitTestObject(q2Match)) {
        q2a2.x = q2Match.x;
        q2a2.y = q2Match.y;
        q2a1.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
        q2a2.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);      
        q2a1.buttonMode = false;
        q2a2.buttonMode = false;

        oui.visible = true;
        non.visible = false;
    }

    if(q2a1.hitTestObject(q2Match)){
        q2a1.x = startX;
        q2a1.y = startY;

        non.visible = true;
        oui.visible = false;
    }

if(q3a2.hitTestObject(q3Match)) {
        q3a2.x = q3Match.x;
        q3a2.y = q3Match.y;
        q3a1.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
        q3a2.removeEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown);
        q3a1.buttonMode = false;
        q3a2.buttonMode = false;

        oui.visible = true;
        non.visible = false;
    }

    if(q3a1.hitTestObject(q3Match)){
        q3a1.x = startX;
        q3a1.y = startY;

        non.visible = true;
        oui.visible = false;
    }
}

please help! T_T


Solution

  • var index:int = dragArray.indexOf(currentClip);
    var matchClip:MovieClip = MovieClip(matchArray[index]); 
    

    This implies that matchArray and dragArray should be of equal length, while you have matchArray of length 3 and dragArray of length 6. At the very first, change matchArray to this:

    var matchArray:Array = [q1Match, q1Match, q2Match, q2Match, q3Match, q3Match];
    

    Then your arrays match the correct clip from answer set to match set.

    The actual error comes from your code not returning the a3q2 back to its original place after dragging it to match q3match, but instead placing it right over q3match. Then, when you process MOUSE_UP event, your code executes in order, the 2nd question is answered wrongly and non is made visible, but the next set of statements check against 3rd question be answered, and it is already answered correctly - oui becomes visible.

    To fix this, you only need to check collision for currentClip and matchClip, so that only the current question will be checked. Then you need to match currentClip to whether the answer given by this clip is right or wrong, if right, let it be over match clip, if wrong, place it back. Note that your currentClip is not returned to its place if you stop dragging it but not place it over match clip, it might spoil your program a bit (not necessarily so).

    The best approach to fix your code will be making a ouinon array of Boolean type matching dragArray for values of right/wrong answer - false is wrong, true is right. In your case the array will be like this:

    var ouinon:Array = [true, false, true, false, false, true];
    

    Then when you detect collision, you check ouinon's element at index you have already received, and operate based on its outcome.

    if (ouinon[index]) {
        currentClip.x=matchClip.x;
        currentClip.y=matchClip.y;
        oui.visible=true;
        non.visible=false;
    } else {
        currentClip.x=startX;
        currentClip.y=startY;
        non.visible=true;
        oui.visible=false;
    }
    

    Place this instead of your 6 ifs, as this replaces all of them, and look how you can operate only on data derived from event.target.