mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-03 12:28:03 +08:00
Infinite and alternating effects
This commit is contained in:
@ -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;
|
||||
@ -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;
|
||||
@ -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: ../../../..
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user