Infinite and alternating effects

This commit is contained in:
Lukas Klingsbo
2020-05-13 23:12:29 +02:00
parent 08583abf68
commit 61d381a89f
11 changed files with 63 additions and 46 deletions

View File

@ -4,7 +4,7 @@ import 'package:flame/gestures.dart';
import 'package:flame/effects/effects.dart'; import 'package:flame/effects/effects.dart';
import 'package:flame/position.dart'; import 'package:flame/position.dart';
import './square.dart'; import 'square.dart';
class MyGame extends BaseGame with TapDetector { class MyGame extends BaseGame with TapDetector {
Square square; Square square;

View File

@ -4,7 +4,7 @@ import 'package:flame/gestures.dart';
import 'package:flame/anchor.dart'; import 'package:flame/anchor.dart';
import 'package:flame/effects/effects.dart'; import 'package:flame/effects/effects.dart';
import './square.dart'; import 'square.dart';
class MyGame extends BaseGame with TapDetector { class MyGame extends BaseGame with TapDetector {
Square square; Square square;

View File

@ -1,4 +1,4 @@
name: effects name: effects2
description: A Flame game showcasing the use of the effects api description: A Flame game showcasing the use of the effects api
version: 1.0.0+1 version: 1.0.0+1
@ -10,4 +10,4 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flame: flame:
path: ../../../ path: ../../../..

View File

@ -157,6 +157,14 @@ abstract class PositionComponent extends Component {
_effects.add(effect..component = this); _effects.add(effect..component = this);
} }
void removeEffect(PositionComponentEffect effect) {
effect.dispose();
}
void clearEffects() {
_effects.forEach(removeEffect);
}
@mustCallSuper @mustCallSuper
@override @override
void update(double dt) { void update(double dt) {

View File

@ -1,10 +1,41 @@
import 'dart:math';
import '../components/component.dart'; import '../components/component.dart';
export './move_effect.dart'; export './move_effect.dart';
export './scale_effect.dart'; export './scale_effect.dart';
abstract class PositionComponentEffect { abstract class PositionComponentEffect {
void update(double dt); bool _isDisposed = false;
bool hasFinished(); bool get isDisposed => _isDisposed;
PositionComponent component;
/// If the animation should first follow the initial curve and then follow the
/// curve backwards
bool isAlternating;
bool isInfinite;
double percentage;
double travelTime;
double _curveTime = 0.0;
int _curveDirection = 1;
PositionComponentEffect(this.isInfinite, this.isAlternating);
void update(double dt) {
_curveTime += dt * _curveDirection;
if (isAlternating) {
_curveDirection = isMax() ? -1 : (isMin() ? 1 : _curveDirection);
} else if (isInfinite && isMax()){
percentage = 0.0;
}
percentage = min(1.0, max(0.0, _curveTime / travelTime));
}
void dispose() => _isDisposed = true;
PositionComponent component;
bool hasFinished() =>
(!isInfinite && !isAlternating && isMax()) ||
(!isInfinite && isAlternating && isMin()) || isDisposed;
bool isMax() => percentage == null ? false : percentage == 1.0;
bool isMin() => percentage == null ? false : percentage == 0.0;
} }

View File

@ -7,15 +7,13 @@ import './effects.dart';
import '../position.dart'; import '../position.dart';
double _direction(double p, double d) => (p - d).sign; double _direction(double p, double d) => (p - d).sign;
double _size(double a, double b) => (a - b).abs(); double _distance(double a, double b) => (a - b).abs();
class MoveEffect extends PositionComponentEffect { class MoveEffect extends PositionComponentEffect {
Position destination; Position destination;
double speed; double speed;
Curve curve; Curve curve;
double _travelTime;
double _xOriginal; double _xOriginal;
double _xDistance; double _xDistance;
double _xDirection; double _xDirection;
@ -24,13 +22,13 @@ class MoveEffect extends PositionComponentEffect {
double _yDistance; double _yDistance;
double _yDirection; double _yDirection;
double _elapsedTime = 0.0;
MoveEffect({ MoveEffect({
@required this.destination, @required this.destination,
@required this.speed, @required this.speed,
this.curve, this.curve,
}); isInfinite = false,
isAlternating = false
}) : super(isInfinite, isAlternating);
@override @override
set component(_comp) { set component(_comp) {
@ -39,34 +37,25 @@ class MoveEffect extends PositionComponentEffect {
_xOriginal = component.x; _xOriginal = component.x;
_yOriginal = component.y; _yOriginal = component.y;
_xDistance = _size(destination.x, component.x); _xDistance = _distance(destination.x, component.x);
_yDistance = _size(destination.y, component.y); _yDistance = _distance(destination.y, component.y);
_xDirection = _direction(destination.x, component.x); _xDirection = _direction(destination.x, component.x);
_yDirection = _direction(destination.y, component.y); _yDirection = _direction(destination.y, component.y);
_travelTime = max( final totalDistance = sqrt(pow(_xDistance, 2) + pow(_yDistance, 2));
_xDistance / speed, travelTime = totalDistance / speed;
_yDistance / speed,
);
} }
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (!hasFinished()) { if (!hasFinished()) {
final double percent = min(1.0, _elapsedTime / _travelTime); final double c = curve?.transform(percentage) ?? 1.0;
final double c = curve?.transform(percent) ?? 1.0;
component.x = _xOriginal + _xDistance * c * _xDirection; component.x = _xOriginal + _xDistance * c * _xDirection;
component.y = _yOriginal + _yDistance * c * _yDirection; component.y = _yOriginal + _yDistance * c * _yDirection;
} else {
component.x = destination.x;
component.y = destination.y;
} }
_elapsedTime += dt;
} }
@override
bool hasFinished() => _elapsedTime >= _travelTime;
} }

View File

@ -15,9 +15,6 @@ class ScaleEffect extends PositionComponentEffect {
double speed; double speed;
Curve curve; Curve curve;
double _scaleTime;
double _elapsedTime = 0.0;
Size _original; Size _original;
Size _diff; Size _diff;
final Position _dir = Position.empty(); final Position _dir = Position.empty();
@ -26,7 +23,9 @@ class ScaleEffect extends PositionComponentEffect {
@required this.size, @required this.size,
@required this.speed, @required this.speed,
this.curve, this.curve,
}); isInfinite = false,
isAlternating = false
}) : super(isInfinite, isAlternating);
@override @override
set component(_comp) { set component(_comp) {
@ -41,28 +40,18 @@ class ScaleEffect extends PositionComponentEffect {
_dir.x = _direction(size.width, _original.width); _dir.x = _direction(size.width, _original.width);
_dir.y = _direction(size.height, _original.height); _dir.y = _direction(size.height, _original.height);
_scaleTime = max( final scaleDistance = sqrt(pow(_diff.width, 2) + pow(_diff.height, 2));
_diff.width / speed, travelTime = scaleDistance / speed;
_diff.height / speed,
);
} }
@override @override
void update(double dt) { void update(double dt) {
super.update(dt);
if (!hasFinished()) { if (!hasFinished()) {
final double percent = min(1.0, _elapsedTime / _scaleTime); final double c = curve?.transform(percentage) ?? 1.0;
final double c = curve?.transform(percent) ?? 1.0;
component.width = _original.width + _diff.width * c * _dir.x; component.width = _original.width + _diff.width * c * _dir.x;
component.height = _original.height + _diff.height * c * _dir.y; component.height = _original.height + _diff.height * c * _dir.y;
} else {
component.width = size.width;
component.height = size.height;
} }
_elapsedTime += dt;
} }
@override
bool hasFinished() => _elapsedTime >= _scaleTime;
} }