Make ScaleEffect.by multiplicative (#1174)

* Make ScaleEffect.by multiplicative

* formatting

Co-authored-by: Lukas Klingsbo <lukas.klingsbo@gmail.com>
This commit is contained in:
Pasha Stetsenko
2021-12-07 03:01:36 -08:00
committed by GitHub
parent 341d227bfc
commit 3ae134aee5
3 changed files with 31 additions and 26 deletions

View File

@ -11,6 +11,7 @@
- Fix render order of components and add tests - Fix render order of components and add tests
- `isHud` renamed to `respectCamera` - `isHud` renamed to `respectCamera`
- Fix `HitboxCircle` when component is flipped - Fix `HitboxCircle` when component is flipped
- `ScaleEffect.by` now applies multiplicatively instead of additively
## [1.0.0-releasecandidate.18] ## [1.0.0-releasecandidate.18]
- Forcing portrait and landscape mode is now supported on web - Forcing portrait and landscape mode is now supported on web

View File

@ -7,27 +7,36 @@ import 'transform2d_effect.dart';
/// ///
/// The following constructors are provided: /// The following constructors are provided:
/// ///
/// - [ScaleEffect.by] will scale the target in relation to it's current /// - [ScaleEffect.by] will scale the target by the given factor, relative to
/// scale; /// its current scale;
/// - [ScaleEffect.to] will scale the target to the specified scale /// - [ScaleEffect.to] will scale the target to the specified scale.
/// ///
/// This effect applies incremental changes to the component's scale, and /// This effect applies incremental changes to the component's scale, and
/// requires that any other effect or update logic applied to the same component /// requires that any other effect or update logic applied to the same component
/// also used incremental updates. /// also used incremental updates.
class ScaleEffect extends Transform2DEffect { class ScaleEffect extends Transform2DEffect {
ScaleEffect.by(Vector2 offset, EffectController controller) ScaleEffect.by(Vector2 scaleFactor, EffectController controller)
: _offset = offset.clone(), : _scaleFactor = scaleFactor.clone(),
super(controller); super(controller);
factory ScaleEffect.to(Vector2 targetScale, EffectController controller) => factory ScaleEffect.to(Vector2 targetScale, EffectController controller) =>
_ScaleToEffect(targetScale, controller); _ScaleToEffect(targetScale, controller);
Vector2 _offset; final Vector2 _scaleFactor;
late Vector2 _scaleDelta;
@override
void onStart() {
_scaleDelta = Vector2(
target.scale.x * (_scaleFactor.x - 1),
target.scale.y * (_scaleFactor.y - 1),
);
}
@override @override
void apply(double progress) { void apply(double progress) {
final dProgress = progress - previousProgress; final dProgress = progress - previousProgress;
target.scale += _offset * dProgress; target.scale += _scaleDelta * dProgress;
super.apply(progress); super.apply(progress);
} }
} }
@ -42,6 +51,6 @@ class _ScaleToEffect extends ScaleEffect {
@override @override
void onStart() { void onStart() {
_offset = _targetScale - target.scale; _scaleDelta = _targetScale - target.scale;
} }
} }

View File

@ -13,9 +13,8 @@ void main() {
final component = PositionComponent(); final component = PositionComponent();
game.ensureAdd(component); game.ensureAdd(component);
component.scale = Vector2.all(1.0);
component.add( component.add(
ScaleEffect.by(Vector2.all(1.0), EffectController(duration: 1)), ScaleEffect.by(Vector2.all(2.0), EffectController(duration: 1)),
); );
game.update(0); game.update(0);
expectVector2(component.scale, Vector2.all(1.0)); expectVector2(component.scale, Vector2.all(1.0));
@ -58,18 +57,18 @@ void main() {
game.ensureAdd(component); game.ensureAdd(component);
final effect = ScaleEffect.by( final effect = ScaleEffect.by(
Vector2.all(1.0), Vector2.all(2.0),
EffectController(duration: 1), EffectController(duration: 1),
); );
component.add(effect..removeOnFinish = false); component.add(effect..removeOnFinish = false);
final expectedScale = Vector2.all(1.0); final expectedScale = Vector2.all(1.0);
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
expectVector2(component.scale, expectedScale); expectVector2(component.scale, expectedScale);
// After each reset the object will be scaled up by Vector2(1, 1) // After each reset the object will be scaled up twice
// relative to its scale at the start of the effect. // relative to its scale at the start of the effect.
effect.reset(); effect.reset();
game.update(1); game.update(1);
expectedScale.add(Vector2.all(1.0)); expectedScale.multiply(Vector2.all(2));
expectVector2(component.scale, expectedScale); expectVector2(component.scale, expectedScale);
} }
}); });
@ -94,7 +93,7 @@ void main() {
}); });
flameGame.test('scale composition', (game) { flameGame.test('scale composition', (game) {
final component = PositionComponent(); final component = PositionComponent()..flipVertically();
game.ensureAdd(component); game.ensureAdd(component);
component.add( component.add(
@ -112,21 +111,17 @@ void main() {
); );
game.update(1); game.update(1);
expectVector2( expect(component.scale.x, closeTo(0.7, 1e-15)); // (1 + 0.4) * 0.5
component.scale, expect(component.scale.y, closeTo(-0.7, 1e-15));
Vector2.all(2),
epsilon: 1e-15,
); // 5*1/10 + 0.5*1
game.update(1); game.update(1);
expectVector2( expect(component.scale.x, closeTo(1.8, 1e-15)); // (1 + 2*0.4) * 1
component.scale, expect(component.scale.y, closeTo(-1.8, 1e-15));
Vector2.all(2), for (var i = 0; i < 8; i++) {
epsilon: 1e-15,
); // 5*2/10 + 0.5*1 - 0.5*1
for (var i = 0; i < 10; i++) {
game.update(1); game.update(1);
} }
expectVector2(component.scale, Vector2.all(6), epsilon: 1e-15); expect(component.scale.x, closeTo(5, 1e-15));
expect(component.scale.y, closeTo(-5, 1e-15));
game.update(0);
expect(component.children.length, 0); expect(component.children.length, 0);
}); });