Skip to content

Commit

Permalink
Merge pull request #573 from RafaelBarbosatec/develop
Browse files Browse the repository at this point in the history
Version 3.12.6
  • Loading branch information
RafaelBarbosatec authored Jan 3, 2025
2 parents 6c26567 + 501a6ce commit f806819
Show file tree
Hide file tree
Showing 12 changed files with 346 additions and 31 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
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
Expand Down
41 changes: 41 additions & 0 deletions example/ios/Podfile
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
5 changes: 1 addition & 4 deletions example/lib/pages/mini_games/random_map/map_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,8 @@ class MapGenerator {
matrix[x][y] == tileGrass;

bool baseTreeInGrass = false;
try {
if (x + 3 < matrix.length && y + 3 < matrix.first.length) {
baseTreeInGrass = matrix[x + 3][y + 3] == tileGrass;
} catch (e) {
// ignore: avoid_print
print(e);
}

bool randomFactor = Random().nextDouble() > 0.5;
Expand Down
8 changes: 4 additions & 4 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ packages:
path: ".."
relative: true
source: path
version: "3.12.4"
version: "3.12.5"
boolean_selector:
dependency: transitive
description:
Expand All @@ -76,10 +76,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.19.0"
version: "1.18.0"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -366,7 +366,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
version: "0.0.99"
source_map_stack_trace:
dependency: transitive
description:
Expand Down
3 changes: 2 additions & 1 deletion lib/base/base_game.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:bonfire/bonfire.dart';
import 'package:bonfire/collision/quad_tree/custom_has_quadtree_collision_detection.dart';
import 'package:bonfire/mixins/pointer_detector.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
Expand All @@ -13,7 +14,7 @@ abstract class BaseGame extends FlameGame
with
PointerDetector,
KeyboardEvents,
HasQuadTreeCollisionDetection,
CustomHasQuadTreeCollisionDetection,
HasTimeScale {
BaseGame({super.world, super.camera});
bool enabledGestures = true;
Expand Down
86 changes: 86 additions & 0 deletions lib/collision/quad_tree/custom_collision_detection.dart
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();
}
}
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();
}
}
99 changes: 99 additions & 0 deletions lib/collision/quad_tree/custom_quad_tree_broadphase.dart
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!;
}
}
8 changes: 4 additions & 4 deletions lib/mixins/shader/shader_setter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ class ShaderSetter {

if (item is SetterColor) {
final color = item.value;
_setFloat(shader, color.r * color.a);
_setFloat(shader, color.g * color.a);
_setFloat(shader, color.b * color.a);
_setFloat(shader, color.a);
_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);
}
}
}
Expand Down
Loading

0 comments on commit f806819

Please sign in to comment.