Obi-wan
Obi-wan

Reputation: 95

vanilla javascript - Changing between two arrays that are rotated through via a function

I am making a math quiz for children. I have a function that, on page load, rotates through a set of images. My goal is that when an answer is correct that it will rotate through a different set of images once before reverting back to the original set. I have managed to get it to change to the second set but I have been trying to get it to only rotate through those images once before reverting back to the original images. I have tried several things including: 1. Using an if statement to change between the two arrays but that was completely unresponsive and did not change the pictures at all. 2. I made a new function that changed the actual content of the first array but then I couldn't change it back after it went through the images once.

The code for the JavaScript is as follows (sorry it is messy from me trying all different things):

// Starting animation
window.addEventListener("load", normalAnimation);

var images = ['01.png', '02.png', '01.png', '02.png', '03.png', '01.png', '02.png', '01.png','04.png'];
var images2 = ['catchfish01.png', 'catchfish02.png', 'catchfish03.png', 'catchfish04.png', 'catchfish05.png', 'catchfish06.png','catchfish07.png'];
var imageNumber = 0;
var pic1 = document.getElementById('pic1');

var normalAnimation = function() {

//Here I attempted to change the images used but only initiates the code in the else part.  The actual change of images used is done with the catchFish function below.
    var feedBack = document.getElementById("feedBack");
    if(feedBack.textContent == "Well Done!"){
        setInterval(function () {
            pic1.src = images2[imageNumber];
            imageNumber++;
            if (imageNumber > images2.length-1) {
                pic1.src = images[imageNumber];
                imageNumber++;}
        },2000);
    }
    else {setInterval(function () {
        pic1.src = images[imageNumber];
        imageNumber++;
        if (imageNumber > images.length -1) {
            imageNumber = 0;}
         },2000);
    }
}

requestAnimationFrame(normalAnimation);

// Making the question

document.getElementById("button1").addEventListener("click", question);

var plusMinus = document.getElementById("plusMinus");
var counter = 0;

function question(){
    var startButton = document.getElementById("button1");
    var number1 = document.getElementById("num1");
    var number2 = document.getElementById("num2");
    var decider = Math.random();
    var answer = document.getElementById("answer");
    counter ++;

    if(decider<0.5){
      plusMinus.textContent = "+"  
    }
    else{plusMinus.textContent = "-"};

    startButton.textContent = "Round" + " " + counter;
    number1.textContent = Math.floor(Math.random()*11);
    number2.textContent = Math.floor(Math.random()*11);
    equals.textContent = "=";

    if(plusMinus.textContent == "-" && parseInt(number2.textContent) >   parseInt(number1.textContent)) {
        console.log('swapped');
        var a = number2.textContent;
        number2.textContent = number1.textContent;
        number1.textContent = a;
    };

    if(startButton.textContent == "Round" + " " + 11){
        startButton.textContent = "Start Again";
        counter = 0;
        number1.textContent = " ";
        plusMinus.textContent = " ";
        number2.textContent = " ";
    }
    answer.textContent = " ";
};

// Answering the question

document.getElementById("button2").addEventListener("click", answer);

var totalScore = 0;

function answer(){
    var num1 = parseInt(document.getElementById("num1").textContent, 10);
    var num2 = parseInt(document.getElementById("num2").textContent, 10);
    var answer = parseInt(document.getElementById("answer").value, 10);
    var feedBack = document.getElementById("feedBack");
    var scoreReport = document.getElementById("score");

    if (plusMinus.textContent == "+"){
        if(answer == num1 + num2) {
            feedBack.textContent = "Well Done!";
            totalScore = totalScore + 10;
            if(feedBack.textContent== "Well Done!"){
                setTimeout(function () {feedBack.textContent = " ";
            }, 2000);
        }
        //Used to call the function that changes the array contents
        catchFish();

        } else {
            feedBack.textContent = "Try again!";
            if(feedBack.textContent == "Try Again!"){
                setTimeout(function () {feedBack.textContent = " "
                }, 2000);
            }
        }
   } else {
     if(answer == num1 - num2){
         feedBack.textContent = "Well Done!";
         if(feedBack.textContent== "Well Done!"){
             setTimeout(function () {feedBack.textContent = " ";
             }, 2000);}
         totalScore = totalScore +10;
     } else {
         feedBack.textContent = "Try Again!";
         if(feedBack.textContent == "Try Again!"){
            setTimeout(function () {feedBack.textContent = " "
            }, 2000);
         }
       }
    }
scoreReport.textContent = "Score:" + totalScore;
};

//This function changes the contents of the array to the second set of images
function catchFish() {
    imageNumber = 0;
    images = ['catchfish01.png', 'catchfish02.png', 'catchfish03.png', 'catchfish04.png', 'catchfish05.png', 'catchfish06.png','catchfish07.png'];
     if(pic1.src == 'catchfish07.png'){
        images = ['01.png', '02.png', '01.png', '02.png', '03.png', '01.png', '02.png', '01.png','04.png'];
     }
} 

Thank you in advanced for your help.

Upvotes: 2

Views: 52

Answers (1)

Ilmari Karonen
Ilmari Karonen

Reputation: 50368

Probably the cleanest solution would be to maintain a queue of images that are going to be shown next. At each interval, you shift the first image off the queue and, if the queue is empty, add a new set of images into the queue:

var queue = [];
setInterval( function () {
    if (queue.length < 1) {
        queue = ['01.png', '02.png', '01.png', '02.png', '03.png', '01.png', '02.png', '01.png', '04.png'];
    }
    pic1.src = queue.shift();
}, 2000 );

Then, to temporarily switch to a different set of images, you can just replace the contents of the queue:

function catchFish() {
    queue = ['catchfish01.png', 'catchfish02.png', 'catchfish03.png', 'catchfish04.png', 'catchfish05.png', 'catchfish06.png', 'catchfish07.png'];
}

Now the setInterval() routine will run through the new contents of the queue, and once it reaches the end, it'll return to the original image rotation.


ps. Tip: If you'd prefer to define your image lists outside the function, you can use slice() to copy them into the queue, like this:

var images = ['01.png', '02.png', '01.png', '02.png', '03.png', '01.png', '02.png', '01.png', '04.png'];
var images2 = ['catchfish01.png', 'catchfish02.png', 'catchfish03.png', 'catchfish04.png', 'catchfish05.png', 'catchfish06.png', 'catchfish07.png'];

var queue = [];
setInterval( function () {
    if (queue.length < 1) queue = images.slice();
    pic1.src = queue.shift();
}, 2000 );

function catchFish() {
    queue = images2.slice();
}

(If you just did queue = images; without using .slice(), this would make queue an alias for images, and so queue.shift() would end up modifying the original images array. Using .slice() instead gives you a copy of the images array, which can be safely assigned to queue. See the Array class documentation on MDN for more examples of how to manipulate JavaScript arrays.)

Upvotes: 1

Related Questions