flame-engine / flame-engine/flame

`flame_forge2d` easier `Ray2` visualisation

Open
#2,533 6 comments 0 reactions 1 assignee Claimed by @FMorschel View on GitHub
enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.