Im new to programming and making the infamous Simon says game but I’m having trouble getting the computer generated sequence to animate in the order of the array.
I wanted to have a function that both wiped the previous sequence (assuming the game has started) and creates a new one while animating the buttons in the order of new array. I tried a few different methods but their outputs only confused me more.
var pattern = []
var userPattern = [];
var buttonColours = ["red", "blue", "green", "yellow"];
var started = false
var level = 0;
function nextSequence() {
pattern = [];
userPattern = [];
while (pattern.length < 4) {
var randomNumber = Math.floor(Math.random() * 4);
var randomColour = buttonColours[randomNumber];
pattern.push(randomColour);
}
/*Method 1*/
for (i = 0; i < pattern.length; i++) {
setTimeout(function() {
$("." + pattern[i]).fadeOut(200).fadeIn(200);
}, 500 * (i + 1));
}
/*Mehtod 2*/
// setTimeout($("." + pattern[0]).fadeOut(200).fadeIn(200), 500);
// setTimeout($("." + pattern[1]).fadeOut(200).fadeIn(200), 1000);
// setTimeout($("." + pattern[2]).fadeOut(200).fadeIn(200), 1500);
// setTimeout($("." + pattern[3]).fadeOut(200).fadeIn(200), 2000);
$("h1").html("Level" + " " + level);
level++;
console.log(pattern)
}
The first method doesn’t play the animation at all and the second plays the animations simultaneously completely disregaurding the setTimeout function. Method 2 also returns a Uncaught SyntaxError: Unexpected identifier ‘Object’ directed at all 4 lines of code.
3
Answers
In the first method you are passing a function as parameter to the
setTimeout
which is fine, but by the time thei
in the function gets evaluated it is alreadyi = 4
.The way to overcome the late evaluation of the
i
is to pass a copy of it that will live inside a function (IIFE). Also the rest of your code will live inside that function, wherei
is what was meant to be when passed to it as argument.The problem is that the value of
i
is not what you expect when the setTimeout triggers its function. Just declare it usinglet
.Your issue is with the scope of
i
infor(i = 0;...
It’s a global for a start, which should be avoided
Making it
for(let i = 0; ...
will ensure thati
is the correct value for the setTimeout delayHowever: I think using array.reduce
and async/await
and jQuery.delay
and jQuery.promise provides much cleaner looking code;