Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/flame/other/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class MyGame extends Game {
style: const TextStyle(color: Colors.white, fontSize: 20),
);

final countdown = Timer(2);
final countdown = Timer(period: 2);

@override
void update(double dt) {
Expand Down Expand Up @@ -110,7 +110,7 @@ class MyGame extends Game {

MyGame() {
interval = Timer(
1,
period: 1,
onTick: () => elapsedSecs += 1,
repeat: true,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ class EnemyCreator extends TimerComponent with HasGameRef<RogueShooterGame> {
final Random random = Random();
final _halfWidth = EnemyComponent.initialSize.x / 2;

EnemyCreator() : super(period: 0.05, repeat: true);
EnemyCreator() : super(period: 0.05, repeat: true) {
timer.onTick = _spawn;
}

@override
void onTick() {
void _spawn() {
gameRef.enemyGroup.addAll(
List.generate(
5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class CalculatePrimeNumber extends PositionComponent

@override
Future<void> onMount() {
_interval = Timer(0.4, repeat: true, onTick: _checkNextAgainstPrime)
_interval = Timer(period: 0.4, repeat: true, onTick: _checkNextAgainstPrime)
..start();
return super.onMount();
}
Expand Down
4 changes: 2 additions & 2 deletions examples/lib/stories/utils/timer_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ class TimerExample extends FlameGame with TapCallbacks {

@override
Future<void> onLoad() async {
countdown = Timer(5);
countdown = Timer(period: 5);
interval = Timer(
1,
period: 1,
onTick: () => elapsedSecs += 1,
repeat: true,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/flame/lib/src/components/spawn_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class SpawnComponent extends Component {
double get period => _period;
set period(double newPeriod) {
_period = newPeriod;
timer.limit = _period;
timer.period = _period;
}

double _period;
Expand Down
20 changes: 6 additions & 14 deletions packages/flame/lib/src/components/timer_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ import 'package:meta/meta.dart';
class TimerComponent extends Component {
late final Timer timer;
final bool removeOnFinish;
final VoidCallback? _onTick;
final bool tickWhenLoaded;

/// Creates a [TimerComponent]
///
/// [period] The period of time in seconds that the tick will be called
/// [repeat] When true, this will continue running after [period] is reached
/// [autoStart] When true, will start upon instantiation (default is true)
/// [_onTick] When provided, will be called every time [period] is reached.
/// This overrides the [_onTick] method
/// [tickWhenLoaded] When true, will call [_onTick] when the component is
/// [onTick] When provided, will be called every time [period] is reached.
/// It can be changed later through [Timer.onTick] on [timer].
/// [tickWhenLoaded] When true, will call [onTick] when the component is
/// first loaded (default is false).
/// [tickCount] The number of time the timer will tick before stopping.
/// This is is only used when [repeat] is true. If null,
Expand All @@ -29,13 +28,13 @@ class TimerComponent extends Component {
bool repeat = false,
bool autoStart = true,
this.removeOnFinish = false,
this._onTick,
VoidCallback? onTick,
this.tickWhenLoaded = false,
int? tickCount,
super.key,
}) {
timer = Timer(
period,
period: period,
repeat: repeat,
onTick: onTick,
autoStart: autoStart,
Expand All @@ -49,17 +48,10 @@ class TimerComponent extends Component {
await super.onLoad();

if (tickWhenLoaded) {
onTick();
timer.onTick?.call();
}
}

/// Called every time the [timer] reached a tick.
/// The default implementation calls the closure received on the
/// constructor and can be overridden to add custom logic.
void onTick() {
_onTick?.call();
}

@override
void update(double dt) {
timer.update(dt);
Expand Down
22 changes: 11 additions & 11 deletions packages/flame/lib/src/timer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import 'dart:ui';
///
/// Timer auto-starts by default.
///
/// NOTE: You can change the [limit], but keep in mind that the timer
/// won't start automatically if the limit is raised and the timer currently
/// NOTE: You can change the [period], but keep in mind that the timer
/// won't start automatically if the period is raised and the timer currently
/// is stopped.
class Timer {
double limit;
double period;
VoidCallback? onTick;
bool repeat;
double _current = 0;
bool _running;
final int? tickCount;
int _currentTick = 0;

Timer(
this.limit, {
Timer({
required this.period,
this.onTick,
this.repeat = false,
bool autoStart = true,
Expand All @@ -35,29 +35,29 @@ class Timer {

/// If the timer is finished, timers that repeat never finish
bool get finished =>
(_current >= limit && !repeat) ||
(_current >= period && !repeat) ||
(tickCount != null && _currentTick >= tickCount!);

/// 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 => min(_current / limit, 1.0);
double get progress => min(_current / period, 1.0);

void update(double dt) {
if (_running) {
_current += dt;
if (_current >= limit) {
if (_current >= period) {
if (!repeat) {
_running = false;
_callTicker();
return;
}
// This is used to cover the rare case of _current being more than
// two times the value of limit, so that the onTick is called the
// two times the value of period, so that the onTick is called the
// correct number of times
while (_current >= limit) {
_current -= limit;
while (_current >= period) {
_current -= period;
_callTicker();
}
}
Expand Down
12 changes: 8 additions & 4 deletions packages/flame/test/components/timer_component_test.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -13,8 +15,9 @@ class _MyTimerComponent extends TimerComponent {
);

@override
void onTick() {
count++;
FutureOr<void> onLoad() {
timer.onTick = () => count++;
return super.onLoad();
}
}

Expand All @@ -30,8 +33,9 @@ class _MyTickOnLoadTimerComponent extends TimerComponent {
);

@override
void onTick() {
count++;
FutureOr<void> onLoad() {
timer.onTick = () => count++;
return super.onLoad();
}
}

Expand Down
22 changes: 13 additions & 9 deletions packages/flame/test/timer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:test/test.dart';
void main() {
group('Timer', () {
test('can be started and stopped, discarding progress', () {
final timer = Timer(1.0, autoStart: false);
final timer = Timer(period: 1.0, autoStart: false);
expect(timer.isRunning(), false);
timer.start();
expect(timer.isRunning(), true);
Expand All @@ -15,7 +15,7 @@ void main() {
});

test('can be paused and resumed, retaining progress', () {
final timer = Timer(1.0, autoStart: false);
final timer = Timer(period: 1.0, autoStart: false);
expect(timer.isRunning(), false);
timer.start();
expect(timer.isRunning(), true);
Expand All @@ -28,15 +28,15 @@ void main() {
});

test('tracks current delta time', () {
final timer = Timer(1.0);
final timer = Timer(period: 1.0);
timer.update(0.5);
expect(timer.current, 0.5);
timer.update(0.2);
expect(timer.current, 0.7);
});

test('tracks progress percent capped at 1.0', () {
final timer = Timer(2.0);
final timer = Timer(period: 2.0);
timer.update(0.5);
expect(timer.progress, 0.25);
timer.update(0.5);
Expand All @@ -47,7 +47,7 @@ void main() {

test('onTick fires once if non-repeating', () {
var onTickCount = 0;
final timer = Timer(1.0, onTick: () => onTickCount++);
final timer = Timer(period: 1.0, onTick: () => onTickCount++);
timer.update(0.9);
expect(onTickCount, 0);
timer.update(0.2);
Expand All @@ -57,15 +57,19 @@ void main() {
});

test('finishes when complete if non-repeating', () {
final timer = Timer(1.0);
final timer = Timer(period: 1.0);
expect(timer.finished, false);
timer.update(1.1);
expect(timer.finished, true);
});

test('onTick fires repeatedly if repeating', () {
var onTickCount = 0;
final timer = Timer(1.0, repeat: true, onTick: () => onTickCount++);
final timer = Timer(
period: 1.0,
repeat: true,
onTick: () => onTickCount++,
);
timer.update(0.9);
expect(onTickCount, 0);
timer.update(0.2);
Expand All @@ -75,7 +79,7 @@ void main() {
});

test('does not finish past limit if repeating', () {
final timer = Timer(1.0, repeat: true);
final timer = Timer(period: 1.0, repeat: true);
expect(timer.finished, false);
timer.update(1.1);
expect(timer.finished, false);
Expand All @@ -84,7 +88,7 @@ void main() {
test('when tickCount is provided, tick only the provided amount', () {
var count = 0;
final timer = Timer(
1,
period: 1,
repeat: true,
tickCount: 2,
onTick: () {
Expand Down
4 changes: 2 additions & 2 deletions packages/flame_behavior_tree/lib/src/has_behavior_tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ mixin HasBehaviorTree<T extends NodeInterface> on Component
_tickInterval = interval;

if (_tickInterval > 0) {
_timer ??= Timer(interval, repeat: true);
_timer?.limit = interval;
_timer ??= Timer(period: interval, repeat: true);
_timer?.period = interval;
} else {
_timer?.onTick = null;
_timer = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import 'package:flame_bloc_example/src/game/game.dart';
class EnemyCreator extends TimerComponent with HasGameRef<SpaceShooterGame> {
Random random = Random();

EnemyCreator() : super(period: 1, repeat: true);
EnemyCreator() : super(period: 1, repeat: true) {
timer.onTick = _spawn;
}

@override
void onTick() {
void _spawn() {
gameRef.add(
EnemyComponent(
(gameRef.size.x - 25) * random.nextDouble(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PlayerComponent extends SpriteAnimationComponent

PlayerComponent()
: super(size: Vector2(50, 75), position: Vector2(100, 500)) {
bulletCreator = Timer(0.5, repeat: true, onTick: _createBullet);
bulletCreator = Timer(period: 0.5, repeat: true, onTick: _createBullet);

add(RectangleHitbox());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class WorkerOvermind extends Component
@override
Future<void> onMount() {
calculateTasks();
_assignTaskInterval = Timer(0.2, repeat: true, onTick: _assignTasks)
_assignTaskInterval = Timer(period: 0.2, repeat: true, onTick: _assignTasks)
..start();
return super.onMount();
}
Expand Down
Loading