Flutter : Timer.periodic 运行 每次迭代多次
Flutter : Timer.periodic running multiple times in each iteration
我正在尝试让 snake 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();
);
}
}
请原谅我的代码一团糟而且没有很好的注释。
任何帮助将不胜感激!
问题是,每次执行 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;
}
}
});
});
}
}
只需添加 return timer.cancel();
像这样:
Timer.periodic(
Duration(
milliseconds: 500,
), (timer) {
// your code
return timer.cancel();
});
尝试一下,它会起作用
我正在尝试让 snake 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();
);
}
}
请原谅我的代码一团糟而且没有很好的注释。 任何帮助将不胜感激!
问题是,每次执行 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;
}
}
});
});
}
}
只需添加 return timer.cancel();
像这样:
Timer.periodic(
Duration(
milliseconds: 500,
), (timer) {
// your code
return timer.cancel();
});
尝试一下,它会起作用