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/position.dart';
import './square.dart';
import 'square.dart';
class MyGame extends BaseGame with TapDetector {
Square square;

View File

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

View File

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

View File

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

View File

@ -1,10 +1,41 @@
import 'dart:math';
import '../components/component.dart';
export './move_effect.dart';
export './scale_effect.dart';
abstract class PositionComponentEffect {
void update(double dt);
bool hasFinished();
PositionComponent component;
bool _isDisposed = false;
bool get isDisposed => _isDisposed;
/// 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';
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 {
Position destination;
double speed;
Curve curve;
double _travelTime;
double _xOriginal;
double _xDistance;
double _xDirection;
@ -24,13 +22,13 @@ class MoveEffect extends PositionComponentEffect {
double _yDistance;
double _yDirection;
double _elapsedTime = 0.0;
MoveEffect({
@required this.destination,
@required this.speed,
this.curve,
});
isInfinite = false,
isAlternating = false
}) : super(isInfinite, isAlternating);
@override
set component(_comp) {
@ -39,34 +37,25 @@ class MoveEffect extends PositionComponentEffect {
_xOriginal = component.x;
_yOriginal = component.y;
_xDistance = _size(destination.x, component.x);
_yDistance = _size(destination.y, component.y);
_xDistance = _distance(destination.x, component.x);
_yDistance = _distance(destination.y, component.y);
_xDirection = _direction(destination.x, component.x);
_yDirection = _direction(destination.y, component.y);
_travelTime = max(
_xDistance / speed,
_yDistance / speed,
);
final totalDistance = sqrt(pow(_xDistance, 2) + pow(_yDistance, 2));
travelTime = totalDistance / speed;
}
@override
void update(double dt) {
super.update(dt);
if (!hasFinished()) {
final double percent = min(1.0, _elapsedTime / _travelTime);
final double c = curve?.transform(percent) ?? 1.0;
final double c = curve?.transform(percentage) ?? 1.0;
component.x = _xOriginal + _xDistance * c * _xDirection;
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;
Curve curve;
double _scaleTime;
double _elapsedTime = 0.0;
Size _original;
Size _diff;
final Position _dir = Position.empty();
@ -26,7 +23,9 @@ class ScaleEffect extends PositionComponentEffect {
@required this.size,
@required this.speed,
this.curve,
});
isInfinite = false,
isAlternating = false
}) : super(isInfinite, isAlternating);
@override
set component(_comp) {
@ -41,28 +40,18 @@ class ScaleEffect extends PositionComponentEffect {
_dir.x = _direction(size.width, _original.width);
_dir.y = _direction(size.height, _original.height);
_scaleTime = max(
_diff.width / speed,
_diff.height / speed,
);
final scaleDistance = sqrt(pow(_diff.width, 2) + pow(_diff.height, 2));
travelTime = scaleDistance / speed;
}
@override
void update(double dt) {
super.update(dt);
if (!hasFinished()) {
final double percent = min(1.0, _elapsedTime / _scaleTime);
final double c = curve?.transform(percent) ?? 1.0;
final double c = curve?.transform(percentage) ?? 1.0;
component.width = _original.width + _diff.width * c * _dir.x;
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;
}