From 939a3b9f69e41ab2021b4152e2dbb995079d1c67 Mon Sep 17 00:00:00 2001 From: Rafael Almeida Barbosa Date: Mon, 18 Nov 2024 14:32:37 -0300 Subject: [PATCH 1/2] chore: random movement improvements --- CHANGELOG.md | 3 + example/lib/pages/enemy/melee_enemy.dart | 21 +++-- lib/mixins/random_movement.dart | 101 ++++++++++++++++------- 3 files changed, 87 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3dcb30f..18dffd7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# next +- `RandomMovement` improvements + # 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. diff --git a/example/lib/pages/enemy/melee_enemy.dart b/example/lib/pages/enemy/melee_enemy.dart index 60bec2a9..35888bee 100644 --- a/example/lib/pages/enemy/melee_enemy.dart +++ b/example/lib/pages/enemy/melee_enemy.dart @@ -16,15 +16,18 @@ class MeleeEnemy extends SimpleEnemy { @override void update(double dt) { - seeAndMoveToPlayer(closePlayer: (p) { - animation?.showStroke(Colors.white, 1); - if (checkInterval('attack', 600, dt)) { - _playAttackAnimation(); - } - }, notObserved: () { - animation?.hideStroke(); - return true; - }); + seeAndMoveToPlayer( + closePlayer: (p) { + animation?.showStroke(Colors.white, 1); + if (checkInterval('attack', 600, dt)) { + _playAttackAnimation(); + } + }, + notObserved: () { + animation?.hideStroke(); + return true; + }, + ); super.update(dt); } diff --git a/lib/mixins/random_movement.dart b/lib/mixins/random_movement.dart index 3dc148ca..0dadc85c 100644 --- a/lib/mixins/random_movement.dart +++ b/lib/mixins/random_movement.dart @@ -46,7 +46,6 @@ mixin RandomMovement on Movement { Direction _currentDirection = Direction.left; Vector2 _originPosition = Vector2.zero(); - double _lastMinDistance = 0; double _travelledDistance = 0; // Area where the random movement will be made @@ -67,42 +66,33 @@ mixin RandomMovement on Movement { Function(Direction direction)? onStartMove, Function()? onStopMove, }) { - _lastMinDistance = minDistance; _onStartMove = onStartMove; _onStopMove = onStopMove; if (_distanceToArrived == null) { if (checkInterval(_KEY_INTERVAL_KEEP_STOPPED, timeKeepStopped, dt)) { - _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)) { - _stop(); - return; - } + final target = _getTarget( + minDistance, + maxDistance, + checkDirectionWithRayCast, + ); + if (target == null) { + _stop(); + return; } + _currentDirection = target.direction; + _distanceToArrived = target.distance; + _originPosition = absoluteCenter.clone(); _onStartMove?.call(_currentDirection); } } else { _travelledDistance = absoluteCenter.distanceTo(_originPosition); - if (_travelledDistance >= _distanceToArrived!) { + final isCanMove = canMove(_currentDirection, displacement: speed); + if (_travelledDistance >= _distanceToArrived! || !isCanMove) { _stop(); return; } + moveFromDirection(_currentDirection, speed: speed); if (updateAngle) { angle = _currentDirection.toRadians(); @@ -130,9 +120,6 @@ mixin RandomMovement on Movement { void _stop() { _onStopMove?.call(); - if (_travelledDistance < _lastMinDistance) { - resetInterval(_KEY_INTERVAL_KEEP_STOPPED); - } _onStopMove = null; _onStartMove = null; _distanceToArrived = null; @@ -146,7 +133,7 @@ mixin RandomMovement on Movement { super.onMount(); } - double? _getDistance(double minDistance, double maxDistance) { + double _getDistance(double minDistance, double maxDistance) { final diffDistane = maxDistance - minDistance; return minDistance + _random.nextDouble() * diffDistane; } @@ -157,7 +144,63 @@ mixin RandomMovement on Movement { } Vector2 _getTargetPosition( - Direction currentDirection, double? distanceToArrived) { + Direction currentDirection, + double? distanceToArrived, + ) { return absoluteCenter + currentDirection.toVector2() * distanceToArrived!; } + + _RandomPositionTarget? _getTarget( + double minDistance, + double maxDistance, + bool checkDirectionWithRayCast, + ) { + int index = 0; + while (index < 100) { + final distance = _getDistance(minDistance, maxDistance); + final direction = _getDirection(RandomMovementDirections.all); + final targetPosition = _getTargetPosition(direction, distance); + bool isRaycastOk = true; + + if (checkDirectionWithRayCast) { + isRaycastOk = canMove( + _currentDirection, + displacement: _distanceToArrived, + ); + } + + if (randomMovementArea != null) { + final insideArea = randomMovementArea!.containsPoint( + targetPosition, + ); + if (insideArea && isRaycastOk) { + return _RandomPositionTarget( + position: targetPosition, + direction: direction, + distance: distance, + ); + } + } else if (isRaycastOk) { + return _RandomPositionTarget( + position: targetPosition, + direction: direction, + distance: distance, + ); + } + + index++; + } + return null; + } +} + +class _RandomPositionTarget { + final Vector2 position; + final Direction direction; + final double distance; + + _RandomPositionTarget( + {required this.position, + required this.direction, + required this.distance}); } From a8188e199d7a796f5be9d9d9dca99540f702704f Mon Sep 17 00:00:00 2001 From: Pessoal Dev Date: Fri, 22 Nov 2024 07:36:17 -0300 Subject: [PATCH 2/2] chore: increment version --- CHANGELOG.md | 2 +- pubspec.yaml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18dffd7b..02874ce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# next +# 3.12.2 - `RandomMovement` improvements # 3.12.1 diff --git a/pubspec.yaml b/pubspec.yaml index 4feb89ce..0588e1da 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,9 @@ name: bonfire description: (RPG maker) Create RPG-style or similar games more simply with Flame. -version: 3.12.1 +version: 3.12.2 homepage: https://bonfire-engine.github.io repository: https://github.com/RafaelBarbosatec/bonfire issue_tracker: https://github.com/RafaelBarbosatec/bonfire/issues -# documentation: https://bonfire-engine.github.io environment: sdk: ">=3.4.0 <4.0.0"