mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-01 10:38:17 +08:00
fix: The visibleGameSize should be based on viewport.virtualSize (#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`.
This commit is contained in:
@ -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()
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user