Реактивное обновление свойства в setInterval работает дважды - PullRequest
0 голосов
/ 18 января 2020

Вкратце: почему в setInterval, обновляя переменную, которая должна быть обновлена ​​один раз, она обновляется дважды?

compTurn() {
      let intervalId = setInterval(()=> {
        if (this.flash==this.round) {
          clearInterval(intervalId);
        }
        if (this.seq[this.flash]==1){
          this.greenFlash();
        }
        if (this.seq[this.flash]==2){
          this.yellowFlash();
        }
        if (this.seq[this.flash]==3){
          this.blueFlash();
        }
        if (this.seq[this.flash]==4){
          this.redFlash();
        }
        this.flash++;
      }
      , 1500);  
    }

Мое первое небольшое игровое приложение содержит кнопки, которые меняют свои цвета в некоторых условиях в соответствии с заданным последовательность. это происходит в методе compTurn. каждый раз, когда цвет меняется, счетчик fla sh увеличивается. Игра начинается с раунда = 1 и должна расти, когда игрок в порядке. (код не заполнен в данный момент) Например, в первом раунде одна кнопка мигает (меняет цвет), а затем увеличивается sh, а затем интервал должен заканчиваться.

Но в setInterval, в compTurn, fla sh обновляется дважды (в первом раунде fla sh превращается в 2).

Требуется некоторая помощь.

Отредактировано: также, когда сессия завершена, когда я нажимаю кнопку пуска снова - ничего не происходит (при нажатии не начинается воспроизведение () снова. Как я могу это сделать? (Я хочу, чтобы пользователь перезапустил игру, нажав кнопку пуска снова).

Полный код, над которым я сейчас работаю, находится здесь:

export default class App extends Component{ 
  constructor (props){
    super(props);
    this.flash=0
    this.round=1
    this.seq=[1,2,3,1,4] //will be random, this is just for testing
    this.playerSeq=[] 
    this.win=false
    this.ok=true
    this.score=0
    this.state = {
      renderView: false,
      greenB: {
        backgroundColor: 'darkgreen'
      },
      yellowB: {
        backgroundColor: 'orange'
      },
      blueB: {
        backgroundColor: 'blue'
      },
      redB: {
        backgroundColor: 'red'
      }
    }
    this.play=this.play.bind(this)
    this.greenFlash=this.greenFlash.bind(this)
    this.blueFlash=this.blueFlash.bind(this)
    this.redFlash=this.redFlash.bind(this)
  }

  play(){
    for (var i=0;i<this.round;i++){
      this.compTurn();
      //this.playerTurn();
    }
  }

  playerTurn(){
    //
  }
  compTurn() {
      let intervalId = setInterval(()=> {
        if (this.flash==this.round) {
          clearInterval(intervalId);
        }
        if (this.seq[this.flash]==1){
          this.greenFlash();
        }
        if (this.seq[this.flash]==2){
          this.yellowFlash();
        }
        if (this.seq[this.flash]==3){
          this.blueFlash();
        }
        if (this.seq[this.flash]==4){
          this.redFlash();
        }
        this.flash++;
      }
      , 1500);  
    }

  greenFlash(){
      setTimeout(() => {
        this.setState( {
            greenB:{
              ...this.state.style1, backgroundColor: 'lightgreen'
            }
            })
        }, 200);
      setTimeout(() => {
        this.setState( {
            greenB:{
              ...this.state.style1, backgroundColor: 'darkgreen'
            }
            })
        }, 1000);
    } 

  yellowFlash(){
    setTimeout(() => {
      this.setState( {
          yellowB:{
            ...this.state.style1, backgroundColor: 'yellow'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          yellowB:{
            ...this.state.style1, backgroundColor: 'orange'
          }
          })
        }, 1000);
   }

  blueFlash(){
    setTimeout(() => {
      this.setState( {
          blueB:{
            ...this.state.style1, backgroundColor: 'lightblue'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          blueB:{
            ...this.state.style1, backgroundColor: 'blue'
          }
          })
        }, 1000);
   }

  redFlash(){
    setTimeout(() => {
      this.setState( {
          redB:{
            ...this.state.style1, backgroundColor: 'pink'
          }
          })
      }, 200);
    setTimeout(() => {
      this.setState( {
          redB:{
            ...this.state.style1, backgroundColor: 'red'
          }
          })
        }, 1000);
   }

  render(){
    return (
      <View>
        <TouchableOpacity style={styles.playB}
        onPress={this.play}> 
        <Text style={{
          color:'white',
          height: 30,
          width:60,
          }}>START</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.greenB, this.state.greenB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.yellowB, this.state.yellowB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.blueB, this.state.blueB]}></TouchableOpacity>
        <TouchableOpacity style={[styles.redB, this.state.redB]}></TouchableOpacity>
    </View>
    );
  }
}

const styles = StyleSheet.create({
  greenB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  yellowB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  blueB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  redB:{
    padding: 5,
    height: 80,
    width: 80,  
    borderRadius:160,    
  },
  playB:{
    alignSelf: 'center',
    backgroundColor: 'blue',
  }

});

1 Ответ

0 голосов
/ 18 января 2020

Начальное значение fla sh равно 0, поэтому функция вызывается, когда значение fla sh равно 0 и 1. В этом проблема. Если вы хотите, чтобы значение fla sh равнялось 1, вы должны вернуть значение после clearInterval(intervalId);

. Если this.flash равно 1, он очищаетInterval и запускает следующий скрипт, и он становится равным 2.

compTurn() {
      let intervalId = setInterval(()=> {
        if (this.flash==this.round) {
          clearInterval(intervalId);
        }
        if (this.seq[this.flash]==1){
          this.greenFlash();
        }
        if (this.seq[this.flash]==2){
          this.yellowFlash();
        }
        if (this.seq[this.flash]==3){
          this.blueFlash();
        }
        if (this.seq[this.flash]==4){
          this.redFlash();
        }
        this.flash++;
      }
      , 1500);  
    }
    ```
...