0

I am refactoring my old Simon game into HTML5 Canvas with React.js. Currently, I am having a hard time figuring out how to control the demo light sequence. It kept playing all the lights at the same time. I redraw the canvas when I call 'drawcircle'. For full code view, it is on my CodePen https://codepen.io/pkshreeman/pen/ZyLEoB?editors=0110 Click Power button, and play a few cycles, and you will see what I am talking about.

function demoLight(current,i){
setTimeout(() => drawcircle(current.matchMe[i],current.matchMe[i]), 500);
setTimeout(()=> {console.log('timeout .5 sec' )}, 500);
setTimeout(() => drawcircle(current.matchMe[i], current[current.matchMe[i]]), 800);
setTimeout(()=> {'timeout part 2 0.5 sec'}, 500);
}
//demo function
function demoMatch(current){ //enter this.state as current
  console.log('demo on the level of '+ current.level)
  for( let i = 0 ; i < current.level; i++){
    setTimeout(()=>{demoLight(current,i)}),2200
  }
}

In case you need to see the drawcircle function:

function drawcircle(id, color) {
  var context = document.getElementById(id).getContext("2d");
  var x = 75;
  var y = 75;

  switch (id) {
    case 'purple':
      x = -10;
      y = -10;
      break;

    case 'pink':
      x = 160;
      y = -10;
      break;

    case 'blue':
      x = -10;
      y = 160;
      break;

    case 'green':
      x = 160;
      y = 160;
      break;
  }
  context.beginPath();
  context.arc(x, y, 115, 0 * Math.PI, 2 * Math.PI, true);
  context.strokeStyle = color;
  context.lineWidth = 85;
  context.stroke();
}

1 Answers1

0

The setTimeouts does not prevent the async operations, so overlapping setTimeouts can occur if you trigger multiple setTimeout like you did in the loop.

The change I made to the code was based on the answers provided in this question: how to control for-loop exection in javascript [what should this javascript code do]...

function demoMatch(current){ //enter this.state as current
  console.log('demo on the level of '+ current.level)
  //for( let i = 0 ; i < current.level; i++){
  let i = 0;
    let intervalHandler = setInterval( function() { 
        demoLight(current,i)
        if( i === current.level - 1 ) {
             clearInterval( intervalHandler );
             return;
        }
        i++;
    }, 1000 );
}