Skip to content

Commit

Permalink
feat: Introduce flame_noise, deprecate NoiseEffectController (#2393)
Browse files Browse the repository at this point in the history
This:

* Deprecates the NoiseEffectController that is based on the deprecated
vector_math library impl
* Adds a new bridge package `flame_noise` to bridge fast noise

Note: the *goal* of this PR is to allow the immediate deprecation of the
old NoiseEffectController by providing an experimental, suitable
replacement. I believe the package flame_noise will look nothing like
this at all if I am able to land [some improvements to the underlying
fast_noise lib](bluefireteam/fast_noise#5). We
will be able to have for example a generic NoiseEffectController.

However I believe we should merge this as an experimental package for
now to unblock removing the current implementation from Flame which is
negatively affecting our scores on pub. Therefore I would advise we
don't spend any time discussing specifics of how the API/impl provided
for the flame_noise, and just go with _something_ instead of nothing.
  • Loading branch information
luanpotter committed Mar 15, 2023
1 parent 426b312 commit b2fdf06
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 5 deletions.
1 change: 1 addition & 0 deletions .github/.cspell/gamedev_dictionary.txt
Expand Up @@ -85,6 +85,7 @@ overmind
overridable
pathfinding
performant
perlin # a type of noise-generating function
platformer
polyline
positionable
Expand Down
5 changes: 3 additions & 2 deletions examples/lib/stories/effects/move_effect_example.dart
Expand Up @@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flame/effects.dart';
import 'package:flame/game.dart';
import 'package:flame/geometry.dart';
import 'package:flame_noise/flame_noise.dart';
import 'package:flutter/material.dart';

class MoveEffectExample extends FlameGame {
Expand Down Expand Up @@ -96,12 +97,12 @@ class MoveEffectExample extends FlameGame {
[
MoveEffect.by(
Vector2(5, 0),
NoiseEffectController(duration: 1, frequency: 20),
PerlinNoiseEffectController(duration: 1, frequency: 20),
),
MoveEffect.by(Vector2.zero(), LinearEffectController(2)),
MoveEffect.by(
Vector2(0, 10),
NoiseEffectController(duration: 1, frequency: 10),
PerlinNoiseEffectController(duration: 1, frequency: 10),
),
],
infinite: true,
Expand Down
1 change: 1 addition & 0 deletions examples/pubspec.yaml
Expand Up @@ -16,6 +16,7 @@ dependencies:
flame_forge2d: ^0.12.2
flame_isolate: ^0.2.0
flame_lottie: ^0.2.0
flame_noise: ^0.1.0
flame_svg: ^1.7.1
flame_tiled: ^1.9.1
flutter:
Expand Down
@@ -1,6 +1,3 @@
// TODO(spydon): Tracked in https://github.com/flame-engine/flame/issues/2329
// ignore_for_file: deprecated_member_use

import 'dart:math';

import 'package:flame/src/effects/controllers/duration_effect_controller.dart';
Expand All @@ -21,7 +18,9 @@ import 'package:vector_math/vector_math_64.dart';
/// 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
/// `offset`.
@Deprecated('Use flame_noise instead. Will be removed in Flame 1.8.0')
class NoiseEffectController extends DurationEffectController {
@Deprecated('Use flame_noise instead. Will be removed in Flame 1.8.0')
NoiseEffectController({
required double duration,
required this.frequency,
Expand Down
@@ -1,3 +1,6 @@
// TODO(spydon): Tracked in https://github.com/flame-engine/flame/issues/2329
// ignore_for_file: deprecated_member_use_from_same_package

import 'dart:math';

import 'package:flame/effects.dart';
Expand Down
22 changes: 22 additions & 0 deletions packages/flame_noise/LICENSE
@@ -0,0 +1,22 @@
MIT License

Copyright (c) 2021 Blue Fire

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

29 changes: 29 additions & 0 deletions packages/flame_noise/README.md
@@ -0,0 +1,29 @@
<!-- markdownlint-disable MD013 -->
<p align="center">
<a href="https://flame-engine.org">
<img alt="flame" width="200px" src="https://user-images.githubusercontent.com/6718144/101553774-3bc7b000-39ad-11eb-8a6a-de2daa31bd64.png">
</a>
</p>

<p align="center">
Integrates the different noises from the <a href="https://github.com/frankpepermans/fast_noise">fast_noise</a> packages into useful <a href="https://github.com/flame-engine/flame">Flame</a> components and effects.
</p>

<p align="center">
<a title="Pub" href="https://pub.dev/packages/flame_noise" ><img src="https://img.shields.io/pub/v/flame_noise.svg?style=popout" /></a>
<a title="Test" href="https://github.com/flame-engine/flame/actions?query=workflow%3Acicd+branch%3Amain"><img src="https://github.com/flame-engine/flame/workflows/cicd/badge.svg?branch=main&event=push"/></a>
<a title="Discord" href="https://discord.gg/pxrBmy4"><img src="https://img.shields.io/discord/509714518008528896.svg"/></a>
<a title="Melos" href="https://github.com/invertase/melos"><img src="https://img.shields.io/badge/maintained%20with-melos-f700ff.svg"/></a>
</p>

---
<!-- markdownlint-enable MD013 -->

<!-- markdownlint-disable-next-line MD002 -->

# flame_noise

> :warning: This package is experimental. Use it at your own risk!
Package to bridge the `fast_noise` library into easy-to-use Flame components
-- in particular, noise-based Effects.
1 change: 1 addition & 0 deletions packages/flame_noise/analysis_options.yaml
@@ -0,0 +1 @@
include: package:flame_lint/analysis_options.yaml
1 change: 1 addition & 0 deletions packages/flame_noise/lib/flame_noise.dart
@@ -0,0 +1 @@
export 'src/effects.dart';
1 change: 1 addition & 0 deletions packages/flame_noise/lib/src/effects.dart
@@ -0,0 +1 @@
export 'effects/perlin_noise_effect_controller.dart';
@@ -0,0 +1,36 @@
import 'package:fast_noise/fast_noise.dart';
import 'package:flame/effects.dart';
import 'package:flutter/animation.dart' show Curve, Curves;

/// Effect controller that oscillates around 0 following a noise curve.
///
/// 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
/// starts at full force, and gradually reduces to zero towards the end.
///
/// This effect controller can be used to implement various shake effects. For
/// 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
/// `offset`.
class PerlinNoiseEffectController 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 PerlinNoise noise;

@override
double get progress {
final x = timer / duration;
final amplitude = taperingCurve.transform(1 - x);
return noise.getPerlin2(x, 1) * amplitude;
}
}
23 changes: 23 additions & 0 deletions packages/flame_noise/pubspec.yaml
@@ -0,0 +1,23 @@
name: flame_noise
description: Integrate the fast_noise package into Flame
version: 0.1.0
homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_noise
funding:
- https://patreon.com/bluefireoss
- https://www.buymeacoffee.com/bluefire

environment:
sdk: ">=2.18.0 <3.0.0"
flutter: ">=3.3.0"

dependencies:
fast_noise: ^1.0.1
flame: ^1.6.0
flutter:
sdk: flutter

dev_dependencies:
dartdoc: ^6.0.1
flame_lint: ^0.2.0
flame_test: ^1.9.2
test: any
51 changes: 51 additions & 0 deletions packages/flame_noise/test/perlin_noise_effect_controller_test.dart
@@ -0,0 +1,51 @@
import 'package:flame_noise/flame_noise.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter/animation.dart';
import 'package:test/test.dart';

void main() {
group('PerlinNoiseEffectController', () {
test('general properties', () {
final ec = PerlinNoiseEffectController(duration: 1, frequency: 12);
expect(ec.duration, 1.0);
expect(ec.taperingCurve, Curves.easeInOutCubic);
expect(ec.started, true);
expect(ec.completed, false);
expect(ec.progress, 0);
expect(ec.isRandom, false);
});

test('progression', () {
final ec = PerlinNoiseEffectController(duration: 1);
final observed = <double>[];
for (var t = 0.0; t < 1.0; t += 0.1) {
observed.add(ec.progress);
ec.advance(0.1);
}
expect(observed, [
0.051042312500000006,
0.04563924284681871,
0.03940642509655703,
0.03206554217595054,
0.02339568569800122,
0.013401536786893568,
0.005727844335713328,
0.002079860116340368,
0.000573751223192571,
0.00008544214797850498,
3.6806334242205264e-9,
]);
});

test('errors', () {
expect(
() => PerlinNoiseEffectController(duration: 0, frequency: 1),
failsAssert('duration must be positive'),
);
expect(
() => PerlinNoiseEffectController(duration: 1, frequency: 0),
failsAssert('frequency parameter must be positive'),
);
});
});
}

0 comments on commit b2fdf06

Please sign in to comment.