【问题标题】:Flutter : Timer.periodic running multiple times in each iterationFlutter : Timer.periodic 在每次迭代中运行多次
【发布时间】:2021-02-23 13:42:25
【问题描述】:

我正在尝试让蛇 2 颤动。我已经使用 Timer.periodic() 进行游戏循环。我尝试将持续时间指定为 1 秒。但是 Timer.periodic() 中的代码在一秒钟内运行多次。我也尝试过调试(虽然我很糟糕),发现 Timer.periodic() 中的代码运行了多次而没有退出。尽管在调试时,这可能会在代码暂停输入时发生。但我不确定。这是我的代码 -

import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';

class SnakePage extends StatefulWidget {
  @override
  _SnakePageState createState() => _SnakePageState();
}

class _SnakePageState extends State<SnakePage> {
  int score = 0;
  String swipe = '';
  bool running = false;
  int iterates = 0;
  List snake = [
    [
      [4, 3],
      1,
      true
    ],
    [
      [4, 2],
      1,
      false
    ],
    [
      [4, 1],
      1,
      false
    ],
  ];

  // Convert radians to degree
  double radians(double degree) {
    return ((degree * 180) / pi);
  }

  void turn(moveEvent) {
       double angle = radians(moveEvent.delta.direction);
      if (angle >= -45 && angle <= 45) {
        this.swipe = 'Swipe Right';
      } else if (angle >= 45 && angle <= 135) {
        this.swipe = 'Swipe Down';
      } else if (angle <= -45 && angle >= -135) {
        this.swipe = 'Swipe Up';
      } else {
        this.swipe = 'Swipe Left';
      }
  }

  int toIndex(coOrdinates) {
    return ((coOrdinates[0] + 1) * 10) + coOrdinates[1];
  }

  void run() {
    this.running = true;
    Timer.periodic(
        Duration(
          milliseconds: 500,
        ), (timer) {
      this.setState(() {
        this.iterates += 1;
        this.swipe = this.iterates.toString();
        for (var i = 0; i < this.snake.length; i++) {
          this.snake[i][0][1] += 1;
          if (this.snake[i][0][1] == 10) {
            this.snake[i][0][1] = 0;
          }
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WC'),
      ),
      body: Listener(
            onPointerMove: this.running
                ? (moveEvent) => this.turn(moveEvent)
                : (moveEvent) => this.run(),// Where the function is being called
            child: Container();
    );
  }
}

请原谅我的代码是一团糟,没有很好的评论。 任何帮助将不胜感激!

【问题讨论】:

    标签: flutter dart mobile-development


    【解决方案1】:

    问题在于,每次执行run() 方法时,都会创建一个新的计时器并再次监听它。老定时器没有停止,所以它一直在触发。 解决方案是,在创建计时器之前,取消前一个计时器。像这样的:

    class _SnakePageState extends State<SnakePage> {
       Timer _myTimer;
    
    void run() {
        this.running = true;
        _myTimer?.cancel(); //in case we have a timer, we'll cancel it.
        _myTimer = Timer.periodic(. // assing new timer to our variable.
            Duration(
              milliseconds: 500,
            ), (timer) {
          this.setState(() {
            this.iterates += 1;
            this.swipe = this.iterates.toString();
            for (var i = 0; i < this.snake.length; i++) {
              this.snake[i][0][1] += 1;
              if (this.snake[i][0][1] == 10) {
                this.snake[i][0][1] = 0;
              }
            }
          });
        });
      }
    
     
    }
    

    【讨论】:

    • 但是我创建了一个正在运行的变量,一旦调用该函数,它就会设置为 true,然后它调用与 Timer.periodic() 无关的轮换函数,尽管您给定的解决方案适用于我,但我不明白 run 函数是如何被多次调用的。
    • @PriyanshuJangra 你的running 变量不会停止定时器块的执行,如果定时器没有被取消。
    【解决方案2】:

    只需添加return timer.cancel();

    像这样:

    Timer.periodic(
        Duration(
          milliseconds: 500,
        ), (timer) {
      // your code
        return timer.cancel();
    });
    

    尝试一下,它会起作用的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多