feat!: Update flame_noise to use latest version of fast_noise (#3015)

Update flame_noise to use the latest version of fast_noise, basically
replacing the Perlin-specific effect controller with a generic
`NoiseEffectController` that can take in any noise class (leveraging the
new Noise2 interface).

Just update from `PerlinNoiseEffectController` to
`NoiseEffectController` and provide the noise/parameters you want
directly into the `noise` field.

---------

Co-authored-by: Lukas Klingsbo <me@lukas.fyi>
This commit is contained in:
Luan Nico
2024-02-04 10:37:54 -05:00
committed by GitHub
parent 343bdca79b
commit 2fd84c846f
7 changed files with 38 additions and 29 deletions

View File

@ -9,7 +9,7 @@ import 'package:flutter/services.dart';
class CameraFollowAndWorldBoundsExample extends FlameGame class CameraFollowAndWorldBoundsExample extends FlameGame
with HasKeyboardHandlerComponents { with HasKeyboardHandlerComponents {
static const description = ''' static const description = '''
This example demonstrates camera following the player, but also obeying the This example demonstrates camera following the player, but also obeying the
world bounds (which are set up to leave a small margin around the visible world bounds (which are set up to leave a small margin around the visible
part of the ground). part of the ground).

View File

@ -85,7 +85,10 @@ This examples showcases how raycast APIs can be used to detect hits within certa
camera.viewfinder.add( camera.viewfinder.add(
MoveEffect.by( MoveEffect.by(
Vector2(5, 5), Vector2(5, 5),
PerlinNoiseEffectController(duration: 0.2, frequency: 400), NoiseEffectController(
duration: 0.2,
noise: PerlinNoise(frequency: 400),
),
), ),
); );
} }

View File

@ -107,12 +107,18 @@ class _MoveEffectWorld extends World {
[ [
MoveEffect.by( MoveEffect.by(
Vector2(5, 0), Vector2(5, 0),
PerlinNoiseEffectController(duration: 1, frequency: 20), NoiseEffectController(
duration: 1,
noise: PerlinNoise(frequency: 20),
),
), ),
MoveEffect.by(Vector2.zero(), LinearEffectController(2)), MoveEffect.by(Vector2.zero(), LinearEffectController(2)),
MoveEffect.by( MoveEffect.by(
Vector2(0, 10), Vector2(0, 10),
PerlinNoiseEffectController(duration: 1, frequency: 10), NoiseEffectController(
duration: 1,
noise: PerlinNoise(frequency: 10),
),
), ),
], ],
infinite: true, infinite: true,

View File

@ -1 +1,3 @@
export 'effects/perlin_noise_effect_controller.dart'; export 'package:fast_noise/fast_noise.dart';
export 'effects/noise_effect_controller.dart';

View File

@ -2,7 +2,7 @@ import 'package:fast_noise/fast_noise.dart';
import 'package:flame/effects.dart'; import 'package:flame/effects.dart';
import 'package:flutter/animation.dart' show Curve, Curves; import 'package:flutter/animation.dart' show Curve, Curves;
/// Effect controller that oscillates around 0 following a noise curve. /// Effect controller that oscillates around following a noise curve.
/// ///
/// The [taperingCurve] describes how the effect fades out over time. The /// The [taperingCurve] describes how the effect fades out over time. The
/// curve that you supply will be flipped along the X axis, so that the effect /// curve that you supply will be flipped along the X axis, so that the effect
@ -12,25 +12,21 @@ import 'package:flutter/animation.dart' show Curve, Curves;
/// example, putting into a `MoveEffect.by` will create a shake motion, where /// example, putting into a `MoveEffect.by` will create a shake motion, where
/// the magnitude and the direction of shaking is controlled by the effect's /// the magnitude and the direction of shaking is controlled by the effect's
/// `offset`. /// `offset`.
class PerlinNoiseEffectController extends DurationEffectController { class NoiseEffectController extends DurationEffectController {
PerlinNoiseEffectController({
required double duration,
int octaves = 3,
double frequency = 0.05,
this.taperingCurve = Curves.easeInOutCubic,
int seed = 1337,
}) : assert(duration > 0, 'duration must be positive'),
assert(frequency > 0, 'frequency parameter must be positive'),
noise = PerlinNoise(seed: seed, octaves: octaves, frequency: frequency),
super(duration);
final Curve taperingCurve; final Curve taperingCurve;
final PerlinNoise noise; final Noise2 noise;
NoiseEffectController({
required double duration,
this.taperingCurve = Curves.easeInOutCubic,
Noise2? noise,
}) : noise = noise ?? PerlinNoise(),
super(duration);
@override @override
double get progress { double get progress {
final x = timer / duration; final x = timer / duration;
final amplitude = taperingCurve.transform(1 - x); final amplitude = taperingCurve.transform(1 - x);
return noise.getPerlin2(x, 1) * amplitude; return noise.getNoise2(x, 1) * amplitude;
} }
} }

View File

@ -12,7 +12,7 @@ environment:
flutter: ">=3.13.0" flutter: ">=3.13.0"
dependencies: dependencies:
fast_noise: ^1.0.1 fast_noise: ^2.0.0
flame: ^1.14.0 flame: ^1.14.0
flutter: flutter:
sdk: flutter sdk: flutter

View File

@ -6,7 +6,10 @@ import 'package:test/test.dart';
void main() { void main() {
group('PerlinNoiseEffectController', () { group('PerlinNoiseEffectController', () {
test('general properties', () { test('general properties', () {
final ec = PerlinNoiseEffectController(duration: 1, frequency: 12); final ec = NoiseEffectController(
duration: 1,
noise: PerlinNoise(frequency: 12),
);
expect(ec.duration, 1.0); expect(ec.duration, 1.0);
expect(ec.taperingCurve, Curves.easeInOutCubic); expect(ec.taperingCurve, Curves.easeInOutCubic);
expect(ec.started, true); expect(ec.started, true);
@ -16,7 +19,10 @@ void main() {
}); });
test('progression', () { test('progression', () {
final ec = PerlinNoiseEffectController(duration: 1); final ec = NoiseEffectController(
duration: 1,
noise: PerlinNoise(frequency: 0.05),
);
final observed = <double>[]; final observed = <double>[];
for (var t = 0.0; t < 1.0; t += 0.1) { for (var t = 0.0; t < 1.0; t += 0.1) {
observed.add(ec.progress); observed.add(ec.progress);
@ -39,12 +45,8 @@ void main() {
test('errors', () { test('errors', () {
expect( expect(
() => PerlinNoiseEffectController(duration: 0, frequency: 1), () => NoiseEffectController(duration: -1),
failsAssert('duration must be positive'), failsAssert('Duration cannot be negative: -1.0'),
);
expect(
() => PerlinNoiseEffectController(duration: 1, frequency: 0),
failsAssert('frequency parameter must be positive'),
); );
}); });
}); });