mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 19:12:31 +08:00
Use a list of vector2 for MoveEffect
This commit is contained in:
committed by
Lukas Klingsbo
parent
ba02032c68
commit
b60f45c388
@ -13,7 +13,7 @@
|
||||
- Make `Resizable` have a `gameSize` property instead of `size`
|
||||
- Fix bug with CombinedEffect inside SequenceEffect
|
||||
- Fix wrong end angle for relative rotational effects
|
||||
- Use a list of Vector2 for Move effect to open up for more capabilities
|
||||
- Use a list of Vector2 for Move effect to open up for more advanced move effects
|
||||
|
||||
## [next]
|
||||
- Fix spriteAsWidget deprecation message
|
||||
|
||||
@ -20,7 +20,7 @@ When an effect is completed the callback `onComplete` will be called, it can be
|
||||
|
||||
## MoveEffect
|
||||
|
||||
Applied to `PositionComponent`s, this effect can be used to move the component to a new position, using an [animation curve](https://api.flutter.dev/flutter/animation/Curves-class.html).
|
||||
Applied to `PositionComponent`s, this effect can be used to move the component to a new positions, using an [animation curve](https://api.flutter.dev/flutter/animation/Curves-class.html).
|
||||
|
||||
Usage example:
|
||||
```dart
|
||||
@ -28,12 +28,18 @@ import 'package:flame/effects/effects.dart';
|
||||
|
||||
// Square is a PositionComponent
|
||||
square.addEffect(MoveEffect(
|
||||
destination: Position(200, 200),
|
||||
path: [Vector2(200, 200), Vector2(200, 100), Vector(0, 50)],
|
||||
speed: 250.0,
|
||||
curve: Curves.bounceInOut,
|
||||
isRelative: false,
|
||||
));
|
||||
```
|
||||
|
||||
If you want the positions in the path list to be relative to the components last position, and not absolute values on the screen, then you can set `isRelative = true`.
|
||||
When you use that, the next position in the list will be relative to the previous position in the list, or if it is the first element of the list it is relative to the components position.
|
||||
So if you have a component which is positioned at `Vector2(100, 100)` and you use `isRelative = true` with the following path list `path: [Vector(20, 0), Vector(0, 50)]`, then the component will
|
||||
first move to `(120, 0)` and then to `(120, 100)`.
|
||||
|
||||
## ScaleEffect
|
||||
|
||||
Applied to `PositionComponent`s, this effect can be used to change the width and height of the component, using an [animation curve](https://api.flutter.dev/flutter/animation/Curves-class.html).
|
||||
|
||||
@ -44,9 +44,9 @@ class MyGame extends BaseGame with TapDetector {
|
||||
|
||||
final move2 = MoveEffect(
|
||||
path: [
|
||||
Vector2(dx, dy + 20),
|
||||
Vector2(dx - 20, dy - 20),
|
||||
Vector2(dx + 20, dy),
|
||||
Vector2(dx, dy + 50),
|
||||
Vector2(dx - 50, dy - 50),
|
||||
Vector2(dx + 50, dy),
|
||||
],
|
||||
speed: 150.0,
|
||||
curve: Curves.easeIn,
|
||||
@ -72,14 +72,15 @@ class MyGame extends BaseGame with TapDetector {
|
||||
|
||||
final combination = CombinedEffect(
|
||||
effects: [move2, rotate],
|
||||
isAlternating: true,
|
||||
isAlternating: false,
|
||||
isInfinite: true,
|
||||
);
|
||||
|
||||
final sequence = SequenceEffect(
|
||||
effects: [move1, scale, combination],
|
||||
isInfinite: false,
|
||||
isAlternating: true,
|
||||
isInfinite: true,
|
||||
isAlternating: false,
|
||||
);
|
||||
greenSquare.addEffect(sequence);
|
||||
greenSquare.addEffect(combination);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flame/extensions/vector2.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/gestures.dart';
|
||||
import 'package:flame/effects/effects.dart';
|
||||
@ -17,9 +18,19 @@ class MyGame extends BaseGame with TapDetector {
|
||||
@override
|
||||
void onTapUp(details) {
|
||||
square.addEffect(MoveEffect(
|
||||
path: [details.localPosition.toVector2()],
|
||||
path: [
|
||||
details.localPosition.toVector2().clone(),
|
||||
Vector2(100, 100),
|
||||
Vector2(50, 120),
|
||||
Vector2(200, 400),
|
||||
Vector2(150, 0),
|
||||
Vector2(100, 300),
|
||||
],
|
||||
speed: 250.0,
|
||||
curve: Curves.bounceInOut,
|
||||
isRelative: false,
|
||||
isInfinite: true,
|
||||
isAlternating: true,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,11 @@ abstract class PositionComponentEffect {
|
||||
double driftTime = 0.0;
|
||||
int curveDirection = 1;
|
||||
|
||||
/// Used to be able to determine the start state of the component
|
||||
Vector2 originalPosition;
|
||||
double originalAngle;
|
||||
Vector2 originalSize;
|
||||
|
||||
/// Used to be able to determine the end state of a sequence of effects
|
||||
Vector2 endPosition;
|
||||
double endAngle;
|
||||
@ -70,6 +75,9 @@ abstract class PositionComponentEffect {
|
||||
@mustCallSuper
|
||||
void initialize(PositionComponent _comp) {
|
||||
component = _comp;
|
||||
originalPosition = component.position;
|
||||
originalAngle = component.angle;
|
||||
originalSize = component.size;
|
||||
|
||||
/// You need to set the travelTime during the initialization of the
|
||||
/// extending effect
|
||||
|
||||
@ -25,7 +25,6 @@ class MoveEffect extends PositionComponentEffect {
|
||||
double speed;
|
||||
Curve curve;
|
||||
Vector2 _startPosition;
|
||||
Vector2 _peakPosition;
|
||||
|
||||
MoveEffect({
|
||||
@required this.path,
|
||||
@ -61,10 +60,10 @@ class MoveEffect extends PositionComponentEffect {
|
||||
} else {
|
||||
_movePath = path;
|
||||
}
|
||||
print(_movePath);
|
||||
_peakPosition = isRelative ? path.last : path.last - _startPosition;
|
||||
if (!isAlternating) {
|
||||
endPosition = _peakPosition;
|
||||
endPosition = _movePath.last;
|
||||
} else {
|
||||
endPosition = _startPosition;
|
||||
}
|
||||
|
||||
double pathLength = 0;
|
||||
@ -91,9 +90,16 @@ class MoveEffect extends PositionComponentEffect {
|
||||
);
|
||||
lastPosition = v;
|
||||
}
|
||||
print(_percentagePath);
|
||||
travelTime = pathLength / speed;
|
||||
}
|
||||
|
||||
@override
|
||||
void reset() {
|
||||
super.reset();
|
||||
if(_percentagePath?.isNotEmpty ?? false) {
|
||||
_currentSubPath = _percentagePath.first;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
|
||||
@ -5,10 +5,10 @@ import 'effects.dart';
|
||||
|
||||
class SequenceEffect extends PositionComponentEffect {
|
||||
final List<PositionComponentEffect> effects;
|
||||
int _currentIndex = 0;
|
||||
int _currentIndex;
|
||||
PositionComponentEffect currentEffect;
|
||||
bool _currentWasAlternating;
|
||||
double _driftModifier = 0.0;
|
||||
double _driftModifier;
|
||||
|
||||
SequenceEffect({
|
||||
@required this.effects,
|
||||
@ -26,9 +26,7 @@ class SequenceEffect extends PositionComponentEffect {
|
||||
void initialize(PositionComponent _comp) {
|
||||
super.initialize(_comp);
|
||||
_currentIndex = 0;
|
||||
final originalSize = _comp.size;
|
||||
final originalPosition = _comp.position;
|
||||
final originalAngle = _comp.angle;
|
||||
_driftModifier = 0.0;
|
||||
effects.forEach((effect) {
|
||||
effect.reset();
|
||||
_comp.size = endSize;
|
||||
@ -43,9 +41,9 @@ class SequenceEffect extends PositionComponentEffect {
|
||||
0,
|
||||
(time, effect) => time + effect.totalTravelTime,
|
||||
);
|
||||
component.size = originalSize;
|
||||
component.position = originalPosition;
|
||||
component.angle = originalAngle;
|
||||
component.size = originalSize;
|
||||
currentEffect = effects.first;
|
||||
_currentWasAlternating = currentEffect.isAlternating;
|
||||
}
|
||||
@ -57,20 +55,30 @@ class SequenceEffect extends PositionComponentEffect {
|
||||
}
|
||||
super.update(dt);
|
||||
|
||||
// If the last effect's time to completion overshot its total time, add that
|
||||
// time to the first time step of the next effect.
|
||||
currentEffect.update(dt + _driftModifier);
|
||||
_driftModifier = 0.0;
|
||||
if (currentEffect.hasFinished()) {
|
||||
_driftModifier = currentEffect.driftTime;
|
||||
currentEffect.isAlternating = _currentWasAlternating;
|
||||
_currentIndex++;
|
||||
final iterationSize = isAlternating ? effects.length * 2 : effects.length;
|
||||
if (_currentIndex != 0 && _currentIndex % iterationSize == 0) {
|
||||
if (_currentIndex != 0
|
||||
&& _currentIndex == iterationSize
|
||||
&& (currentEffect.isAlternating ||
|
||||
currentEffect.isAlternating == isAlternating)) {
|
||||
isInfinite ? reset() : dispose();
|
||||
return;
|
||||
}
|
||||
final orderedEffects =
|
||||
curveDirection.isNegative ? effects.reversed.toList() : effects;
|
||||
// Make sure the current effect has the `isAlternating` value it
|
||||
// initially started with
|
||||
currentEffect.isAlternating = _currentWasAlternating;
|
||||
// Get the next effect that should be executed
|
||||
currentEffect = orderedEffects[_currentIndex % effects.length];
|
||||
// Keep track of what value of `isAlternating` the effect had from the
|
||||
// start
|
||||
_currentWasAlternating = currentEffect.isAlternating;
|
||||
if (isAlternating &&
|
||||
!currentEffect.isAlternating &&
|
||||
@ -84,6 +92,10 @@ class SequenceEffect extends PositionComponentEffect {
|
||||
@override
|
||||
void reset() {
|
||||
super.reset();
|
||||
component.position = originalPosition;
|
||||
component.angle = originalAngle;
|
||||
component.size = originalSize;
|
||||
initialize(component);
|
||||
//effects.forEach((e) => e.reset());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user