diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ad4154cb8..fa99f0643 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,6 +12,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v1 + - name: Intall dart + uses: dart-lang/setup-dart@v1 - name: Setup Flutter uses: subosito/flutter-action@v2 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index d24b0c9b7..b3dcb30f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.12.1 +- Resolve the alignment and visibility issues when using the MiniMap widget with non-1.0 zoom values. Thanks [qulvmp6](https://github.com/qulvmp6) +- Adds `randomMovementArea` param in `RandomMovement` mixin. + # 3.12.0 - Adds `UseShader` mixin. diff --git a/example/lib/pages/home/home_page.dart b/example/lib/pages/home/home_page.dart index d8f128a92..82b24c61e 100644 --- a/example/lib/pages/home/home_page.dart +++ b/example/lib/pages/home/home_page.dart @@ -283,7 +283,6 @@ class _HomePageState extends State { ), ], ), - SectionDrawer( name: 'Mini games', itens: [ diff --git a/example/lib/pages/player/simple/human.dart b/example/lib/pages/player/simple/human.dart index 0174e72cf..361b20815 100644 --- a/example/lib/pages/player/simple/human.dart +++ b/example/lib/pages/player/simple/human.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:bonfire/bonfire.dart'; import 'package:example/shared/util/person_sprite_sheet.dart'; -class HumanPlayer extends SimplePlayer with BlockMovementCollision, UseShader { +class HumanPlayer extends SimplePlayer with BlockMovementCollision { HumanPlayer({ required Vector2 position, }) : super( @@ -14,7 +14,7 @@ class HumanPlayer extends SimplePlayer with BlockMovementCollision, UseShader { ); @override - Future onLoad() { + Future onLoad() async { /// Adds rectangle collision add( RectangleHitbox( diff --git a/example/lib/pages/shader/shader_layer_configuration.dart b/example/lib/pages/shader/shader_layer_configuration.dart index 90e2725ee..36642fad0 100644 --- a/example/lib/pages/shader/shader_layer_configuration.dart +++ b/example/lib/pages/shader/shader_layer_configuration.dart @@ -41,20 +41,19 @@ class ShaderConfiguration extends GameComponent { return super.onLoad(); } - @override - void onMount() { - _loadShader(); - super.onMount(); - } - @override void onRemove() { super.onRemove(); controller.removeListener(_controllerListener); } - Future _loadShader() async { - await Future.delayed(Duration.zero); + @override + void onGameMounted() { + super.onGameMounted(); + _setupShader(); + } + + void _setupShader() { final layer = gameRef.map.layersComponent.elementAtOrNull(1); layer?.shader = shader; layer?.shaderComponentStatic = true; diff --git a/example/lib/pages/shader/shader_page.dart b/example/lib/pages/shader/shader_page.dart index 972d8b793..91fad3f42 100644 --- a/example/lib/pages/shader/shader_page.dart +++ b/example/lib/pages/shader/shader_page.dart @@ -20,6 +20,7 @@ class _ShaderPageState extends State { controller = ShaderConfigController(); super.initState(); } + @override Widget build(BuildContext context) { return Row( @@ -43,7 +44,10 @@ class _ShaderPageState extends State { ], ), ), - Expanded(child: ShaderConfigPanel(controller: controller,)), + Expanded( + child: ShaderConfigPanel( + controller: controller, + )), ], ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index 74540077f..d29b2ea72 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -55,7 +55,7 @@ packages: path: ".." relative: true source: path - version: "3.11.0" + version: "3.12.0" boolean_selector: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index a12f1a490..61704c3a9 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -44,6 +44,7 @@ flutter: uses-material-design: true shaders: + - shaders/baseShader.frag - shaders/waterShader.frag - shaders/waterShaderV2.frag diff --git a/example/shaders/baseShader.frag b/example/shaders/baseShader.frag index fba4a38ba..cf3040b79 100644 --- a/example/shaders/baseShader.frag +++ b/example/shaders/baseShader.frag @@ -7,6 +7,6 @@ uniform sampler2D uTexture; // COMPONETE TEXTURE out vec4 fragColor; void main() { - vec2 uv = FlutterFragCoord().xy / uSize + vec2 uv = FlutterFragCoord().xy / uSize; fragColor = texture(uTexture, uv); } \ No newline at end of file diff --git a/lib/base/bonfire_game.dart b/lib/base/bonfire_game.dart index 46cac6670..b06340458 100644 --- a/lib/base/bonfire_game.dart +++ b/lib/base/bonfire_game.dart @@ -182,18 +182,16 @@ class BonfireGame extends BaseGame implements BonfireGameInterface { ); } + bool _gameMounted = false; @override void update(double dt) { super.update(dt); _intervalUpdateOder.update(dt); _intervalOprimizeTree.update(dt); - } - - @override - void onMount() { - super.onMount(); - _notifyGameMounted(); - onReady?.call(this); + if (!_gameMounted && camera.world?.children.isNotEmpty == true) { + _gameMounted = true; + Future.delayed(Duration.zero, _notifyGameMounted); + } } @override @@ -471,12 +469,8 @@ class BonfireGame extends BaseGame implements BonfireGameInterface { void _notifyGameMounted() { void gameMontedComp(GameComponent c) => c.onGameMounted(); query().forEach(gameMontedComp); - for (var child in camera.children) { - if (child is GameComponent) { - child.onGameMounted(); - } - child.children.query().forEach(gameMontedComp); - } + camera.world?.children.query().forEach(gameMontedComp); + onReady?.call(this); } void _notifyGameDetach() { diff --git a/lib/base/game_component.dart b/lib/base/game_component.dart index aa9977f01..e2bcfe6d1 100644 --- a/lib/base/game_component.dart +++ b/lib/base/game_component.dart @@ -267,5 +267,8 @@ abstract class GameComponent extends PositionComponent void onGameMounted() { _gameMounted = true; + children.query().forEach((c) { + c.onGameMounted(); + }); } } diff --git a/lib/bonfire.dart b/lib/bonfire.dart index 32b94f47f..30a55b799 100644 --- a/lib/bonfire.dart +++ b/lib/bonfire.dart @@ -35,7 +35,7 @@ export 'package:bonfire/map/tiled/world_map_by_tiled.dart'; export 'package:bonfire/map/util/world_map_reader.dart'; export 'package:bonfire/map/world_map.dart'; export 'package:bonfire/mixins/attackable.dart'; -export 'package:bonfire/mixins/automatic_random_movement.dart'; +export 'package:bonfire/mixins/random_movement.dart'; export 'package:bonfire/mixins/elastic_collision.dart'; export 'package:bonfire/mixins/flip_render.dart'; export 'package:bonfire/mixins/follower.dart'; diff --git a/lib/mixins/automatic_random_movement.dart b/lib/mixins/random_movement.dart similarity index 70% rename from lib/mixins/automatic_random_movement.dart rename to lib/mixins/random_movement.dart index 2b9594765..3dc148ca5 100644 --- a/lib/mixins/automatic_random_movement.dart +++ b/lib/mixins/random_movement.dart @@ -42,13 +42,16 @@ mixin RandomMovement on Movement { late Random _random; - double? distanceToArrived; + double? _distanceToArrived; Direction _currentDirection = Direction.left; Vector2 _originPosition = Vector2.zero(); double _lastMinDistance = 0; double _travelledDistance = 0; + // Area where the random movement will be made + ShapeHitbox? randomMovementArea; + /// Method that bo used in [update] method. void runRandomMovement( double dt, { @@ -68,15 +71,26 @@ mixin RandomMovement on Movement { _onStartMove = onStartMove; _onStopMove = onStopMove; - if (distanceToArrived == null) { + if (_distanceToArrived == null) { if (checkInterval(_KEY_INTERVAL_KEEP_STOPPED, timeKeepStopped, dt)) { - final diffDistane = maxDistance - minDistance; - distanceToArrived = minDistance + _random.nextDouble() * diffDistane; - final randomInt = _random.nextInt(directions.length); - _currentDirection = directions.values[randomInt]; + _distanceToArrived = _getDistance(minDistance, maxDistance); + _currentDirection = _getDirection(directions); _originPosition = absoluteCenter.clone(); + if (randomMovementArea != null) { + final targetPosition = _getTargetPosition( + _currentDirection, + _distanceToArrived, + ); + final insideArea = randomMovementArea!.containsLocalPoint( + targetPosition, + ); + if (!insideArea) { + _stop(); + return; + } + } if (checkDirectionWithRayCast) { - if (!canMove(_currentDirection, displacement: distanceToArrived)) { + if (!canMove(_currentDirection, displacement: _distanceToArrived)) { _stop(); return; } @@ -85,7 +99,7 @@ mixin RandomMovement on Movement { } } else { _travelledDistance = absoluteCenter.distanceTo(_originPosition); - if (_travelledDistance >= distanceToArrived!) { + if (_travelledDistance >= _distanceToArrived!) { _stop(); return; } @@ -121,7 +135,7 @@ mixin RandomMovement on Movement { } _onStopMove = null; _onStartMove = null; - distanceToArrived = null; + _distanceToArrived = null; _originPosition = Vector2.zero(); stopMove(); } @@ -131,4 +145,19 @@ mixin RandomMovement on Movement { _random = Random(Random().nextInt(1000)); super.onMount(); } + + double? _getDistance(double minDistance, double maxDistance) { + final diffDistane = maxDistance - minDistance; + return minDistance + _random.nextDouble() * diffDistane; + } + + Direction _getDirection(RandomMovementDirections directions) { + final randomInt = _random.nextInt(directions.length); + return directions.values[randomInt]; + } + + Vector2 _getTargetPosition( + Direction currentDirection, double? distanceToArrived) { + return absoluteCenter + currentDirection.toVector2() * distanceToArrived!; + } } diff --git a/lib/mixins/shader/shader_setter.dart b/lib/mixins/shader/shader_setter.dart index 8b15be8ad..582bb7780 100644 --- a/lib/mixins/shader/shader_setter.dart +++ b/lib/mixins/shader/shader_setter.dart @@ -32,7 +32,8 @@ class ShaderSetter { final List values; final int startFloatIndex; final int startImageIndex; - + int _indexFloat = 0; + int _indexImage = 0; ShaderSetter({ required this.values, this.startFloatIndex = 3, @@ -40,36 +41,38 @@ class ShaderSetter { }); void apply(FragmentShader shader) { - int indexFloat = startFloatIndex; - int indexImage = startImageIndex; + _indexFloat = startFloatIndex; + _indexImage = startImageIndex; for (var item in values) { if (item is SetterDouble) { - shader.setFloat(indexFloat, item.value); - indexFloat++; + _setFloat(shader, item.value); } if (item is SetterImage) { - shader.setImageSampler(indexImage, item.value); - indexImage++; + _setSampler(shader, item.value); } if (item is SetterVector2) { - shader.setFloat(indexFloat, item.value.x); - indexFloat++; - shader.setFloat(indexFloat, item.value.y); - indexFloat++; + _setFloat(shader, item.value.x); + _setFloat(shader, item.value.y); } if (item is SetterColor) { final color = item.value; - shader.setFloat(indexFloat, color.red / 255 * color.opacity); - indexFloat++; - shader.setFloat(indexFloat, color.green / 255 * color.opacity); - indexFloat++; - shader.setFloat(indexFloat, color.blue / 255 * color.opacity); - indexFloat++; - shader.setFloat(indexFloat, color.opacity); - indexFloat++; + _setFloat(shader, color.red / 255 * color.opacity); + _setFloat(shader, color.green / 255 * color.opacity); + _setFloat(shader, color.blue / 255 * color.opacity); + _setFloat(shader, color.opacity); } } } + + void _setFloat(FragmentShader shader, double value) { + shader.setFloat(_indexFloat, value); + _indexFloat++; + } + + void _setSampler(FragmentShader shader, Image value) { + shader.setImageSampler(_indexImage, value); + _indexImage++; + } } diff --git a/lib/mixins/shader/shader_util.dart b/lib/mixins/shader/shader_util.dart new file mode 100644 index 000000000..f8d1a1320 --- /dev/null +++ b/lib/mixins/shader/shader_util.dart @@ -0,0 +1,48 @@ +import 'dart:ui' as ui; + +import 'package:bonfire/bonfire.dart'; + +abstract class ShaderUtils { + static ui.Image renderShader({ + required ui.FragmentShader? shader, + required ui.Canvas canvas, + required Function(ui.Canvas canvas) record, + required Vector2 size, + required ui.Paint paint, + double shaderCanvasScale = 1.0, + bool shaderComponentStatic = false, + ui.Image? snapshot, + }) { + { + ui.Image? innerSnapshot = snapshot; + ui.PictureRecorder recorder = ui.PictureRecorder(); + ui.Canvas canvasRecorder = ui.Canvas(recorder); + canvasRecorder.scale(shaderCanvasScale); + record(canvasRecorder); + + if (shaderComponentStatic) { + if (innerSnapshot == null) { + innerSnapshot = recorder.endRecording().toImageSync( + (size.x * shaderCanvasScale).floor(), + (size.y * shaderCanvasScale).floor(), + ); + shader!.setImageSampler(0, innerSnapshot); + } + } else { + innerSnapshot = recorder.endRecording().toImageSync( + (size.x * shaderCanvasScale).floor(), + (size.y * shaderCanvasScale).floor(), + ); + shader!.setImageSampler(0, innerSnapshot); + } + + paint.shader = shader; + + canvas.drawRect( + ui.Rect.fromLTWH(0, 0, size.x, size.y), + paint, + ); + return innerSnapshot; + } + } +} diff --git a/lib/mixins/shader/use_shader.dart b/lib/mixins/shader/use_shader.dart index 69af58d86..e9494b7dc 100644 --- a/lib/mixins/shader/use_shader.dart +++ b/lib/mixins/shader/use_shader.dart @@ -2,14 +2,16 @@ import 'dart:ui' as ui; import 'package:bonfire/bonfire.dart'; +import 'shader_util.dart'; + export 'shader_setter.dart'; mixin UseShader on PositionComponent { ui.FragmentShader? shader; double shaderCanvasScale = 1; - ui.Paint? _paintShader; bool shaderComponentStatic = false; ui.Image? _snapshot; + ui.Paint? _paint; double _shaderTime = 0; bool get _runShader => shader != null && _canSee; @@ -24,9 +26,9 @@ mixin UseShader on PositionComponent { void update(double dt) { if (_runShader) { _shaderTime += dt; - shader!.setFloat(0, _shaderTime); - shader!.setFloat(1, width); - shader!.setFloat(2, height); + shader?.setFloat(0, _shaderTime); + shader?.setFloat(1, width); + shader?.setFloat(2, height); if (_shaderTime > 100000000) { _shaderTime = 0; } @@ -56,33 +58,17 @@ mixin UseShader on PositionComponent { } } - void _applyShader(ui.Canvas canvas, Function(ui.Canvas canvas) apply) { - ui.PictureRecorder recorder = ui.PictureRecorder(); - ui.Canvas canvasRecorder = ui.Canvas(recorder); - canvasRecorder.scale(shaderCanvasScale); - apply(canvasRecorder); - - if (shaderComponentStatic) { - if (_snapshot == null) { - _snapshot = recorder.endRecording().toImageSync( - (width * shaderCanvasScale).floor(), - (height * shaderCanvasScale).floor(), - ); - shader!.setImageSampler(0, _snapshot!); - } - } else { - _snapshot = recorder.endRecording().toImageSync( - (width * shaderCanvasScale).floor(), - (height * shaderCanvasScale).floor(), - ); - shader!.setImageSampler(0, _snapshot!); - } - - _paintShader ??= ui.Paint()..color = const Color(0xFFFFFFFF); - - canvas.drawRect( - ui.Rect.fromLTWH(0, 0, width, height), - _paintShader!..shader = shader!, + void _applyShader(ui.Canvas canvas, Function(ui.Canvas canvas) record) { + _paint ??= ui.Paint()..color = const ui.Color(0xFFFFFFFF); + _snapshot = ShaderUtils.renderShader( + shader: shader, + canvas: canvas, + record: record, + size: size, + paint: _paint!, + shaderCanvasScale: shaderCanvasScale, + shaderComponentStatic: shaderComponentStatic, + snapshot: _snapshot, ); } } diff --git a/lib/widgets/mini_map/mini_map.dart b/lib/widgets/mini_map/mini_map.dart index f2ae0c4e8..480ffc27e 100644 --- a/lib/widgets/mini_map/mini_map.dart +++ b/lib/widgets/mini_map/mini_map.dart @@ -105,7 +105,7 @@ class _MiniMapState extends State { borderRadius: widget.borderRadius ?? BorderRadius.zero, child: CustomPaint( painter: MiniMapCanvas( - components: widget.game.visibles(), + components: widget.game.query(), tiles: widget.game.map.getRenderedTiles(), cameraPosition: cameraPosition, gameSize: diff --git a/lib/widgets/mini_map/mini_map_canvas.dart b/lib/widgets/mini_map/mini_map_canvas.dart index 70b07c88c..f25e2ffab 100644 --- a/lib/widgets/mini_map/mini_map_canvas.dart +++ b/lib/widgets/mini_map/mini_map_canvas.dart @@ -39,18 +39,9 @@ class MiniMapCanvas extends CustomPainter { double scaleY = size.height / gameSize.y; double scale = max(scaleX, scaleY) * zoom; - double restX = (gameSize.x - gameSize.y) / 2 * scale; - double restY = (gameSize.y - gameSize.x) / 2 * scale; - - if (gameSize.x > gameSize.y) { - restY = 0; - } else if (gameSize.x < gameSize.y) { - restX = 0; - } - canvas.translate( - (cameraPosition.x * scale + restX) * -1, - (cameraPosition.y * scale + restY) * -1, + -cameraPosition.x * scale + size.width / 2 - (gameSize.x * scale) / 2, + -cameraPosition.y * scale + size.height / 2 - (gameSize.y * scale) / 2, ); canvas.save(); canvas.scale(scale); diff --git a/pubspec.lock b/pubspec.lock index 2d7faad7a..d145c5c71 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -119,18 +119,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -159,18 +159,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" ordered_set: dependency: transitive description: @@ -236,10 +236,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" tiledjsonreader: dependency: "direct main" description: @@ -268,10 +268,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.4" web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 07114e6e0..4feb89ce4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: bonfire description: (RPG maker) Create RPG-style or similar games more simply with Flame. -version: 3.12.0 +version: 3.12.1 homepage: https://bonfire-engine.github.io repository: https://github.com/RafaelBarbosatec/bonfire issue_tracker: https://github.com/RafaelBarbosatec/bonfire/issues