-
-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #573 from RafaelBarbosatec/develop
Version 3.12.6
- Loading branch information
Showing
12 changed files
with
346 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
# 3.12.6 | ||
- Fix `RangerError`. | ||
|
||
# 3.12.5 | ||
- Update `a_star_algorithm`. | ||
- InitialMapZoomFitEnum improvements | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Uncomment this line to define a global platform for your project | ||
# platform :ios, '12.0' | ||
|
||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. | ||
ENV['COCOAPODS_DISABLE_STATS'] = 'true' | ||
|
||
project 'Runner', { | ||
'Debug' => :debug, | ||
'Profile' => :release, | ||
'Release' => :release, | ||
} | ||
|
||
def flutter_root | ||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | ||
unless File.exist?(generated_xcode_build_settings_path) | ||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | ||
end | ||
|
||
File.foreach(generated_xcode_build_settings_path) do |line| | ||
matches = line.match(/FLUTTER_ROOT\=(.*)/) | ||
return matches[1].strip if matches | ||
end | ||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | ||
end | ||
|
||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | ||
|
||
flutter_ios_podfile_setup | ||
|
||
target 'Runner' do | ||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | ||
target 'RunnerTests' do | ||
inherit! :search_paths | ||
end | ||
end | ||
|
||
post_install do |installer| | ||
installer.pods_project.targets.each do |target| | ||
flutter_additional_ios_build_settings(target) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// ignore_for_file: invalid_use_of_internal_member | ||
|
||
import 'package:bonfire/collision/quad_tree/custom_quad_tree_broadphase.dart'; | ||
import 'package:flame/collisions.dart'; | ||
import 'package:flutter/widgets.dart'; | ||
|
||
/// Collision detection modification to support a Quad Tree broadphase. | ||
/// | ||
/// Do not use standard [items] list for components. Instead adds all components | ||
/// into [QuadTreeBroadphase] class. | ||
class CustomQuadTreeCollisionDetection | ||
extends StandardCollisionDetection<QuadTreeBroadphase> { | ||
CustomQuadTreeCollisionDetection({ | ||
required Rect mapDimensions, | ||
required ExternalBroadphaseCheck onComponentTypeCheck, | ||
required ExternalMinDistanceCheck minimumDistanceCheck, | ||
int maxObjects = 25, | ||
int maxDepth = 10, | ||
}) : super( | ||
broadphase: CustomQuadTreeBroadphase( | ||
mainBoxSize: mapDimensions, | ||
maxObjects: maxObjects, | ||
maxDepth: maxDepth, | ||
broadphaseCheck: onComponentTypeCheck, | ||
minimumDistanceCheck: minimumDistanceCheck, | ||
), | ||
); | ||
|
||
final _listenerCollisionType = <ShapeHitbox, VoidCallback>{}; | ||
final _scheduledUpdate = <ShapeHitbox>{}; | ||
|
||
@override | ||
void add(ShapeHitbox item) { | ||
item.onAabbChanged = () => _scheduledUpdate.add(item); | ||
void listenerCollisionType() { | ||
if (item.isMounted) { | ||
if (item.collisionType == CollisionType.active) { | ||
broadphase.activeHitboxes.add(item); | ||
} else { | ||
broadphase.activeHitboxes.remove(item); | ||
} | ||
} | ||
} | ||
|
||
item.collisionTypeNotifier.addListener(listenerCollisionType); | ||
_listenerCollisionType[item] = listenerCollisionType; | ||
|
||
super.add(item); | ||
} | ||
|
||
@override | ||
void addAll(Iterable<ShapeHitbox> items) { | ||
for (final item in items) { | ||
add(item); | ||
} | ||
} | ||
|
||
@override | ||
void remove(ShapeHitbox item) { | ||
item.onAabbChanged = null; | ||
final listenerCollisionType = _listenerCollisionType[item]; | ||
if (listenerCollisionType != null) { | ||
item.collisionTypeNotifier.removeListener(listenerCollisionType); | ||
_listenerCollisionType.remove(item); | ||
} | ||
|
||
super.remove(item); | ||
} | ||
|
||
@override | ||
void removeAll(Iterable<ShapeHitbox> items) { | ||
broadphase.clear(); | ||
for (final item in items) { | ||
remove(item); | ||
} | ||
} | ||
|
||
@override | ||
void run() { | ||
for (final hitbox in _scheduledUpdate) { | ||
broadphase.updateTransform(hitbox); | ||
} | ||
_scheduledUpdate.clear(); | ||
super.run(); | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
lib/collision/quad_tree/custom_has_quadtree_collision_detection.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import 'package:bonfire/collision/quad_tree/custom_collision_detection.dart'; | ||
import 'package:flame/camera.dart'; | ||
import 'package:flame/collisions.dart'; | ||
import 'package:flame/extensions.dart'; | ||
import 'package:flame/game.dart'; | ||
|
||
/// This should be applied to a [FlameGame] to bring QuadTree collision | ||
/// support. | ||
/// | ||
/// Use [HasQuadTreeCollisionDetection] if you have lots of collidable entities | ||
/// in your game, but most of them are static (such as platforms, walls, trees, | ||
/// buildings). | ||
/// | ||
/// Always experiment before deciding which collision detection | ||
/// method to use. It's not unheard of to see better performance with | ||
/// the default [HasCollisionDetection] mixin. | ||
/// | ||
/// [initializeCollisionDetection] should be called in the game's [onLoad] | ||
/// method. | ||
mixin CustomHasQuadTreeCollisionDetection<W extends World> on FlameGame<W> | ||
implements HasCollisionDetection<QuadTreeBroadphase> { | ||
late CustomQuadTreeCollisionDetection _collisionDetection; | ||
|
||
@override | ||
CustomQuadTreeCollisionDetection get collisionDetection => | ||
_collisionDetection; | ||
|
||
@override | ||
set collisionDetection( | ||
CollisionDetection<ShapeHitbox, QuadTreeBroadphase> cd, | ||
) { | ||
if (cd is! CustomQuadTreeCollisionDetection) { | ||
throw 'Must be CustomQuadTreeCollisionDetection!'; | ||
} | ||
_collisionDetection = cd; | ||
} | ||
|
||
/// Initialize the QuadTree. | ||
/// | ||
/// - [mapDimensions] describes the collision area coordinates and size. | ||
/// Should match to game map's position and size. | ||
/// - [maxObjects] (optional) - maximum amount of objects in one quadrant. | ||
/// - [maxLevels] (optional) - maximum number of nested quadrants. | ||
/// - [minimumDistance] (optional) - specify minimum distance between objects | ||
/// to consider them as possibly colliding. You can also implement the | ||
/// [minimumDistanceCheck] if you need some custom behavior. | ||
/// | ||
/// The [onComponentTypeCheck] checks if objects of different types should | ||
/// collide. | ||
/// The result of the calculation is cached so you should not check any | ||
/// dynamical parameters here, the function is intended to be used as pure | ||
/// type checker. | ||
/// It should usually not be overridden, see | ||
/// [CollisionCallbacks.onComponentTypeCheck] instead | ||
void initializeCollisionDetection({ | ||
required Rect mapDimensions, | ||
double? minimumDistance, | ||
int maxObjects = 25, | ||
int maxLevels = 10, | ||
}) { | ||
_collisionDetection = CustomQuadTreeCollisionDetection( | ||
mapDimensions: mapDimensions, | ||
maxDepth: maxLevels, | ||
maxObjects: maxObjects, | ||
onComponentTypeCheck: onComponentTypeCheck, | ||
minimumDistanceCheck: minimumDistanceCheck, | ||
); | ||
this.minimumDistance = minimumDistance; | ||
} | ||
|
||
double? minimumDistance; | ||
|
||
bool minimumDistanceCheck(Vector2 activeItemCenter, Vector2 potentialCenter) { | ||
return minimumDistance == null || | ||
!((activeItemCenter.x - potentialCenter.x).abs() > minimumDistance! || | ||
(activeItemCenter.y - potentialCenter.y).abs() > minimumDistance!); | ||
} | ||
|
||
bool onComponentTypeCheck(ShapeHitbox first, ShapeHitbox second) { | ||
return first.onComponentTypeCheck(second) && | ||
second.onComponentTypeCheck(first); | ||
} | ||
|
||
@override | ||
void update(double dt) { | ||
super.update(dt); | ||
collisionDetection.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import 'package:flame/collisions.dart'; | ||
import 'package:flame/extensions.dart'; | ||
|
||
/// Performs Quad Tree broadphase check. | ||
/// | ||
/// See [HasQuadTreeCollisionDetection.initializeCollisionDetection] for a | ||
/// detailed description of its initialization parameters. | ||
class CustomQuadTreeBroadphase extends QuadTreeBroadphase { | ||
CustomQuadTreeBroadphase({ | ||
required super.mainBoxSize, | ||
required super.broadphaseCheck, | ||
required super.minimumDistanceCheck, | ||
super.maxDepth, | ||
super.maxObjects, | ||
}); | ||
|
||
final _broadphaseCheckCache = <ShapeHitbox, Map<ShapeHitbox, bool>>{}; | ||
|
||
final _cachedCenters = <ShapeHitbox, Vector2>{}; | ||
|
||
final _potentials = <int, CollisionProspect<ShapeHitbox>>{}; | ||
final _potentialsTmp = <ShapeHitbox>[]; | ||
final _prospectPool = ProspectPool<ShapeHitbox>(); | ||
|
||
@override | ||
Iterable<CollisionProspect<ShapeHitbox>> query() { | ||
_potentials.clear(); | ||
_potentialsTmp.clear(); | ||
|
||
for (final activeItem in activeHitboxes) { | ||
if (activeItem.isRemoving || !activeItem.isMounted) { | ||
tree.remove(activeItem); | ||
continue; | ||
} | ||
|
||
final itemCenter = activeItem.aabb.center; | ||
final potentiallyCollide = tree.query(activeItem); | ||
for (final potential in potentiallyCollide.entries.first.value) { | ||
if (potential.collisionType == CollisionType.inactive) { | ||
continue; | ||
} | ||
|
||
if (_broadphaseCheckCache[activeItem]?[potential] == false) { | ||
continue; | ||
} | ||
|
||
if (!potential.allowSiblingCollision && | ||
potential.hitboxParent == activeItem.hitboxParent && | ||
potential.isMounted) { | ||
continue; | ||
} | ||
|
||
final distanceCloseEnough = minimumDistanceCheck.call( | ||
itemCenter, | ||
_cacheCenterOfHitbox(potential), | ||
); | ||
if (distanceCloseEnough == false) { | ||
continue; | ||
} | ||
|
||
_potentialsTmp | ||
..add(activeItem) | ||
..add(potential); | ||
} | ||
} | ||
|
||
if (_potentialsTmp.isNotEmpty) { | ||
for (var i = 0; i < _potentialsTmp.length; i += 2) { | ||
final item0 = _potentialsTmp[i]; | ||
final item1 = _potentialsTmp[i + 1]; | ||
if (broadphaseCheck(item0, item1)) { | ||
final CollisionProspect<ShapeHitbox> prospect; | ||
while (_prospectPool.length <= i) { | ||
_prospectPool.expand(item0); | ||
} | ||
prospect = _prospectPool[i]..set(item0, item1); | ||
_potentials[prospect.hash] = prospect; | ||
} else { | ||
if (_broadphaseCheckCache[item0] == null) { | ||
_broadphaseCheckCache[item0] = {}; | ||
} | ||
_broadphaseCheckCache[item0]![item1] = false; | ||
} | ||
} | ||
} | ||
return _potentials.values; | ||
} | ||
|
||
/// Caches hitbox center because calculating on-the-fly is too expensive | ||
/// whereas many of game objects could not change theirs position or size | ||
Vector2 _cacheCenterOfHitbox(ShapeHitbox hitbox) { | ||
var cache = _cachedCenters[hitbox]; | ||
if (cache == null) { | ||
_cachedCenters[hitbox] = hitbox.aabb.center; | ||
cache = _cachedCenters[hitbox]; | ||
} | ||
return cache!; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.