Skip to content

Commit

Permalink
fix: The visibleGameSize should be based on viewport.virtualSize (#…
Browse files Browse the repository at this point in the history
…2945)

The `visibleGameSize` should be based on the virtual size of the
viewport, otherwise it won't work for `FixedResolutionViewport` for
example.
We noticed this when using the `ScreenHitbox` in a world that was looked
upon by a camera with a `FixedResolutionViewport`.
  • Loading branch information
spydon committed Dec 21, 2023
1 parent 093a702 commit bd130b7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
34 changes: 17 additions & 17 deletions examples/lib/stories/collision_detection/circles_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,41 @@ import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter/material.dart' hide Image, Draggable;

class CirclesExample extends FlameGame with HasCollisionDetection, TapDetector {
class CirclesExample extends FlameGame {
static const description = '''
This example will create a circle every time you tap on the screen. It will
have the initial velocity towards the center of the screen and if it touches
another circle both of them will change color.
''';

@override
Future<void> onLoad() async {
add(ScreenHitbox());
}
CirclesExample()
: super(
camera: CameraComponent.withFixedResolution(width: 600, height: 400),
world: MyWorld(),
);
}

class MyWorld extends World with TapCallbacks, HasCollisionDetection {
MyWorld() : super(children: [ScreenHitbox()..debugMode = true]);

@override
void onTapDown(TapDownInfo info) {
add(MyCollidable(info.eventPosition.widget));
void onTapDown(TapDownEvent info) {
add(MyCollidable(position: info.localPosition));
}
}

class MyCollidable extends PositionComponent
with HasGameReference<CirclesExample>, CollisionCallbacks {
MyCollidable({super.position})
: super(size: Vector2.all(30), anchor: Anchor.center);

late Vector2 velocity;
final _collisionColor = Colors.amber;
final _defaultColor = Colors.cyan;
late ShapeHitbox hitbox;

MyCollidable(Vector2 position)
: super(
position: position,
size: Vector2.all(100),
anchor: Anchor.center,
);

@override
Future<void> onLoad() async {
final defaultPaint = Paint()
Expand All @@ -46,8 +46,8 @@ class MyCollidable extends PositionComponent
..paint = defaultPaint
..renderShape = true;
add(hitbox);
final center = game.size / 2;
velocity = (center - position)..scaleTo(150);
velocity = -position
..scaleTo(50);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion packages/flame/lib/src/camera/viewfinder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class Viewfinder extends Component
Rect? visibleRect;
@protected
Rect computeVisibleRect() {
final viewportSize = camera.viewport.size;
final viewportSize = camera.viewport.virtualSize;
final currentTransform = transform;
currentTransform.globalToLocal(_zeroVector, output: _topLeft);
currentTransform.globalToLocal(viewportSize, output: _bottomRight);
Expand Down
36 changes: 36 additions & 0 deletions packages/flame/test/collisions/screen_hibox_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,41 @@ void main() {
expect(testBlock.endCounter, 0);
},
});

runCollisionTestRegistry({
'collides with FixedResolutionViewport': (hasCollisionDetection) async {
final game = hasCollisionDetection as FlameGame;
game.camera = CameraComponent.withFixedResolution(
width: 100,
height: 100,
);
final testBlock = TestBlock(
Vector2.all(-50),
Vector2.all(2),
)..anchor = Anchor.center;
final screenHitbox = ScreenHitbox();
await game.world.addAll([screenHitbox, testBlock]);
await game.ready();
game.update(0);

expect(testBlock.startCounter, 1);
expect(testBlock.onCollisionCounter, 1);
expect(testBlock.endCounter, 0);

testBlock.position = Vector2.all(50);
game.update(0);

expect(testBlock.startCounter, 1);
expect(testBlock.onCollisionCounter, 2);
expect(testBlock.endCounter, 0);

testBlock.position = Vector2.all(0);
game.update(0);

expect(testBlock.startCounter, 1);
expect(testBlock.onCollisionCounter, 2);
expect(testBlock.endCounter, 1);
},
});
});
}

0 comments on commit bd130b7

Please sign in to comment.