【问题标题】:AS3 - Navigating through array elementsAS3 - 浏览数组元素
【发布时间】:2015-01-25 16:27:14
【问题描述】:

您好,感谢您抽出宝贵时间。我有一个 as3 代码,它从 7 个帧中随机选择 5 个帧,没有重复。

var mygroup1:RadioButtonGroup = new RadioButtonGroup("group1");
q1a1.group = q1a2.group = q1a3.group = q1a4.group = q1a5.group = mygroup1;

var number_array:Array = [8158,8159,8160,8161,8162,8163,8164];
var final_array:Array = [];
var count_selected:int = 5;
var i:int;

for(i = 0; i < count_selected; i++)
   {
      if(number_array.length == 0)
         break;
      else
         final_array.push(number_array.splice(Math.floor(Math.random() * number_array.length), 1)[0]);
   }

var index = 0;
var currentQuestion:int = final_array[index];
var answers:Object = {
    8158: 'B) 12',
    8159: 'F) All of the above',
    8160: 'A) True',
    8161: 'B) False',
    8162: 'C) 4',
    8163: 'F) D and E',
    8164: 'B) B'
};

var getAnswer = mygroup1.selection.label;  //Getting the selection from RadioButtonGroup

submitBtn.addEventListener(MouseEvent.CLICK, onSubmitClicked);

function onSubmitClicked(e:MouseEvent):void {
var answer:String = getAnswer();
   if (answer === answers[currentQuestion]) 
      awardScore(currentQuestion);
      ++index;
      currentQuestion = final_array[index];
      gotoAndStop(final_array[index]);
   }

当您单击“startBtn”时,它会将您带到第一个随机生成的帧(final_array[0]),随机启动该过程非常棒。

接下来的 7 帧中的每一帧都有一个提交按钮 (b1,b2...b7),它会跟踪分数并提交答案,并且应该转到下一个随机选择的帧,但是仅 5 次,在剩余的生成帧之后....gotoAndStop(final_array[1])...(final_array[2])....(final_array[3])....(final_array[4])。

    b1.addEventListener(MouseEvent.CLICK, quizHandler1)
    function  quizHandler1(event:MouseEvent):void{
    if(mygroup1.selection.label=="B) 12") {
        count = count + 20;
        scoreresult.text = (count).toString();
        gotoAndStop(final_array[1]);    
    }
    else{
        gotoAndStop(final_array[1]);
        }
    }

我的问题是......由于用户只会去 7 个随机选择的帧中的 5 个,我如何确保所有 7 个帧中的所有按钮都会听并遵循 gotoAndStop(final_array[]);以 5 的顺序声明?因为最后,会遗漏 2 帧,而这两个帧会在每一卷中随机变化。我希望我能解释我的困境。再次感谢。

