From c9f55a799d3234ab19d761a0428a9d986b8335ca Mon Sep 17 00:00:00 2001 From: Dipak Date: Fri, 28 Oct 2022 19:47:47 +0530 Subject: [PATCH 01/19] added glow effect using maskFilter. --- packages/flame/lib/effects.dart | 1 + packages/flame/lib/src/effects/glow_effect.dart | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/flame/lib/src/effects/glow_effect.dart diff --git a/packages/flame/lib/effects.dart b/packages/flame/lib/effects.dart index 3abf214f13e..4b12306ccef 100644 --- a/packages/flame/lib/effects.dart +++ b/packages/flame/lib/effects.dart @@ -21,6 +21,7 @@ export 'src/effects/controllers/speed_effect_controller.dart'; export 'src/effects/controllers/zigzag_effect_controller.dart'; export 'src/effects/effect.dart'; export 'src/effects/effect_target.dart'; +export 'src/effects/glow_effect.dart'; export 'src/effects/move_along_path_effect.dart'; export 'src/effects/move_by_effect.dart'; export 'src/effects/move_effect.dart'; diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart new file mode 100644 index 00000000000..4f9215bb4a0 --- /dev/null +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -0,0 +1,17 @@ +import 'dart:ui'; + +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; + +class GlowEffect extends ComponentEffect { + GlowEffect(this.filter, super.controller, {this.paintId}); + + final MaskFilter filter; + final String? paintId; + + + @override + void apply(double progress) { + target.paint.maskFilter = filter; + } +} From a81863652f3d9a4a3a3a9bc01d84561860d0ab3a Mon Sep 17 00:00:00 2001 From: Dipak Date: Fri, 28 Oct 2022 19:53:12 +0530 Subject: [PATCH 02/19] added example --- .../stories/effects/glow_effect_example.dart | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 examples/lib/stories/effects/glow_effect_example.dart diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart new file mode 100644 index 00000000000..c80eb225fce --- /dev/null +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -0,0 +1,33 @@ +import 'package:examples/commons/ember.dart'; +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:flame/game.dart'; +import 'package:flame/input.dart'; +import 'package:flutter/material.dart'; + +class GlowEffectExample extends FlameGame with TapDetector { + static const String description = ''' + In this example we show how the `GlowEffect` can be used. + '''; + + late final SpriteComponent sprite; + + @override + Future onLoad() async { + add( + Ember( + position: Vector2(180, 230), + size: Vector2.all(100), + )..add( + GlowEffect( + const MaskFilter.blur(BlurStyle.solid, 100.0), + EffectController( + duration: 1.5, + reverseDuration: 1.5, + infinite: true, + ), + ), + ), + ); + } +} From d7d138d8b04d784e4dffd29fd55d9a9b86dac089 Mon Sep 17 00:00:00 2001 From: Dipak Date: Fri, 28 Oct 2022 20:01:30 +0530 Subject: [PATCH 03/19] fixed format --- packages/flame/lib/src/effects/glow_effect.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart index 4f9215bb4a0..09207d892e8 100644 --- a/packages/flame/lib/src/effects/glow_effect.dart +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -9,7 +9,6 @@ class GlowEffect extends ComponentEffect { final MaskFilter filter; final String? paintId; - @override void apply(double progress) { target.paint.maskFilter = filter; From bdb992ffec4fd7b56831ddd2b0e020d8357ff4a2 Mon Sep 17 00:00:00 2001 From: Dipak Date: Fri, 28 Oct 2022 22:03:39 +0530 Subject: [PATCH 04/19] fixed glow effect --- .../stories/effects/glow_effect_example.dart | 17 ++++++++++------- packages/flame/lib/src/effects/glow_effect.dart | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index c80eb225fce..19ecc1d1e4d 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -1,26 +1,29 @@ -import 'package:examples/commons/ember.dart'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flame/game.dart'; import 'package:flame/input.dart'; import 'package:flutter/material.dart'; +void main() { + runApp(GameWidget(game: GlowEffectExample())); +} + class GlowEffectExample extends FlameGame with TapDetector { static const String description = ''' In this example we show how the `GlowEffect` can be used. '''; - late final SpriteComponent sprite; - @override Future onLoad() async { add( - Ember( - position: Vector2(180, 230), - size: Vector2.all(100), + CircleComponent( + radius: 50, + position: Vector2(280, 280), + paint: Paint()..color = const Color(0xff39FF14), )..add( GlowEffect( - const MaskFilter.blur(BlurStyle.solid, 100.0), + BlurStyle.outer, + 50.0, EffectController( duration: 1.5, reverseDuration: 1.5, diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart index 09207d892e8..0738f17baa3 100644 --- a/packages/flame/lib/src/effects/glow_effect.dart +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -4,13 +4,22 @@ import 'package:flame/components.dart'; import 'package:flame/effects.dart'; class GlowEffect extends ComponentEffect { - GlowEffect(this.filter, super.controller, {this.paintId}); + GlowEffect(this.style, this.blurValue, super.controller, {this.paintId}); - final MaskFilter filter; + final BlurStyle style; + final double blurValue; final String? paintId; @override void apply(double progress) { - target.paint.maskFilter = filter; + final _value = blurValue * progress; + + target.paint.maskFilter = MaskFilter.blur(style, _value); + } + + @override + void reset() { + super.reset(); + target.paint.maskFilter = null; } } From 6b8573a289d2593d74435e02c9574a4ad077033b Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 08:18:49 +0530 Subject: [PATCH 05/19] style parameter made optional. blurValue renamed to strength. removed unused var. --- examples/lib/stories/effects/glow_effect_example.dart | 9 +++++---- packages/flame/lib/src/effects/glow_effect.dart | 7 +++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index 19ecc1d1e4d..8a254e615bc 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -15,17 +15,18 @@ class GlowEffectExample extends FlameGame with TapDetector { @override Future onLoad() async { + final paint2 = Paint()..color = const Color(0xff39FF14); + add( CircleComponent( radius: 50, position: Vector2(280, 280), - paint: Paint()..color = const Color(0xff39FF14), + paint: paint2, )..add( GlowEffect( - BlurStyle.outer, - 50.0, + 10.0, EffectController( - duration: 1.5, + duration: 3, reverseDuration: 1.5, infinite: true, ), diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart index 0738f17baa3..87f78202303 100644 --- a/packages/flame/lib/src/effects/glow_effect.dart +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -4,15 +4,14 @@ import 'package:flame/components.dart'; import 'package:flame/effects.dart'; class GlowEffect extends ComponentEffect { - GlowEffect(this.style, this.blurValue, super.controller, {this.paintId}); + GlowEffect(this.strength, super.controller, {this.style = BlurStyle.outer}); final BlurStyle style; - final double blurValue; - final String? paintId; + final double strength; @override void apply(double progress) { - final _value = blurValue * progress; + final _value = strength * progress; target.paint.maskFilter = MaskFilter.blur(style, _value); } From 0b84e813e71c51a0aee6bd00c3656231669531b5 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 08:35:37 +0530 Subject: [PATCH 06/19] pass parameter via the PaintProvider interface --- packages/flame/lib/src/effects/glow_effect.dart | 10 ++++++++-- .../flame/lib/src/effects/provider_interfaces.dart | 11 +++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart index 87f78202303..9f5c8bc6c54 100644 --- a/packages/flame/lib/src/effects/glow_effect.dart +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -1,9 +1,15 @@ import 'dart:ui'; -import 'package:flame/components.dart'; import 'package:flame/effects.dart'; +import 'package:flame/src/effects/provider_interfaces.dart'; -class GlowEffect extends ComponentEffect { +/// Change the MaskFilter on Paint of a component over time. +/// +/// This effect applies incremental changes to the MaskFilter on Paint of a +/// component and +/// requires that any other effect or update logic applied to the same component +/// also used incremental updates. +class GlowEffect extends Effect with EffectTarget { GlowEffect(this.strength, super.controller, {this.style = BlurStyle.outer}); final BlurStyle style; diff --git a/packages/flame/lib/src/effects/provider_interfaces.dart b/packages/flame/lib/src/effects/provider_interfaces.dart index 031b70a1d10..861ef2ff5a0 100644 --- a/packages/flame/lib/src/effects/provider_interfaces.dart +++ b/packages/flame/lib/src/effects/provider_interfaces.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import 'package:flame/components.dart'; /// Interface for a component that can be affected by move effects. @@ -64,3 +66,12 @@ abstract class OpacityProvider { double get opacity; set opacity(double value); } + + +/// Interface for a component that can be affected by Paint effects. +/// +/// See [HasPaint] for an example implementation. +abstract class PaintProvider { + Paint get paint; + set opacity(Paint value); +} From 5d269ca40c71739f13b901d85aa19cababea822d Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 08:44:25 +0530 Subject: [PATCH 07/19] format fixed --- packages/flame/lib/src/effects/provider_interfaces.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/flame/lib/src/effects/provider_interfaces.dart b/packages/flame/lib/src/effects/provider_interfaces.dart index 861ef2ff5a0..1219debdd0f 100644 --- a/packages/flame/lib/src/effects/provider_interfaces.dart +++ b/packages/flame/lib/src/effects/provider_interfaces.dart @@ -67,7 +67,6 @@ abstract class OpacityProvider { set opacity(double value); } - /// Interface for a component that can be affected by Paint effects. /// /// See [HasPaint] for an example implementation. From 8c5a663e25360c405945d083c7f82fdb98c68a47 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 08:59:14 +0530 Subject: [PATCH 08/19] implemented PaintProvider on HasPaint --- .../flame/lib/src/components/mixins/has_paint.dart | 14 ++++++++++++-- .../flame/lib/src/effects/provider_interfaces.dart | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/flame/lib/src/components/mixins/has_paint.dart b/packages/flame/lib/src/components/mixins/has_paint.dart index 295e9e9a89b..8ffddf3fe46 100644 --- a/packages/flame/lib/src/components/mixins/has_paint.dart +++ b/packages/flame/lib/src/components/mixins/has_paint.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; +import 'package:flame/src/effects/provider_interfaces.dart'; import 'package:flame/src/palette.dart'; import 'package:meta/meta.dart'; @@ -14,9 +15,10 @@ import 'package:meta/meta.dart'; /// [T], that can be omitted if the component only has one paint. /// [paintLayers] paints should be drawn in list order during the render. The /// main Paint is the first element. -mixin HasPaint on Component implements OpacityProvider { +mixin HasPaint on Component + implements OpacityProvider, PaintProvider { late final Map _paints = {}; - Paint paint = BasicPalette.white.paint(); + Paint _paint = BasicPalette.white.paint(); @internal List? paintLayersInternal; @@ -124,6 +126,14 @@ mixin HasPaint on Component implements OpacityProvider { } } + @override + Paint get paint => _paint; + + @override + set paint(Paint value) { + _paint = value; + } + /// Creates an [OpacityProvider] for given [paintId] and can be used as /// `target` for [OpacityEffect]. OpacityProvider opacityProviderOf(T paintId) { diff --git a/packages/flame/lib/src/effects/provider_interfaces.dart b/packages/flame/lib/src/effects/provider_interfaces.dart index 1219debdd0f..74a076fe361 100644 --- a/packages/flame/lib/src/effects/provider_interfaces.dart +++ b/packages/flame/lib/src/effects/provider_interfaces.dart @@ -72,5 +72,5 @@ abstract class OpacityProvider { /// See [HasPaint] for an example implementation. abstract class PaintProvider { Paint get paint; - set opacity(Paint value); + set paint(Paint value); } From 6dd7214f55bb092f2e9f5380e63b4c2e6f1c2c25 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 09:38:04 +0530 Subject: [PATCH 09/19] updated examples --- .../stories/effects/glow_effect_example.dart | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index 8a254e615bc..214564ede1c 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -1,3 +1,4 @@ +import 'package:examples/commons/ember.dart'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flame/game.dart'; @@ -15,19 +16,39 @@ class GlowEffectExample extends FlameGame with TapDetector { @override Future onLoad() async { - final paint2 = Paint()..color = const Color(0xff39FF14); + final paint2 = Paint() + ..color = const Color(0xff39FF14) + ..style = PaintingStyle.stroke; + + add( + Ember( + position: Vector2(280, 280), + size: Vector2.all(100), + )..add( + RectangleComponent(paint: paint2, size: Vector2.all(100)) + ..add( + GlowEffect( + 30.0, + EffectController( + duration: 3.5, + infinite: true, + ), + ), + ), + ), + ); add( CircleComponent( radius: 50, - position: Vector2(280, 280), + position: Vector2(300, 400), paint: paint2, )..add( GlowEffect( 10.0, EffectController( duration: 3, - reverseDuration: 1.5, + // reverseDuration: 1.5, infinite: true, ), ), From 9a1a3ed8d737f624fcb0545ee225d6226d18ddc1 Mon Sep 17 00:00:00 2001 From: Dipak Prajapati Date: Sat, 29 Oct 2022 15:12:37 +0530 Subject: [PATCH 10/19] Update examples/lib/stories/effects/glow_effect_example.dart Co-authored-by: Lukas Klingsbo --- examples/lib/stories/effects/glow_effect_example.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index 214564ede1c..f21f7e16103 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -16,7 +16,7 @@ class GlowEffectExample extends FlameGame with TapDetector { @override Future onLoad() async { - final paint2 = Paint() + final paint = Paint() ..color = const Color(0xff39FF14) ..style = PaintingStyle.stroke; From 7151ff6eacda82937960bcbfb537ea2f30b21f0b Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 15:18:30 +0530 Subject: [PATCH 11/19] removed ember from example. --- .../stories/effects/glow_effect_example.dart | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index f21f7e16103..ce26e43a4bb 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -1,4 +1,3 @@ -import 'package:examples/commons/ember.dart'; import 'package:flame/components.dart'; import 'package:flame/effects.dart'; import 'package:flame/game.dart'; @@ -20,29 +19,11 @@ class GlowEffectExample extends FlameGame with TapDetector { ..color = const Color(0xff39FF14) ..style = PaintingStyle.stroke; - add( - Ember( - position: Vector2(280, 280), - size: Vector2.all(100), - )..add( - RectangleComponent(paint: paint2, size: Vector2.all(100)) - ..add( - GlowEffect( - 30.0, - EffectController( - duration: 3.5, - infinite: true, - ), - ), - ), - ), - ); - add( CircleComponent( radius: 50, position: Vector2(300, 400), - paint: paint2, + paint: paint, )..add( GlowEffect( 10.0, From 363a4fe8c73d972fa07a8844e056a745a9a69e30 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 15:47:41 +0530 Subject: [PATCH 12/19] removed comment --- examples/lib/stories/effects/glow_effect_example.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lib/stories/effects/glow_effect_example.dart b/examples/lib/stories/effects/glow_effect_example.dart index ce26e43a4bb..f66b6201a9d 100644 --- a/examples/lib/stories/effects/glow_effect_example.dart +++ b/examples/lib/stories/effects/glow_effect_example.dart @@ -29,7 +29,7 @@ class GlowEffectExample extends FlameGame with TapDetector { 10.0, EffectController( duration: 3, - // reverseDuration: 1.5, + reverseDuration: 1.5, infinite: true, ), ), From b429eb6a29ff3aea9d83ec563db39727741e7648 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 15:48:05 +0530 Subject: [PATCH 13/19] override the paint here instead of making it private. --- .../flame/lib/src/components/mixins/has_paint.dart | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/flame/lib/src/components/mixins/has_paint.dart b/packages/flame/lib/src/components/mixins/has_paint.dart index 8ffddf3fe46..ccb8f46b870 100644 --- a/packages/flame/lib/src/components/mixins/has_paint.dart +++ b/packages/flame/lib/src/components/mixins/has_paint.dart @@ -18,7 +18,9 @@ import 'package:meta/meta.dart'; mixin HasPaint on Component implements OpacityProvider, PaintProvider { late final Map _paints = {}; - Paint _paint = BasicPalette.white.paint(); + + @override + Paint paint = BasicPalette.white.paint(); @internal List? paintLayersInternal; @@ -126,14 +128,6 @@ mixin HasPaint on Component } } - @override - Paint get paint => _paint; - - @override - set paint(Paint value) { - _paint = value; - } - /// Creates an [OpacityProvider] for given [paintId] and can be used as /// `target` for [OpacityEffect]. OpacityProvider opacityProviderOf(T paintId) { From 1c60675e64adeb2546c9ea4150da499bbe467cce Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 16:27:03 +0530 Subject: [PATCH 14/19] docs: added doc and interactive example --- doc/flame/effects.md | 125 +++++++++++++++++------- doc/flame/examples/lib/glow_effect.dart | 29 ++++++ doc/flame/examples/lib/main.dart | 2 + 3 files changed, 122 insertions(+), 34 deletions(-) create mode 100644 doc/flame/examples/lib/glow_effect.dart diff --git a/doc/flame/effects.md b/doc/flame/effects.md index 8db631d511f..b44c699991e 100644 --- a/doc/flame/effects.md +++ b/doc/flame/effects.md @@ -82,17 +82,17 @@ The base `Effect` class is not usable on its own (it is abstract), but it provid functionality inherited by all other effects. This includes: - The ability to pause/resume the effect using `effect.pause()` and `effect.resume()`. You can - check whether the effect is currently paused using `effect.isPaused`. + check whether the effect is currently paused using `effect.isPaused`. - The ability to reverse the effect's time direction using `effect.reverse()`. Use - `effect.isReversed` to check if the effect is currently running back in time. + `effect.isReversed` to check if the effect is currently running back in time. - Property `removeOnFinish` (which is true by default) will cause the effect component to be - removed from the game tree and garbage-collected once the effect completes. Set this to false - if you plan to reuse the effect after it is finished. + removed from the game tree and garbage-collected once the effect completes. Set this to false + if you plan to reuse the effect after it is finished. - Optional user-provided `onComplete`, which will be invoked when the effect has just - completed its execution but before it is removed from the game. + completed its execution but before it is removed from the game. - The `reset()` method reverts the effect to its original state, allowing it to run once again. @@ -111,6 +111,7 @@ offset is relative to the current position of the target: ``` ```dart + final effect = MoveByEffect( Vector2(0, -10), EffectController(duration: 0.5), @@ -138,6 +139,7 @@ point in a straight line. ``` ```dart + final effect = MoveToEffect( Vector2(100, 500), EffectController(duration: 3), @@ -163,8 +165,10 @@ position. ``` ```dart + final effect = MoveAlongPathEffect( - Path()..quadraticBezierTo(100, 0, 50, -50), + Path() + ..quadraticBezierTo(100, 0, 50, -50), EffectController(duration: 1.5), ); ``` @@ -193,8 +197,9 @@ clockwise: ``` ```dart + final effect = RotateEffect.by( - tau/4, + tau / 4, EffectController(duration: 2), ); ``` @@ -214,8 +219,9 @@ target to look east (0º is north, 90º=[tau]/4 east, 180º=tau/2 south, and 270 ``` ```dart + final effect = RotateEffect.to( - tau/4, + tau / 4, EffectController(duration: 2), ); ``` @@ -235,6 +241,7 @@ the component to grow 50% larger: ``` ```dart + final effect = ScaleEffect.by( Vector2.all(1.5), EffectController(duration: 0.3), @@ -255,6 +262,7 @@ This effect works similar to `ScaleEffect.by`, but sets the absolute value of th ``` ```dart + final effect = ScaleEffect.to( Vector2.all(0.5), EffectController(duration: 0.5), @@ -277,9 +285,10 @@ course, the new size will be `Vector2(120, 50)`: ``` ```dart + final effect = SizeEffect.by( - Vector2(-15, 30), - EffectController(duration: 1), + Vector2(-15, 30), + EffectController(duration: 1), ); ``` @@ -299,7 +308,6 @@ target component and its children. Changes the size of the target component to the specified size. Target size cannot be negative: - ```{flutter-app} :sources: ../flame/examples :page: size_to_effect @@ -309,6 +317,7 @@ Changes the size of the target component to the specified size. Target size cann ``` ```dart + final effect = SizeEffect.to( Vector2(90, 80), EffectController(duration: 1), @@ -330,8 +339,9 @@ using `AnchorEffect.by()`. ``` ```dart + final effect = AnchorByEffect( - Vector2(0.1, 0.1), + Vector2(0.1, 0.1), EffectController(speed: 1), ); ``` @@ -351,8 +361,9 @@ Changes the location of the target's anchor. This effect can also be created usi ``` ```dart + final effect = AnchorToEffect( - Anchor.center, + Anchor.center, EffectController(speed: 1), ); ``` @@ -372,6 +383,7 @@ It can only be applied to components that implement the `OpacityProvider`. ``` ```dart + final effect = OpacityEffect.to( 0.2, EffectController(duration: 0.75), @@ -383,7 +395,6 @@ using the `target` parameter. The `HasPaint` mixin implements `OpacityProvider` to easily create providers for desired paintIds. For single paintId `opacityProviderOf` can be used and for multiple paintIds and `opacityProviderOfList` can be used. - ```{flutter-app} :sources: ../flame/examples :page: opacity_effect_with_target @@ -393,6 +404,7 @@ and for multiple paintIds and `opacityProviderOfList` can be used. ``` ```dart + final effect = OpacityEffect.to( 0.2, EffectController(duration: 0.75), @@ -409,7 +421,8 @@ animate the target into full transparency / full visibility respectively. ### `OpacityByEffect` -This effect will change the opacity of the target relative to the specified alpha-value. For example, +This effect will change the opacity of the target relative to the specified alpha-value. For +example, the following effect will change the opacity of the target by `90%`: ```{flutter-app} @@ -421,16 +434,43 @@ the following effect will change the opacity of the target by `90%`: ``` ```dart + final effect = OpacityEffect.by( 0.9, EffectController(duration: 0.75), ); ``` -Currently this effect can only be applied to components that have a `HasPaint` mixin. If the target component +Currently this effect can only be applied to components that have a `HasPaint` mixin. If the target +component uses multiple paints, the effect can target any individual color using the `paintId` parameter. +### GlowEffect + +This effect will apply the glowing shade around target relative to the specified +`glow-strength`. The color of shade will be targets paint color. For example, the following effect +will apply the glowing shade around target by strength of `10`: + +```{flutter-app} +:sources: ../flame/examples +:page: glow_effect +:show: widget code infobox +:width: 180 +:height: 160 +``` + +```dart + +final effect = GlowEffect( + 10.0, + EffectController(duration: 3), +); +``` + +Currently this effect can only be applied to components that have a `HasPaint` mixin. + + ### `SequenceEffect` This effect can be used to run multiple other effects one after another. The constituent effects @@ -448,22 +488,23 @@ backward); and also repeat a certain predetermined number of times, or infinitel ``` ```dart + final effect = SequenceEffect([ ScaleEffect.by( - Vector2.all(1.5), + Vector2.all(1.5), EffectController( - duration: 0.2, + duration: 0.2, alternate: true, ), ), MoveEffect.by( - Vector2(30, -50), + Vector2(30, -50), EffectController( duration: 0.5, ), ), OpacityEffect.to( - 0, + 0, EffectController( duration: 0.3, ), @@ -479,6 +520,7 @@ This is a simple effect that can be attached to a component causing it to be rem tree after the specified delay has passed: ```dart + final effect = RemoveEffect(delay: 10.0); ``` @@ -491,6 +533,7 @@ the provided color between a provided range. Usage example: ```dart + final effect = ColorEffect( const Color(0xFF00FF00), const Offset(0.0, 0.8), @@ -542,18 +585,18 @@ common controllers. The syntax of the constructor is the following: ```dart EffectController({ - required double duration, - Curve curve = Curves.linear, - double? reverseDuration, - Curve? reverseCurve, - bool alternate = false, - double atMaxDuration = 0.0, - double atMinDuration = 0.0, - int? repeatCount, - bool infinite = false, - double startDelay = 0.0, - VoidCallback? onMax, - VoidCallback? onMin, + required double duration, + Curve curve = Curves.linear, + double? reverseDuration, + Curve? reverseCurve, + bool alternate = false, + double atMaxDuration = 0.0, + double atMinDuration = 0.0, + int? repeatCount, + bool infinite = false, + double startDelay = 0.0, + VoidCallback? onMax, + VoidCallback? onMin, }); ``` @@ -633,6 +676,7 @@ This is the simplest effect controller that grows linearly from 0 to 1 over the `duration`: ```dart + final ec = LinearEffectController(3); ``` @@ -643,6 +687,7 @@ Similar to the `LinearEffectController`, but it goes in the opposite direction a from 1 to 0 over the specified duration: ```dart + final ec = ReverseLinearEffectController(1); ``` @@ -653,6 +698,7 @@ This effect controller grows non-linearly from 0 to 1 over the specified `durati the provided `curve`: ```dart + final ec = CurvedEffectController(0.5, Curves.easeOut); ``` @@ -663,6 +709,7 @@ Similar to the `CurvedEffectController`, but the controller grows down from 1 to provided `curve`: ```dart + final ec = ReverseCurvedEffectController(0.5, Curves.bounceInOut); ``` @@ -673,6 +720,7 @@ This effect controller keeps the progress at a constant value for the specified Typically, the `progress` would be either 0 or 1: ```dart + final ec = PauseEffectController(1.5, progress: 0); ``` @@ -683,6 +731,7 @@ This is a composite effect controller. It takes another effect controller as a c it multiple times, resetting before the start of each next cycle. ```dart + final ec = RepeatedEffectController(LinearEffectController(1), 10); ``` @@ -695,6 +744,7 @@ re-initialized with new random values on each iteration. Similar to the `RepeatedEffectController`, but repeats its child controller indefinitely. ```dart + final ec = InfiniteEffectController(LinearEffectController(1)); ``` @@ -705,6 +755,7 @@ Executes a sequence of effect controllers, one after another. The list of contro empty. ```dart + final ec = SequenceEffectController([ LinearEffectController(1), PauseEffectController(0.2), @@ -730,6 +781,7 @@ effect. For example, for move effects, they refer to the distance travelled; for the units are radians. ```dart + final ec1 = SpeedEffectController(LinearEffectController(0), speed: 1); final ec2 = EffectController(speed: 1); // same as ec1 ``` @@ -742,6 +794,7 @@ controller is executing the "delay" stage, the effect will be considered "not st `.started` property will be returning `false`. ```dart + final ec = DelayedEffectController(LinearEffectController(1), delay: 5); ``` @@ -752,6 +805,7 @@ This effect controller exhibits noisy behavior, i.e. it oscillates randomly arou controller can be used to implement a variety of shake effects. ```dart + final ec = NoiseEffectController(duration: 0.6, frequency: 10); ``` @@ -763,8 +817,9 @@ duration is re-generated upon each reset, which makes this controller particular repeated contexts, such as [](#repeatedeffectcontroller) or [](#infiniteeffectcontroller). ```dart + final ec = RandomEffectController.uniform( - LinearEffectController(0), // duration here is irrelevant + LinearEffectController(0), // duration here is irrelevant min: 0.5, max: 1.5, ); @@ -782,6 +837,7 @@ natural-looking harmonic oscillations. Two perpendicular move effects governed b `SineEffectControllers` with different periods, will create a [Lissajous curve]. ```dart + final ec = SineEffectController(period: 1); ``` @@ -794,6 +850,7 @@ starting position should be the center of the oscillations, rather than the extr by the standard alternating `EffectController`). ```dart + final ec = ZigzagEffectController(period: 2); ``` @@ -802,6 +859,6 @@ final ec = ZigzagEffectController(period: 2); - [Examples of various effects](https://examples.flame-engine.org/). - [tau]: https://en.wikipedia.org/wiki/Tau_(mathematical_constant) + [Lissajous curve]: https://en.wikipedia.org/wiki/Lissajous_curve diff --git a/doc/flame/examples/lib/glow_effect.dart b/doc/flame/examples/lib/glow_effect.dart new file mode 100644 index 00000000000..c669b0f5d4d --- /dev/null +++ b/doc/flame/examples/lib/glow_effect.dart @@ -0,0 +1,29 @@ +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:flame/game.dart'; + +import 'package:flutter/material.dart'; + +class GlowEffectExample extends FlameGame { + @override + Future onLoad() async { + final paint = Paint()..color = const Color(0xff39FF14); + + add( + CircleComponent( + radius: canvasSize.y / 4, + position: canvasSize / 2, + anchor: Anchor.center, + paint: paint, + )..add( + GlowEffect( + 10.0, + EffectController( + duration: 2, + infinite: true, + ), + ), + ), + ); + } +} diff --git a/doc/flame/examples/lib/main.dart b/doc/flame/examples/lib/main.dart index a196c4e81cf..8ae374df585 100644 --- a/doc/flame/examples/lib/main.dart +++ b/doc/flame/examples/lib/main.dart @@ -9,6 +9,7 @@ import 'package:doc_flame_examples/decorator_rotate3d.dart'; import 'package:doc_flame_examples/decorator_shadow3d.dart'; import 'package:doc_flame_examples/decorator_tint.dart'; import 'package:doc_flame_examples/drag_events.dart'; +import 'package:doc_flame_examples/glow_effect.dart'; import 'package:doc_flame_examples/move_along_path_effect.dart'; import 'package:doc_flame_examples/move_by_effect.dart'; import 'package:doc_flame_examples/move_to_effect.dart'; @@ -63,6 +64,7 @@ void main() { 'value_route': ValueRouteExample.new, 'ray_cast': RayCastExample.new, 'ray_trace': RayTraceExample.new, + 'glow_effect': GlowEffectExample.new, }; final game = routes[page]?.call(); if (game != null) { From fe8f5a6fe9cdecd0584cca73bf29cd45a0ccf4c3 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 17:04:12 +0530 Subject: [PATCH 15/19] test: added glow effect test --- packages/flame/test/effects/glow_effect.dart | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 packages/flame/test/effects/glow_effect.dart diff --git a/packages/flame/test/effects/glow_effect.dart b/packages/flame/test/effects/glow_effect.dart new file mode 100644 index 00000000000..78717a3bb2c --- /dev/null +++ b/packages/flame/test/effects/glow_effect.dart @@ -0,0 +1,37 @@ +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('GlowEffect', () { + testWithFlameGame('can apply to component having HasPaint', (game) async { + final component = _PaintComponent(); + + await game.ensureAdd(component); + + await component.add( + GlowEffect(1, EffectController(duration: 1)), + ); + + game.update(0); + + expect(component.children.length, 1); + expect(component.paint.maskFilter, isNotNull); + + expect( + component.paint.maskFilter.toString(), + 'MaskFilter.blur(BlurStyle.outer, 0.0)', + ); + + game.update(1); + + expect( + component.paint.maskFilter.toString(), + 'MaskFilter.blur(BlurStyle.outer, 1.0)', + ); + }); + }); +} + +class _PaintComponent extends Component with HasPaint {} From 09ccce6541c80c87f98c5d0cc67949c3759de035 Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 18:34:42 +0530 Subject: [PATCH 16/19] fixed formating --- doc/flame/effects.md | 90 ++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 61 deletions(-) diff --git a/doc/flame/effects.md b/doc/flame/effects.md index b44c699991e..a79be3cb35e 100644 --- a/doc/flame/effects.md +++ b/doc/flame/effects.md @@ -111,7 +111,6 @@ offset is relative to the current position of the target: ``` ```dart - final effect = MoveByEffect( Vector2(0, -10), EffectController(duration: 0.5), @@ -139,7 +138,6 @@ point in a straight line. ``` ```dart - final effect = MoveToEffect( Vector2(100, 500), EffectController(duration: 3), @@ -165,10 +163,8 @@ position. ``` ```dart - final effect = MoveAlongPathEffect( - Path() - ..quadraticBezierTo(100, 0, 50, -50), + Path()..quadraticBezierTo(100, 0, 50, -50), EffectController(duration: 1.5), ); ``` @@ -197,9 +193,8 @@ clockwise: ``` ```dart - final effect = RotateEffect.by( - tau / 4, + tau/4, EffectController(duration: 2), ); ``` @@ -219,9 +214,8 @@ target to look east (0º is north, 90º=[tau]/4 east, 180º=tau/2 south, and 270 ``` ```dart - final effect = RotateEffect.to( - tau / 4, + tau/4, EffectController(duration: 2), ); ``` @@ -241,7 +235,6 @@ the component to grow 50% larger: ``` ```dart - final effect = ScaleEffect.by( Vector2.all(1.5), EffectController(duration: 0.3), @@ -262,7 +255,6 @@ This effect works similar to `ScaleEffect.by`, but sets the absolute value of th ``` ```dart - final effect = ScaleEffect.to( Vector2.all(0.5), EffectController(duration: 0.5), @@ -285,10 +277,9 @@ course, the new size will be `Vector2(120, 50)`: ``` ```dart - final effect = SizeEffect.by( - Vector2(-15, 30), - EffectController(duration: 1), + Vector2(-15, 30), + EffectController(duration: 1), ); ``` @@ -308,6 +299,7 @@ target component and its children. Changes the size of the target component to the specified size. Target size cannot be negative: + ```{flutter-app} :sources: ../flame/examples :page: size_to_effect @@ -317,7 +309,6 @@ Changes the size of the target component to the specified size. Target size cann ``` ```dart - final effect = SizeEffect.to( Vector2(90, 80), EffectController(duration: 1), @@ -339,9 +330,8 @@ using `AnchorEffect.by()`. ``` ```dart - final effect = AnchorByEffect( - Vector2(0.1, 0.1), + Vector2(0.1, 0.1), EffectController(speed: 1), ); ``` @@ -361,9 +351,8 @@ Changes the location of the target's anchor. This effect can also be created usi ``` ```dart - final effect = AnchorToEffect( - Anchor.center, + Anchor.center, EffectController(speed: 1), ); ``` @@ -383,7 +372,6 @@ It can only be applied to components that implement the `OpacityProvider`. ``` ```dart - final effect = OpacityEffect.to( 0.2, EffectController(duration: 0.75), @@ -395,6 +383,7 @@ using the `target` parameter. The `HasPaint` mixin implements `OpacityProvider` to easily create providers for desired paintIds. For single paintId `opacityProviderOf` can be used and for multiple paintIds and `opacityProviderOfList` can be used. + ```{flutter-app} :sources: ../flame/examples :page: opacity_effect_with_target @@ -404,7 +393,6 @@ and for multiple paintIds and `opacityProviderOfList` can be used. ``` ```dart - final effect = OpacityEffect.to( 0.2, EffectController(duration: 0.75), @@ -421,8 +409,7 @@ animate the target into full transparency / full visibility respectively. ### `OpacityByEffect` -This effect will change the opacity of the target relative to the specified alpha-value. For -example, +This effect will change the opacity of the target relative to the specified alpha-value. For example, the following effect will change the opacity of the target by `90%`: ```{flutter-app} @@ -434,15 +421,13 @@ the following effect will change the opacity of the target by `90%`: ``` ```dart - final effect = OpacityEffect.by( 0.9, EffectController(duration: 0.75), ); ``` -Currently this effect can only be applied to components that have a `HasPaint` mixin. If the target -component +Currently this effect can only be applied to components that have a `HasPaint` mixin. If the target component uses multiple paints, the effect can target any individual color using the `paintId` parameter. @@ -488,23 +473,22 @@ backward); and also repeat a certain predetermined number of times, or infinitel ``` ```dart - final effect = SequenceEffect([ ScaleEffect.by( - Vector2.all(1.5), + Vector2.all(1.5), EffectController( - duration: 0.2, + duration: 0.2, alternate: true, ), ), MoveEffect.by( - Vector2(30, -50), + Vector2(30, -50), EffectController( duration: 0.5, ), ), OpacityEffect.to( - 0, + 0, EffectController( duration: 0.3, ), @@ -520,7 +504,6 @@ This is a simple effect that can be attached to a component causing it to be rem tree after the specified delay has passed: ```dart - final effect = RemoveEffect(delay: 10.0); ``` @@ -533,7 +516,6 @@ the provided color between a provided range. Usage example: ```dart - final effect = ColorEffect( const Color(0xFF00FF00), const Offset(0.0, 0.8), @@ -585,18 +567,18 @@ common controllers. The syntax of the constructor is the following: ```dart EffectController({ - required double duration, - Curve curve = Curves.linear, - double? reverseDuration, - Curve? reverseCurve, - bool alternate = false, - double atMaxDuration = 0.0, - double atMinDuration = 0.0, - int? repeatCount, - bool infinite = false, - double startDelay = 0.0, - VoidCallback? onMax, - VoidCallback? onMin, + required double duration, + Curve curve = Curves.linear, + double? reverseDuration, + Curve? reverseCurve, + bool alternate = false, + double atMaxDuration = 0.0, + double atMinDuration = 0.0, + int? repeatCount, + bool infinite = false, + double startDelay = 0.0, + VoidCallback? onMax, + VoidCallback? onMin, }); ``` @@ -676,7 +658,6 @@ This is the simplest effect controller that grows linearly from 0 to 1 over the `duration`: ```dart - final ec = LinearEffectController(3); ``` @@ -687,7 +668,6 @@ Similar to the `LinearEffectController`, but it goes in the opposite direction a from 1 to 0 over the specified duration: ```dart - final ec = ReverseLinearEffectController(1); ``` @@ -698,7 +678,6 @@ This effect controller grows non-linearly from 0 to 1 over the specified `durati the provided `curve`: ```dart - final ec = CurvedEffectController(0.5, Curves.easeOut); ``` @@ -709,7 +688,6 @@ Similar to the `CurvedEffectController`, but the controller grows down from 1 to provided `curve`: ```dart - final ec = ReverseCurvedEffectController(0.5, Curves.bounceInOut); ``` @@ -720,7 +698,6 @@ This effect controller keeps the progress at a constant value for the specified Typically, the `progress` would be either 0 or 1: ```dart - final ec = PauseEffectController(1.5, progress: 0); ``` @@ -731,7 +708,6 @@ This is a composite effect controller. It takes another effect controller as a c it multiple times, resetting before the start of each next cycle. ```dart - final ec = RepeatedEffectController(LinearEffectController(1), 10); ``` @@ -744,7 +720,6 @@ re-initialized with new random values on each iteration. Similar to the `RepeatedEffectController`, but repeats its child controller indefinitely. ```dart - final ec = InfiniteEffectController(LinearEffectController(1)); ``` @@ -755,7 +730,6 @@ Executes a sequence of effect controllers, one after another. The list of contro empty. ```dart - final ec = SequenceEffectController([ LinearEffectController(1), PauseEffectController(0.2), @@ -781,7 +755,6 @@ effect. For example, for move effects, they refer to the distance travelled; for the units are radians. ```dart - final ec1 = SpeedEffectController(LinearEffectController(0), speed: 1); final ec2 = EffectController(speed: 1); // same as ec1 ``` @@ -794,7 +767,6 @@ controller is executing the "delay" stage, the effect will be considered "not st `.started` property will be returning `false`. ```dart - final ec = DelayedEffectController(LinearEffectController(1), delay: 5); ``` @@ -805,7 +777,6 @@ This effect controller exhibits noisy behavior, i.e. it oscillates randomly arou controller can be used to implement a variety of shake effects. ```dart - final ec = NoiseEffectController(duration: 0.6, frequency: 10); ``` @@ -817,9 +788,8 @@ duration is re-generated upon each reset, which makes this controller particular repeated contexts, such as [](#repeatedeffectcontroller) or [](#infiniteeffectcontroller). ```dart - final ec = RandomEffectController.uniform( - LinearEffectController(0), // duration here is irrelevant + LinearEffectController(0), // duration here is irrelevant min: 0.5, max: 1.5, ); @@ -837,7 +807,6 @@ natural-looking harmonic oscillations. Two perpendicular move effects governed b `SineEffectControllers` with different periods, will create a [Lissajous curve]. ```dart - final ec = SineEffectController(period: 1); ``` @@ -850,7 +819,6 @@ starting position should be the center of the oscillations, rather than the extr by the standard alternating `EffectController`). ```dart - final ec = ZigzagEffectController(period: 2); ``` @@ -859,6 +827,6 @@ final ec = ZigzagEffectController(period: 2); - [Examples of various effects](https://examples.flame-engine.org/). -[tau]: https://en.wikipedia.org/wiki/Tau_(mathematical_constant) +[tau]: https://en.wikipedia.org/wiki/Tau_(mathematical_constant) [Lissajous curve]: https://en.wikipedia.org/wiki/Lissajous_curve From 98d9e8e648e1298d50d10144de08d3ceacfde736 Mon Sep 17 00:00:00 2001 From: Dipak Prajapati Date: Sat, 29 Oct 2022 20:03:27 +0530 Subject: [PATCH 17/19] Update doc/flame/effects.md Co-authored-by: Lukas Klingsbo --- doc/flame/effects.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/flame/effects.md b/doc/flame/effects.md index d1a092d86be..130f6ec698a 100644 --- a/doc/flame/effects.md +++ b/doc/flame/effects.md @@ -446,7 +446,6 @@ will apply the glowing shade around target by strength of `10`: ``` ```dart - final effect = GlowEffect( 10.0, EffectController(duration: 3), From dc4222ee1be5e6b3f0c5dc88f85faec8b9193009 Mon Sep 17 00:00:00 2001 From: Dipak Prajapati Date: Sat, 29 Oct 2022 20:03:49 +0530 Subject: [PATCH 18/19] Update doc/flame/examples/lib/glow_effect.dart Co-authored-by: Lukas Klingsbo --- doc/flame/examples/lib/glow_effect.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/flame/examples/lib/glow_effect.dart b/doc/flame/examples/lib/glow_effect.dart index c669b0f5d4d..7ec5fdd05df 100644 --- a/doc/flame/examples/lib/glow_effect.dart +++ b/doc/flame/examples/lib/glow_effect.dart @@ -11,8 +11,8 @@ class GlowEffectExample extends FlameGame { add( CircleComponent( - radius: canvasSize.y / 4, - position: canvasSize / 2, + radius: size.y / 4, + position: size / 2, anchor: Anchor.center, paint: paint, )..add( From 0185e65a1b5ea3be7ce9430593850d6d6895160a Mon Sep 17 00:00:00 2001 From: Dipak Date: Sat, 29 Oct 2022 20:05:11 +0530 Subject: [PATCH 19/19] line breaks fixed --- packages/flame/lib/src/effects/glow_effect.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/flame/lib/src/effects/glow_effect.dart b/packages/flame/lib/src/effects/glow_effect.dart index 9f5c8bc6c54..672025ea5ed 100644 --- a/packages/flame/lib/src/effects/glow_effect.dart +++ b/packages/flame/lib/src/effects/glow_effect.dart @@ -6,9 +6,8 @@ import 'package:flame/src/effects/provider_interfaces.dart'; /// Change the MaskFilter on Paint of a component over time. /// /// This effect applies incremental changes to the MaskFilter on Paint of a -/// component and -/// requires that any other effect or update logic applied to the same component -/// also used incremental updates. +/// component and requires that any other effect or update logic applied to the +/// same component also used incremental updates. class GlowEffect extends Effect with EffectTarget { GlowEffect(this.strength, super.controller, {this.style = BlurStyle.outer});