Reputation: 29
I'm taking a programming course where one of my projects is to create a Simon says game on Javascript, one of the functions i want to add is that the game each time a level begins it goes through each and every color of the sequence in order for the user to recall a bit better the sequence, for that i created this next level function:
function nextLevel(){
//increasing level by one
level++;
//Changing title to show level
$('h1').text('Level '+level);
//Repeating the sequence (with the user sequence first as a test)
var i;
for(i=0; i <= userMemory.length; i++){
var currentColor = userMemory[i];
//Sequence walkthrough
setTimeout(function(){
makeSound(currentColor);
$("#"+currentColor).addClass("pressed");
$("#"+currentColor).fadeOut(200).fadeIn(200);
$("#"+currentColor).removeClass("pressed");
}, 1000, currentColor);
}
};
thing is that when i want to repeat the sequence i want to make it in order and kind of slow, because if i just do it like this:
for(i=0; i <= userMemory.length; i++){
var currentColor = userMemory[i];
makeSound(currentColor);
$("#"+currentColor).addClass("pressed");
$("#"+currentColor).fadeOut(200).fadeIn(200);
$("#"+currentColor).removeClass("pressed");
}
it will play all buttons inside the array all at once that's why i wanted to use a setTimeout function, but to my surprise when trying to do this it wont play nor apply the effects to the buttons and the console logs my error message as if the setTimeout function couldn't tell what the currentColor variable is, seems that it is out of scope (even though the variable it's inside the same function) am i doing something wrong? how can i pass the variable to the setTimeout?
Thanks in advance :)
Upvotes: 0
Views: 966
Reputation: 1
asynchrony does that ... by the time the callback is called, for all instances, currentColor will be undefined, because it's assigned to the value of userMemory 1 greater than the number of items in that array (i.e. you have TWO issues with the code)
to explain the array issue ... let's say you have an array
let array = ['a', 'b', 'c']
the indexes of the items are 0, 1 and 2
for (i=0; i <= array.length; i++) {
console.log(array[i]);
}
will output, a, b, c and undefined
- for when i == 3
Hope that's clear.
Also, based on a comment, it seems you also want each iteration to be 1 second after the previous one
you'll need to make each setTimeout 1 second longer than the previous one
modern browser fix -use let
// note, use < not <= ... an array of length 1 has 1 item, at index 0
for(let i=0; i < userMemory.length; i++){
let currentColor = userMemory[i];
//Sequence walkthrough
setTimeout(function(){
makeSound(currentColor);
$("#"+currentColor).addClass("pressed");
$("#"+currentColor).fadeOut(200).fadeIn(200);
$("#"+currentColor).removeClass("pressed");
}, (i + 1) * 1000, currentColor);
}
other possible fix - use a function
function doThings(delay, currentColor) {
setTimeout(function(){
makeSound(currentColor);
$("#"+currentColor).addClass("pressed");
$("#"+currentColor).fadeOut(200).fadeIn(200);
$("#"+currentColor).removeClass("pressed");
}, delay, currentColor);
}
for(i=0; i < userMemory.length; i++){
doThings((i+1) * 1000, userMemory[i]);
}
Upvotes: 1