flame-engine / flame-engine/flame
`flame_forge2d` easier `Ray2` visualisation
- Dominant language
- Dart
- Stars
- 10.8k
- Forks
- 1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 21
Description
# What could be improved
For Flame_Forge2D there could exist a mixin that helps users to actually see the `Ray2` in the screen.
# Why should this be improved
This could help people debug `HitBox`es easier.
# Any risks?
I don't believe that anything is a risk here.
# More information
Here is an example using the code below.
https://github.com/flame-engine/flame/assets/52160996/5518a2f7-76e4-427e-bba9-368cec75a27f
Here is an example of what could be written (copied from [raycast_example.dart](https://github.com/flame-engine/flame/blob/main/examples/lib/stories/bridge_libraries/forge2d/raycast_example.dart)):
```dart
mixin RayCastToMouse on Forge2DGame implements RayCast, MouseMovementDetector {
late Vector2 _direction = Vector2(1, 0);
@override
void onMouseMove(PointerHoverInfo info) {
final vector = info.eventPosition.game;
final tempDirection = Vector2(
vector.x - rayStartPosition.x,
vector.y - rayStartPosition.y,
);
_direction = Vector2(
tempDirection.x / tempDirection.length.abs(),
tempDirection.y / tempDirection.length.abs(),
);
}
@override
Vector2 get rayDirection => _direction;
}
mixin RayCast on Forge2DGame implements HasCollisionDetection {
final _points = [];
@override
void update(double dt) {
super.update(dt);
final ray = Ray2(
origin: Vector2(rayStartPosition.x, rayStartPosition.y),
direction: rayDirection,
);
final result = collisionDetection.raycast(ray);
if ((result != null) && (result.intersectionPoint != null)) {
_fireRay(ray.origin, result.intersectionPoint!);
}
}
@override
void render(Canvas canvas) {
super.render(canvas);
for (int i = 0; i < _points.length - 1; i++) {
canvas.drawLine(
_points[i].toOffset(),
_points[i + 1].toOffset(),
Paint()
..color = Colors.red
..strokeWidth = 4,
);
}
}
void _fireRay(
Vector2 rayStart,
Vector2 rayTarget,
) {
_points.clear();
_points.add(worldToScreen(rayStart));
final nearestCallback = _NearestBoxRayCastCallback();
world.raycast(nearestCallback, rayStart, rayTarget);
if (nearestCallback.nearestPoint != null) {
_points.add(worldToScreen(nearestCallback.nearestPoint!));
} else {
_points.add(worldToScreen(rayTarget));
}
}
Vector2 get rayDirection => Vector2(1, 0);
Vector2 get rayStartPosition;
}
class _NearestBoxRayCastCallback extends RayCastCallback {
Vector2? nearestPoint;
double nearestFraction = 0;
@override
double reportFixture(
Fixture fixture,
Vector2 point,
Vector2 normal,
double fraction,
) {
if ((nearestPoint == null) || (fraction < nearestFraction)) {
nearestPoint = point;
nearestFraction = fraction;
}
return 1;
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.