mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 10:38:17 +08:00
Merge branch 'v1.0.0' into erick.ensure-animation-initialization
This commit is contained in:
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@ -17,8 +17,8 @@ Please delete options that are not relevant.
|
||||
|
||||
If something is unclear, please submit the PR anyways and ask about what you thought was unclear.
|
||||
|
||||
- [ ] This branch is based on `develop`
|
||||
- [ ] This PR is targeted to merge into `develop` (not `master`)
|
||||
- [ ] This branch is based on `v1.0.0`
|
||||
- [ ] This PR is targeted to merge into `v1.0.0` (not `master` or `develop`)
|
||||
- [ ] I have added an entry under `[next]` in `CHANGELOG.md`
|
||||
- [ ] I have formatted my code with `flutter format`
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
- Improve IsometricTileMap and Spritesheet classes
|
||||
- Export full vector_math library from extension
|
||||
- Ensuring sprite animation and sprite animation components don't get NPEs on initialization
|
||||
- Refactor timer class
|
||||
|
||||
## 1.0.0-rc1
|
||||
- Move all box2d related code and examples to the flame_box2d repo
|
||||
|
||||
@ -19,7 +19,7 @@ import 'package:flame/particles/animation_particle.dart';
|
||||
import 'package:flame/particles/component_particle.dart';
|
||||
import 'package:flame/flame.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/extensions/vector2.dart';
|
||||
import 'package:flame/sprite.dart';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.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/gestures.dart';
|
||||
import 'package:flame/extensions/vector2.dart';
|
||||
@ -68,9 +68,11 @@ class MyGame extends Game with TapDetector {
|
||||
|
||||
MyGame() {
|
||||
countdown = Timer(2);
|
||||
interval = Timer(1, repeat: true, callback: () {
|
||||
elapsedSecs += 1;
|
||||
});
|
||||
interval = Timer(
|
||||
1,
|
||||
callback: () => elapsedSecs += 1,
|
||||
repeat: true,
|
||||
);
|
||||
interval.start();
|
||||
}
|
||||
|
||||
|
||||
33
doc/util.md
33
doc/util.md
@ -59,7 +59,7 @@ import 'dart:ui';
|
||||
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/text_config.dart';
|
||||
import 'package:flame/time.dart';
|
||||
import 'package:flame/timer.dart';
|
||||
import 'package:flame/vector2.dart';
|
||||
|
||||
class MyGame extends Game {
|
||||
@ -73,15 +73,18 @@ class MyGame extends Game {
|
||||
@override
|
||||
void update(double dt) {
|
||||
countdown.update(dt);
|
||||
if (countdown.isFinished()) {
|
||||
// do something ...
|
||||
if (countdown.finished) {
|
||||
// Prefer the timer callback, but this is better in some cases
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void render(Canvas canvas) {
|
||||
textConfig.render(canvas, "Countdown: ${countdown.current.toString()}",
|
||||
Vector2(10, 100));
|
||||
textConfig.render(
|
||||
canvas,
|
||||
"Countdown: ${countdown.current.toString()}",
|
||||
Vector2(10, 100),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +97,7 @@ import 'dart:ui';
|
||||
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/text_config.dart';
|
||||
import 'package:flame/time.dart';
|
||||
import 'package:flame/timer.dart';
|
||||
import 'package:flame/vector2.dart';
|
||||
|
||||
class MyGame extends Game {
|
||||
@ -104,9 +107,11 @@ class MyGame extends Game {
|
||||
int elapsedSecs = 0;
|
||||
|
||||
MyGame() {
|
||||
interval = Timer(1, repeat: true, callback: () {
|
||||
elapsedSecs += 1;
|
||||
});
|
||||
interval = Timer(
|
||||
1,
|
||||
callback: () => elapsedSecs += 1,
|
||||
repeat: true,
|
||||
);
|
||||
interval.start();
|
||||
}
|
||||
|
||||
@ -128,7 +133,7 @@ Timer instances can also be used inside a `BaseGame` game by using the `TimerCom
|
||||
__Timer Component__
|
||||
|
||||
```dart
|
||||
import 'package:flame/time.dart';
|
||||
import 'package:flame/timer.dart';
|
||||
import 'package:flame/components/timer_component.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
@ -136,9 +141,11 @@ class MyBaseGame extends BaseGame {
|
||||
MyBaseGame() {
|
||||
add(
|
||||
TimerComponent(
|
||||
Timer(10, repeat: true, callback: () {
|
||||
print("10 seconds elapsed");
|
||||
})
|
||||
Timer(
|
||||
10,
|
||||
callback: () => print("10 seconds elapsed"),
|
||||
repeat: true,
|
||||
)
|
||||
..start()
|
||||
)
|
||||
);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import '../time.dart';
|
||||
import '../timer.dart';
|
||||
import 'component.dart';
|
||||
|
||||
/// 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) {}
|
||||
|
||||
@override
|
||||
bool destroy() => timer.isFinished();
|
||||
bool destroy() => timer.finished;
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import 'particles/moving_particle.dart';
|
||||
import 'particles/rotating_particle.dart';
|
||||
import 'particles/scaled_particle.dart';
|
||||
import 'particles/translated_particle.dart';
|
||||
import 'time.dart';
|
||||
import 'timer.dart';
|
||||
|
||||
/// A function which returns [Particle] when called
|
||||
typedef ParticleGenerator = Particle Function(int);
|
||||
@ -84,10 +84,6 @@ abstract class Particle {
|
||||
/// Marks [Particle] for destroy when it is over.
|
||||
void update(double dt) {
|
||||
_timer.update(dt);
|
||||
|
||||
if (_timer.progress >= 1) {
|
||||
_shouldBeDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// A control method allowing a parent of this [Particle]
|
||||
@ -98,7 +94,8 @@ abstract class Particle {
|
||||
void setLifespan(double lifespan) {
|
||||
_lifespan = lifespan;
|
||||
_timer?.stop();
|
||||
_timer = Timer(lifespan);
|
||||
final void Function() destroyCallback = () => _shouldBeDestroyed = true;
|
||||
_timer = Timer(lifespan, callback: destroyCallback);
|
||||
_timer.start();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
62
lib/timer.dart
Normal file
62
lib/timer.dart
Normal file
@ -0,0 +1,62 @@
|
||||
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;
|
||||
}
|
||||
|
||||
void pause() {
|
||||
_running = false;
|
||||
}
|
||||
|
||||
void resume() {
|
||||
_running = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user