diff --git a/packages/flame/lib/src/collisions/collision_detection.dart b/packages/flame/lib/src/collisions/collision_detection.dart index 9dfd14e889a..7601699ad7d 100644 --- a/packages/flame/lib/src/collisions/collision_detection.dart +++ b/packages/flame/lib/src/collisions/collision_detection.dart @@ -96,17 +96,19 @@ abstract class CollisionDetection> { List>? out, }); - /// Gives back all hitboxes and intersection points the ray hits. + /// Follows the ray and its reflections until [maxDepth] is reached and then + /// returns all hitboxes, intersection points, normals and reflection rays + /// (bundled in a list of [RaycastResult]s) from where the ray hits. /// /// [maxDepth] is how many times the ray should collide before returning a - /// result, defaults to 100. + /// result, defaults to 10. /// /// If [out] is provided the [RaycastResult]s in that list be modified and /// returned with the result. If there are less objects in [out] than the /// result requires, the missing [RaycastResult] objects will be created. - List> raytrace( + Iterable> raytrace( Ray2 ray, { - double maxDepth = 100, + double maxDepth = 10, List>? out, }); } diff --git a/packages/flame/lib/src/collisions/standard_collision_detection.dart b/packages/flame/lib/src/collisions/standard_collision_detection.dart index 9da12204629..c6c9ae96435 100644 --- a/packages/flame/lib/src/collisions/standard_collision_detection.dart +++ b/packages/flame/lib/src/collisions/standard_collision_detection.dart @@ -130,11 +130,12 @@ class StandardCollisionDetection extends CollisionDetection { } @override - List> raytrace( + Iterable> raytrace( Ray2 ray, { - double maxDepth = 100, + double maxDepth = 10, List>? out, - }) { + }) sync* { + out?.forEach((e) => e.reset()); final result = out ?? >[]; var currentRay = ray; for (var i = 0; i < maxDepth; i++) { @@ -145,14 +146,11 @@ class StandardCollisionDetection extends CollisionDetection { currentRay = currentResult.reflectionRay!; if (!hasResultObject) { result.add(currentResult); + yield currentResult; } } else { - for (var j = i; j < result.length; j++) { - result[j].reset(); - } break; } } - return result; } } diff --git a/packages/flame/test/collisions/collision_detection_test.dart b/packages/flame/test/collisions/collision_detection_test.dart index b8c12cc5b8c..1b86bcb2149 100644 --- a/packages/flame/test/collisions/collision_detection_test.dart +++ b/packages/flame/test/collisions/collision_detection_test.dart @@ -1113,7 +1113,7 @@ void main() { )..add(CircleHitbox()); await game.ensureAddAll([circle1, circle2]); final ray = Ray2(Vector2(0, 10), Vector2.all(1.0)..normalize()); - final results = game.collisionDetection.raytrace(ray); + final results = game.collisionDetection.raytrace(ray).toList(); expect(results.length, 2); expect(results.every((e) => e.isActive), isTrue); expect(results.every((e) => e.isInsideHitbox), isFalse); @@ -1146,7 +1146,7 @@ void main() { )..add(RectangleHitbox()); await game.ensureAddAll([rectangle1, rectangle2]); final ray = Ray2(Vector2(0, 10), Vector2.all(1.0)..normalize()); - final results = game.collisionDetection.raytrace(ray); + final results = game.collisionDetection.raytrace(ray).toList(); expect(results.length, 2); expect(results.every((e) => e.isActive), isTrue); expect(results.every((e) => e.isInsideHitbox), isFalse); @@ -1156,7 +1156,8 @@ void main() { final reflectionRay1 = results[0].reflectionRay; expect(reflectionRay1?.origin, Vector2(10, 20)); expect(reflectionRay1?.direction, Vector2(-1, 1)..normalize()); - final results2 = game.collisionDetection.raytrace(reflectionRay1!); + final results2 = + game.collisionDetection.raytrace(reflectionRay1!).toList(); expect(results2.length, 1); // Second box expect(results[1].intersectionPoint, Vector2(-10, 40)); @@ -1176,8 +1177,8 @@ void main() { )..add(RectangleHitbox()); await game.ensureAddAll([rectangle1, rectangle2]); final ray = Ray2(Vector2(20, 10), Vector2(1, 1)..normalize()); - final results = game.collisionDetection.raytrace(ray); - expect(results.length, 100); + final results = game.collisionDetection.raytrace(ray).toList(); + expect(results.length, 10); expect(results.every((e) => e.isActive), isTrue); expect(results[0].isInsideHitbox, isFalse); expect(results[1].isInsideHitbox, isTrue); @@ -1187,8 +1188,9 @@ void main() { final reflectionRay1 = results[0].reflectionRay; expect(reflectionRay1?.origin, Vector2(30, 20)); expect(reflectionRay1?.direction, Vector2(1, -1)..normalize()); - final results2 = game.collisionDetection.raytrace(reflectionRay1!); - expect(results2.length, 100); + final results2 = + game.collisionDetection.raytrace(reflectionRay1!).toList(); + expect(results2.length, 10); // Second box expect(results[1].intersectionPoint, Vector2(50, 0)); expect(results[1].normal, Vector2(0, 1));