【问题讨论】:

    标签: arrays actionscript-3 random


    【解决方案1】:

    要进行像您这样的测验,我认为您不需要在每一帧上复制所有内容。您可以将您的问题放入 MovieClips(或一个具有多个帧的 MovieClip),然后您可以将其添加到您的舞台,并且对于您的复选框,您可以创建它一次,并且每次您可以更改它们的值和标签。对于按钮,您只需要一个按钮即可验证和检查当前问题并转到下一个问题。

    看看这个例子:

    var score:int;
    var max_score:int;
    const default_score:int = 20;
    
    // create our questions list (7 questions) : 
    var questions_list:Object = {
        // index        : to identify our question
        // movie_clip   : the class name used for AS linkage    
        1: { index : 1, movie_clip : Question1, good_answer : 'css3', first_answer : 'html5', second_answer : 'jquery', third_answer : 'css3', score : default_score }, 
        2: { index : 2, movie_clip : Question2, good_answer : 'html5', first_answer : 'html5',  second_answer : 'less', third_answer : 'ruby', score : 50 }, 
        3: { index : 3, movie_clip : Question3, good_answer : 'jquery', first_answer : 'ruby',  second_answer : 'jquery', third_answer : 'css3', score : default_score }, 
        4: { index : 4, movie_clip : Question4, good_answer : 'less', first_answer : 'less', second_answer : 'html5', third_answer : 'css3', score : 15 }, 
        5: { index : 5, movie_clip : Question5, good_answer : 'nodejs', first_answer : 'python', second_answer : 'nodejs', third_answer : 'jquery', score : 10 }, 
        6: { index : 6, movie_clip : Question6, good_answer : 'python', first_answer : 'css3', second_answer : 'html5', third_answer : 'python', score : default_score }, 
        7: { index : 7, movie_clip : Question7, good_answer : 'ruby', first_answer : 'ruby', second_answer : 'html5', third_answer : 'less', score : default_score }
    };
    
    var enabled_questions:Array = [1, 2, 3, 4, 5, 6, 7];    
    var current_question:int = 0;
    
    //----------------------------------------------------------------------------------------------------
    
    // sprite that shows our questions 
    var questions_container:Sprite = new Sprite();
        questions_container.x = questions_container.y = 20;
        questions_container.visible = false;
        addChild(questions_container);
    
    var checks_group:RadioButtonGroup = new RadioButtonGroup('checks_group');
    
    // sprite that contains our 3 check box 
    var checks_container:Sprite = new Sprite();
        checks_container.visible = false;
        checks_container.x = int(stage.stageWidth / 2);
        checks_container.y = 50;
        addChild(checks_container);
    
    // create our check box, 3 buttons in my case
    // the 4th one is used only to uncheck every time all check box
    for(var i:int = 0; i < 4; i++)
    {
        var btn_check:RadioButton = new RadioButton();
            if(i != 3){
                btn_check.y = i * 30;       
            } else {
    
                // our 4th check box is hidden
                btn_check.visible = false;
            }
            btn_check.group = checks_group; 
            btn_check.name = 'btn_check' + i;
            checks_container.addChild(btn_check);
    }
    
    // start button
    var btn_start:Button = new Button();
        btn_start.label = 'Start ! ';
        btn_start.width = 180;
        btn_start.height = 60;
        btn_start.x = int((stage.stageWidth - btn_start.width)/2);
        btn_start.y = int((stage.stageHeight - btn_start.height)/2) - 20;
        btn_start.addEventListener(MouseEvent.CLICK, startQuiz);
        addChild(btn_start);
    
    // next button, to go to the next question
    var btn_next:Button = new Button()
        btn_next.label = 'Next  >> ';
        btn_next.width = 90;
        btn_next.height = 30;
        btn_next.visible = false;
        btn_next.x = stage.stageWidth - btn_next.width - 10;
        btn_next.y = stage.stageHeight - btn_next.height - 10;
        btn_next.addEventListener(MouseEvent.CLICK, checkAnswer);
        addChild(btn_next); 
    
    // a text field which will show the score and the current question number
    var txt_score:TextField = new TextField();
        txt_score.width = 200;
        txt_score.height = 30;
        txt_score.x = stage.stageWidth - txt_score.width;
        txt_score.y = 10;
        txt_score.visible = false;
        txt_score.selectable = false;
        addChild(txt_score);
    
    //----------------------------------------------------------------------------------------------------
    
    function startQuiz(e:MouseEvent):void
    {   
        // here we will get only 5 questions
        // I used a method from http://stackoverflow.com/questions/11980657/as3-random-array-randomize-array-actionscript-3 to shuffle the array
        // and then I remove the last 2 elements from the array
        enabled_questions = enabled_questions.sort(function(i:*,j:*){return(Math.random()<.5)?-1:1;}).slice(0,enabled_questions.length-2);
    
        for(var i:int = 0; i < enabled_questions.length; i++){
            var q_i:int = enabled_questions[i];
            var q:Object = questions_list[q_i];
            max_score += q.score;
    
            // create our questions instance and hide it
            // every question is an instance of a movieclip in our library
            // we can alse use only one movieclip and then we can use its timeline to go from a question to another
            var question = new (q.movie_clip);
                question.index = q_i;
                question.visible = false;
                questions_container.addChild(question);
        }       
    
        // hide the start button
        e.target.visible = false;
    
        // show other elements 
        questions_container.visible = checks_container.visible = btn_next.visible = txt_score.visible = true    
    
        // load the first question
        loadQuestion(current_question);
    
    }
    
    // check the answer and update score
    function checkAnswer(e:MouseEvent):void 
    {   
        var question:Object = questions_list[enabled_questions[current_question]];
    
        if(question.good_answer == checks_group.selectedData){
    
            // update the score
            setScore(question.score);       
        }
    
        if(current_question < enabled_questions.length - 1){        
    
            current_question ++;
            loadQuestion(current_question);
    
        } else {
    
            e.target.x = e.target.y = 0;
            e.target.enabled = false;
            e.target.width = stage.stageWidth;
            e.target.height = stage.stageHeight;
            e.target.label = 'You have finished the quiz, your score is : ' + score;
    
            checks_container.visible = questions_container.visible = txt_score.visible = false;
    
        }
    }
    
    // load question (show it) and update our check box
    function loadQuestion(index:int):void 
    {   
        var question:Object = questions_list[enabled_questions[index]];
    
        for(var i:int = 0; i < checks_container.numChildren; i++){      
            if(checks_container.getChildAt(i) is RadioButton){
                var btn:RadioButton = RadioButton(checks_container.getChildAt(i));          
                switch (btn.name){              
                    case 'btn_check0' : btn.value = btn.label = question.first_answer; break;
                    case 'btn_check1' : btn.value = btn.label = question.second_answer; break;
                    case 'btn_check2' : btn.value = btn.label = question.third_answer; break;   
                    case 'btn_check3' : btn.selected = true; break; 
                }               
            }       
        }
    
        for( i=0; i < questions_container.numChildren; i++){            
            if(questions_container.getChildAt(i) is MovieClip){
                var mc:MovieClip = MovieClip(questions_container.getChildAt(i));
                    mc.visible = mc.index == question.index;    
            }       
        }
    
        // setScore is used here just to update the question number in the score text field
        setScore();
    
    }
    
    // show the score and current question
    function setScore(new_score:int = 0){
        score += new_score;
        txt_score.text = 'Score : ' + score.toString() + ' / ' + max_score.toString() + ', Question : ' + (current_question+1) + ' / ' + enabled_questions.length;
    }
    
    // icons used in this example by Jozef Krajčovič : https://www.iconfinder.com/Jozef89
    

    这段代码给你这样的东西:

    你也可以看到它在工作here

    当然这只是一个简单的例子,您可以根据自己的需要进行改进和调整。

    希望能有所帮助。

    【讨论】:

    • 非常感谢您付出的所有时间。它完美无瑕!睡一觉之后,我会马上开始工作。太棒了……太棒了……太棒了!
    • 按“开始”后,我收到:#1007:实例化尝试出现非构造函数错误,它指向 var question = new (q.movi​​e_clip);你能告诉我我错过了什么吗?我为库中的 7 个问题中的每一个都创建了一个实例。
    • 在我的示例中,我将每个图像(css3、ruby、...)作为 MovieClip 放入类名为 Question1、Question2、... Question7 的库中。
    • 可以从here下载源文件。
    • 如果每个问题的单选按钮数量不同,您能告诉我们该怎么做吗?在示例中,单选按钮的数量始终为 3,我不会妨碍您的 :)
    【解决方案2】:

    听起来您只需要一个提交按钮即可转到下一帧。这样您就不必担心订单。

    一些示例代码让您了解它的工作原理

    var index = 0;
    var currentQuestion:int = final_array[index];
    var answers:Object = {
      8158: '12',
      8159: '13'
      //...etc.
    };
    
    submitBtn.addEventListener(MouseEvent.CLICK, onSubmitClicked);
    
    function onSubmitClicked(e:MouseEvent):void {
       var answer:String = getAnswer(); //get the user's answer
       if (answer === answers[currentQuestion]) {
          awardScore(currentQuestion);
          ++index;
          currentQuestion = final_array[index];
          gotoAndStop(final_array[index]);
       }
    }
    

    我们的想法是在一个单击处理程序中包含所有逻辑,一旦单击它就会获取用户的答案并检查它是否正确,如果正确,则继续下一个问题。

    【讨论】:

    • 谢谢巴里斯。我现在正在尝试实现您的代码并随时更新原始代码。如果您能密切关注线程,我将不胜感激。
    • 在上面更新的代码中,我得到错误 #1006: value is not a function。调试说“答案未定义”。另外,我担心“awardScore”行会出错,因为它没有被分配。但我还无法到达那部分。有什么指点吗?
    猜你喜欢
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 2015-05-28
    • 1970-01-01
    相关资源
    最近更新 更多