Refactor timer class

This commit is contained in:
Lukas Klingsbo
2020-10-22 20:15:08 +02:00
parent 11fb4580a8
commit b29e0a6f11
8 changed files with 87 additions and 79 deletions

View File

@ -3,6 +3,7 @@
## [next] ## [next]
- Improve IsometricTileMap and Spritesheet classes - Improve IsometricTileMap and Spritesheet classes
- Export full vector_math library from extension - Export full vector_math library from extension
- Refactor timer class
## 1.0.0-rc1 ## 1.0.0-rc1
- Move all box2d related code and examples to the flame_box2d repo - Move all box2d related code and examples to the flame_box2d repo

View File

@ -19,7 +19,7 @@ import 'package:flame/particles/animation_particle.dart';
import 'package:flame/particles/component_particle.dart'; import 'package:flame/particles/component_particle.dart';
import 'package:flame/flame.dart'; import 'package:flame/flame.dart';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame/time.dart' as flame_time; import 'package:flame/timer.dart' as flame_time;
import 'package:flame/particle.dart'; import 'package:flame/particle.dart';
import 'package:flame/extensions/vector2.dart'; import 'package:flame/extensions/vector2.dart';
import 'package:flame/sprite.dart'; import 'package:flame/sprite.dart';

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame/time.dart'; import 'package:flame/timer.dart';
import 'package:flame/text_config.dart'; import 'package:flame/text_config.dart';
import 'package:flame/gestures.dart'; import 'package:flame/gestures.dart';
import 'package:flame/extensions/vector2.dart'; import 'package:flame/extensions/vector2.dart';
@ -68,9 +68,11 @@ class MyGame extends Game with TapDetector {
MyGame() { MyGame() {
countdown = Timer(2); countdown = Timer(2);
interval = Timer(1, repeat: true, callback: () { interval = Timer(
elapsedSecs += 1; 1,
}); callback: () => elapsedSecs += 1,
repeat: true,
);
interval.start(); interval.start();
} }

View File

@ -59,7 +59,7 @@ import 'dart:ui';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame/text_config.dart'; import 'package:flame/text_config.dart';
import 'package:flame/time.dart'; import 'package:flame/timer.dart';
import 'package:flame/vector2.dart'; import 'package:flame/vector2.dart';
class MyGame extends Game { class MyGame extends Game {
@ -73,15 +73,18 @@ class MyGame extends Game {
@override @override
void update(double dt) { void update(double dt) {
countdown.update(dt); countdown.update(dt);
if (countdown.isFinished()) { if (countdown.finished) {
// do something ... // Prefer the timer callback, but this is better in some cases
} }
} }
@override @override
void render(Canvas canvas) { void render(Canvas canvas) {
textConfig.render(canvas, "Countdown: ${countdown.current.toString()}", textConfig.render(
Vector2(10, 100)); canvas,
"Countdown: ${countdown.current.toString()}",
Vector2(10, 100),
);
} }
} }
@ -94,7 +97,7 @@ import 'dart:ui';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
import 'package:flame/text_config.dart'; import 'package:flame/text_config.dart';
import 'package:flame/time.dart'; import 'package:flame/timer.dart';
import 'package:flame/vector2.dart'; import 'package:flame/vector2.dart';
class MyGame extends Game { class MyGame extends Game {
@ -104,9 +107,11 @@ class MyGame extends Game {
int elapsedSecs = 0; int elapsedSecs = 0;
MyGame() { MyGame() {
interval = Timer(1, repeat: true, callback: () { interval = Timer(
elapsedSecs += 1; 1,
}); callback: () => elapsedSecs += 1,
repeat: true,
);
interval.start(); interval.start();
} }
@ -128,7 +133,7 @@ Timer instances can also be used inside a `BaseGame` game by using the `TimerCom
__Timer Component__ __Timer Component__
```dart ```dart
import 'package:flame/time.dart'; import 'package:flame/timer.dart';
import 'package:flame/components/timer_component.dart'; import 'package:flame/components/timer_component.dart';
import 'package:flame/game.dart'; import 'package:flame/game.dart';
@ -136,9 +141,11 @@ class MyBaseGame extends BaseGame {
MyBaseGame() { MyBaseGame() {
add( add(
TimerComponent( TimerComponent(
Timer(10, repeat: true, callback: () { Timer(
print("10 seconds elapsed"); 10,
}) callback: () => print("10 seconds elapsed"),
repeat: true,
)
..start() ..start()
) )
); );

View File

@ -1,6 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import '../time.dart'; import '../timer.dart';
import 'component.dart'; import 'component.dart';
/// Simple component which wraps a [Timer] instance allowing it to be easily used inside a [BaseGame] game. /// Simple component which wraps a [Timer] instance allowing it to be easily used inside a [BaseGame] game.
@ -19,5 +19,5 @@ class TimerComponent extends Component {
void render(Canvas canvas) {} void render(Canvas canvas) {}
@override @override
bool destroy() => timer.isFinished(); bool destroy() => timer.finished;
} }

View File

@ -12,7 +12,7 @@ import 'particles/moving_particle.dart';
import 'particles/rotating_particle.dart'; import 'particles/rotating_particle.dart';
import 'particles/scaled_particle.dart'; import 'particles/scaled_particle.dart';
import 'particles/translated_particle.dart'; import 'particles/translated_particle.dart';
import 'time.dart'; import 'timer.dart';
/// A function which returns [Particle] when called /// A function which returns [Particle] when called
typedef ParticleGenerator = Particle Function(int); typedef ParticleGenerator = Particle Function(int);
@ -84,10 +84,6 @@ abstract class Particle {
/// Marks [Particle] for destroy when it is over. /// Marks [Particle] for destroy when it is over.
void update(double dt) { void update(double dt) {
_timer.update(dt); _timer.update(dt);
if (_timer.progress >= 1) {
_shouldBeDestroyed = true;
}
} }
/// A control method allowing a parent of this [Particle] /// A control method allowing a parent of this [Particle]
@ -98,7 +94,8 @@ abstract class Particle {
void setLifespan(double lifespan) { void setLifespan(double lifespan) {
_lifespan = lifespan; _lifespan = lifespan;
_timer?.stop(); _timer?.stop();
_timer = Timer(lifespan); final void Function() destroyCallback = () => _shouldBeDestroyed = true;
_timer = Timer(lifespan, callback: destroyCallback);
_timer.start(); _timer.start();
} }

View File

@ -1,53 +0,0 @@
/// Simple utility class that helps handling time counting and implementing interval like events.
///
class Timer {
final double _limit;
void Function() _callback;
bool _repeat;
double _current = 0;
bool _running = false;
Timer(this._limit, {bool repeat = false, void Function() callback}) {
_repeat = repeat;
_callback = callback;
}
double get current => _current;
void update(double dt) {
if (_running) {
_current += dt;
if (isFinished()) {
if (_repeat) {
_current -= _limit;
} else {
_running = false;
}
if (_callback != null) {
_callback();
}
}
}
}
bool isFinished() {
return _current >= _limit;
}
bool isRunning() => _running;
void start() {
_current = 0;
_running = true;
}
void stop() {
_current = 0;
_running = false;
}
/// A value between 0 and 1 indicating the timer progress
double get progress => _current / _limit;
}

54
lib/timer.dart Normal file
View File

@ -0,0 +1,54 @@
import 'dart:math';
/// Simple utility class that helps handling time counting and implementing
/// interval like events.
class Timer {
final double limit;
void Function() callback;
bool repeat;
double _current = 0;
bool _running = false;
Timer(this.limit, {this.callback, this.repeat = false});
/// The current amount of ms that has passed on this iteration
double get current => _current;
/// If the timer is finished, timers that repeat never finish
bool get finished => _current >= limit && !repeat;
/// Whether the timer is running or not
bool isRunning() => _running;
/// A value between 0.0 and 1.0 indicating the timer progress
double get progress => max(_current / limit, 1.0);
void update(double dt) {
if (_running) {
_current += dt;
if (_current >= limit) {
if (!repeat) {
_running = false;
return;
}
// This is used to cover the rare case of _current being more than
// two times the value of limit, so that the callback is called the
// correct number of times
while(_current >= limit) {
_current -= limit;
callback?.call();
}
}
}
}
void start() {
_current = 0;
_running = true;
}
void stop() {
_current = 0;
_running = false;
}
}