Rawle Juglal Rawle Juglal - 5 months ago 20
Javascript Question

Simon Says Game unable to disable color pads during computer turn

I have built the simon game. It functions correctly if the user plays correctly but in an attempt to make it full proof I wanted to disable the user from clicking choices while the computer is showing the next pattern. I've tried many combinations of using the jquery .on/.off .unbind/.bind with e.preventDefault but have had no success. Can someone please help me with the solution to adding this feature.This is a codepen link if you want to see the full project as I'm only going to post what seems like relevant code below it. http://codepen.io/RawleJuglal/full/vKxwWw/

HTML:

<div class='gameContainer'>
<div class="center"></div>
<a href="#" id="1" class="field blue"></a>
<a href="#" id="2" class="field yellow "></a>
<a href="#" id="3" class="field red"></a>
<a href="#" id="4" class="field green"></a>
</div><!--End of gameContainer-->


CSS:

function playComputerSequence(seq,speed){
//Preventing pressing not working
$('.field').each(function(){
$(this).off('click',function(e){
e.preventDefault();
});
});
//Everything below this working correctly
var count = Number($('.count span').text());
var i = 0;
var interval = setInterval(function(){
$('#'+seq[i]).addClass('on');
var audio = new Audio(audioArray[seq[i]-1]);
setTimeout(function(){
audio.play();
$('#'+seq[i]).removeClass('on');
i++;
},500)
setTimeout(function(){
if(i == count)
{
clearInterval(interval);
}
},500);
},speed);
$('.field').each(function(){
$(this).off().on('click',recordUserChoice);
});
}

function recordUserChoice(){
userArray.push(this.id);
var audio = new Audio(audioArray[this.id-1]);
setTimeout(function(){
audio.play();
},500);
checkSequence(userArray);
}

Answer

My suggestion would be to use some sort of flag to determine the state of the game.

Obviously, the .off() isn't doing the trick, so I would say remove all references to that. However, I believe the reason it is not working is because you are using it wrong. You don't need to use .each() when unbinding. That is what the selector is for, so if you use $('.field').off('click', '**') that should remove all delegated click handlers from any elements with class='field'. To read up on proper usage I would suggest looking here: http://api.jquery.com/off/

However, I still do not believe that you should be removing the delegated events. To simplify things just have a flag that can be checked to see game state.

var gameState = 0; //0 means the user can click, 1 means the user cannot

function playComputerSequence(seq, speed){
   gameState = 1;

   //Rest of function code
   //...

   gameState = 0;
}

function recordUserChoice(){
   if(gameState === 1) return; //if gameState is 1, jump out of the function

   //Rest of function code
   //...
}

While this logic works, for your situation it needs to be tailored a little differently.

At the start of your code, below your audioArray place the below code. This will be your field click handler.

$(document).on('click', '.field', recordUserChoice);

Then, one thing I realized was that gamestate basically immediately gets changed back to 0, so I instead put that below where you clearInterval(interval) since that is what determines when the computer is done going.

if(i == count)
{
   clearInterval(interval);
  gamestate = 0;
  console.log(gamestate);
}

Then you can remove all instances of $('.field').each()

See this pen: http://codepen.io/anon/pen/wWJLyp

Comments