Skip to content

Commit

Permalink
fix: BodyComponent fixtures should test with global point (#3042)
Browse files Browse the repository at this point in the history
The previous solution didn't take the whole transform into
consideration, this one does.



Closes: #3039
  • Loading branch information
spydon committed Feb 17, 2024
1 parent 4f053ed commit 7c3038b
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 5 deletions.
4 changes: 1 addition & 3 deletions packages/flame_forge2d/lib/body_component.dart
Expand Up @@ -207,9 +207,7 @@ class BodyComponent<T extends Forge2DGame> extends Component

@override
bool containsLocalPoint(Vector2 point) {
_hitTestPoint
..setFrom(body.position)
..add(point);
_transform.localToGlobal(point, output: _hitTestPoint);
return body.fixtures.any((fixture) => fixture.testPoint(_hitTestPoint));
}

Expand Down
86 changes: 84 additions & 2 deletions packages/flame_forge2d/test/body_component_test.dart
@@ -1,5 +1,12 @@
import 'package:flame/components.dart' show ComponentKey, PositionComponent;
// ignore_for_file: invalid_use_of_internal_member

import 'dart:math';

import 'package:flame/components.dart'
show Anchor, ComponentKey, PositionComponent;
import 'package:flame/events.dart';
import 'package:flame/extensions.dart';
import 'package:flame/src/events/flame_game_mixins/multi_tap_dispatcher.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:flame_test/flame_test.dart';
import 'package:flutter/material.dart';
Expand All @@ -8,12 +15,19 @@ import 'package:mocktail/mocktail.dart';

import 'helpers/mocks.dart';

class _TestBodyComponent extends BodyComponent {
class _TestBodyComponent extends BodyComponent with TapCallbacks {
int tapCount = 0;

@override
Body createBody() => body;

@override
void noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);

@override
void onTapDown(TapDownEvent _) {
tapCount++;
}
}

class _MockCanvas extends Mock implements Canvas {}
Expand Down Expand Up @@ -350,6 +364,7 @@ void main() {
},
);
});

group('createBody', () {
test('should throw an error if bodyDef is null', () {
final bodyComponent = BodyComponent();
Expand Down Expand Up @@ -399,5 +414,72 @@ void main() {
);
});
});

group('containsLocalPoint', () {
testWithGame('with rotation', Forge2DGame.new, (game) async {
game.camera.viewfinder.anchor = Anchor.topLeft;
final zoom = game.camera.viewfinder.zoom;
final position = Vector2.all(10);
final body = game.world.createBody(
BodyDef(position: position, angle: pi / 2),
);

body.createFixtureFromShape(
CircleShape()
..radius = 1
..position.setFrom(Vector2(3, 0)),
);
body.createFixtureFromShape(
CircleShape()
..radius = 1
..position.setFrom(Vector2(-3, 0)),
);
final component = _TestBodyComponent()..body = body;

await game.world.ensureAdd(component);
game.update(0);
final tapDispatcher = game.firstChild<MultiTapDispatcher>()!;

tapDispatcher.handleTapDown(
1,
TapDownDetails(
globalPosition: position.toOffset() * zoom + Offset(0, 3 * zoom),
),
);
expect(component.tapCount, 1);

tapDispatcher.handleTapDown(
1,
TapDownDetails(
globalPosition: position.toOffset() * zoom + Offset(3 * zoom, 0),
),
);
expect(component.tapCount, 1);

tapDispatcher.handleTapDown(
1,
TapDownDetails(
globalPosition: position.toOffset() * zoom + Offset(0, -3 * zoom),
),
);
expect(component.tapCount, 2);

tapDispatcher.handleTapDown(
1,
TapDownDetails(
globalPosition: position.toOffset() * zoom + Offset(-3 * zoom, 0),
),
);
expect(component.tapCount, 2);

tapDispatcher.handleTapDown(
1,
TapDownDetails(
globalPosition: position.toOffset() * zoom,
),
);
expect(component.tapCount, 2);
});
});
});
}

0 comments on commit 7c3038b

Please sign in to comment.