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/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;
|
||||||
@ -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;
|
||||||
@ -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: ../../../..
|
||||||
@ -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) {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
/// 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;
|
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';
|
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user