mirror of
https://github.com/flame-engine/flame.git
synced 2025-10-30 16:36:57 +08:00
Making velocities and deltas have the game and global values (#769)
* Making velocities and deltas have the game and global values * Re adding code metircs * Re adding code metircs * Update packages/flame/lib/src/gestures/events.dart Co-authored-by: Luan Nico <luanpotter27@gmail.com> * Renaming example variable * fixing example * Linting Co-authored-by: Luan Nico <luanpotter27@gmail.com>
This commit is contained in:
@ -3,6 +3,7 @@ import 'package:flame/flame.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'stories/animations/animations.dart';
|
||||
import 'stories/camera_and_viewport/camera_and_viewport.dart';
|
||||
import 'stories/collision_detection/collision_detection.dart';
|
||||
import 'stories/components/components.dart';
|
||||
import 'stories/controls/controls.dart';
|
||||
@ -29,6 +30,7 @@ void main() async {
|
||||
addSpritesStories(dashbook);
|
||||
addRenderingStories(dashbook);
|
||||
addUtilsStories(dashbook);
|
||||
addCameraAndViewportStories(dashbook);
|
||||
addParallaxStories(dashbook);
|
||||
|
||||
await _setupWidgetsExample();
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
import 'package:dashbook/dashbook.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
import '../../commons/commons.dart';
|
||||
import 'follow_object.dart';
|
||||
import 'zoom.dart';
|
||||
|
||||
void addCameraAndViewportStories(Dashbook dashbook) {
|
||||
dashbook.storiesOf('Camera & Viewport')
|
||||
..add(
|
||||
'Follow Object',
|
||||
(context) {
|
||||
return GameWidget(
|
||||
game: CameraAndViewportGame(
|
||||
viewportResolution: Vector2(
|
||||
context.numberProperty('viewport width', 500),
|
||||
context.numberProperty('viewport height', 500),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
codeLink: baseLink('camera_and_viewport/follow_object.dart'),
|
||||
/*
|
||||
Text for instructions:
|
||||
|
||||
Move around with W, A, S, D and notice how the camera follows the white square
|
||||
The blue squares can also be clicked to show how the coordinate system respect
|
||||
The camera transformation
|
||||
*/
|
||||
)
|
||||
..add(
|
||||
'Zoom',
|
||||
(context) {
|
||||
return GameWidget(
|
||||
game: ZoomGame(
|
||||
viewportResolution: Vector2(
|
||||
context.numberProperty('viewport width', 500),
|
||||
context.numberProperty('viewport height', 500),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
codeLink: baseLink('camera_and_viewport/zoom.dart'),
|
||||
/*
|
||||
Text for instructions:
|
||||
|
||||
On web: use scroll to zoom in and out
|
||||
On mobile: use scale gesture to zoom in and out
|
||||
*/
|
||||
);
|
||||
}
|
||||
@ -118,9 +118,15 @@ class CameraAndViewportGame extends BaseGame
|
||||
with KeyboardEvents, HasCollidables, HasTapableComponents {
|
||||
late MovableSquare square;
|
||||
|
||||
final Vector2 viewportResolution;
|
||||
|
||||
CameraAndViewportGame({
|
||||
required this.viewportResolution,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
viewport = FixedResolutionViewport(Vector2(500, 500));
|
||||
viewport = FixedResolutionViewport(viewportResolution);
|
||||
add(Map());
|
||||
|
||||
add(square = MovableSquare());
|
||||
47
examples/lib/stories/camera_and_viewport/zoom.dart
Normal file
47
examples/lib/stories/camera_and_viewport/zoom.dart
Normal file
@ -0,0 +1,47 @@
|
||||
import 'package:flame/components.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/gestures.dart';
|
||||
|
||||
class ZoomGame extends BaseGame with ScrollDetector, ScaleDetector {
|
||||
final Vector2 viewportResolution;
|
||||
late SpriteComponent flame;
|
||||
|
||||
Vector2? lastScale;
|
||||
|
||||
ZoomGame({
|
||||
required this.viewportResolution,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<void> onLoad() async {
|
||||
final flameSprite = await loadSprite('flame.png');
|
||||
|
||||
viewport = FixedResolutionViewport(viewportResolution);
|
||||
|
||||
final flameSize = Vector2(149, 211);
|
||||
add(
|
||||
flame = SpriteComponent(
|
||||
sprite: flameSprite,
|
||||
size: flameSize,
|
||||
)..anchor = Anchor.center,
|
||||
);
|
||||
camera.followComponent(flame);
|
||||
}
|
||||
|
||||
static const zoomPerScrollUnit = 0.001;
|
||||
@override
|
||||
void onScroll(PointerScrollInfo event) {
|
||||
camera.zoom += event.scrollDelta.game.y * zoomPerScrollUnit;
|
||||
}
|
||||
|
||||
@override
|
||||
void onScaleUpdate(ScaleUpdateInfo info) {
|
||||
final scale = lastScale;
|
||||
if (scale != null) {
|
||||
final delta = info.scale.game - scale;
|
||||
camera.zoom += delta.y;
|
||||
}
|
||||
|
||||
lastScale = info.scale.game;
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ class ScrollGame extends BaseGame with ScrollDetector {
|
||||
|
||||
@override
|
||||
void onScroll(PointerScrollInfo event) {
|
||||
target = position + event.scrollDelta * 5;
|
||||
target = position + event.scrollDelta.game * 5;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -2,7 +2,6 @@ import 'package:dashbook/dashbook.dart';
|
||||
import 'package:flame/game.dart';
|
||||
|
||||
import '../../commons/commons.dart';
|
||||
import 'camera_and_viewport.dart';
|
||||
import 'nine_tile_box.dart';
|
||||
import 'particles.dart';
|
||||
import 'timer.dart';
|
||||
@ -29,10 +28,5 @@ void addUtilsStories(Dashbook dashbook) {
|
||||
'Particles',
|
||||
(_) => GameWidget(game: ParticlesGame()),
|
||||
codeLink: baseLink('utils/particles.dart'),
|
||||
)
|
||||
..add(
|
||||
'Camera & Viewport',
|
||||
(_) => GameWidget(game: CameraAndViewportGame()),
|
||||
codeLink: baseLink('utils/camera_and_viewport.dart'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -26,6 +26,23 @@ class EventPosition {
|
||||
EventPosition(this._game, this._localPosition, this._globalPosition);
|
||||
}
|
||||
|
||||
/// [EventDelta] converts deltas based events to two different values (game and global).
|
||||
///
|
||||
/// [global]: this is the raw value received by the event without any scale applied to it; this is always the same as local because Flutter doesn't apply any scaling.
|
||||
/// [game]: the scalled value applied all the game transformations.
|
||||
class EventDelta {
|
||||
final Game _game;
|
||||
final Offset _delta;
|
||||
|
||||
/// Scaled value relative to the game transformations
|
||||
late final Vector2 game = _game.scaleVector(_delta.toVector2());
|
||||
|
||||
/// Raw value relative to the game transformations
|
||||
late final Vector2 global = _delta.toVector2();
|
||||
|
||||
EventDelta(this._game, this._delta);
|
||||
}
|
||||
|
||||
/// BaseInfo is the base class for Flame's input events.
|
||||
/// This base class just wraps Flutter's [raw] attribute.
|
||||
abstract class BaseInfo<T> {
|
||||
@ -104,8 +121,7 @@ class ForcePressInfo extends PositionInfo<ForcePressDetails> {
|
||||
}
|
||||
|
||||
class PointerScrollInfo extends PositionInfo<PointerScrollEvent> {
|
||||
late final Vector2 scrollDelta =
|
||||
_game.unscaleVector(raw.scrollDelta.toVector2());
|
||||
late final EventDelta scrollDelta = EventDelta(_game, raw.scrollDelta);
|
||||
|
||||
PointerScrollInfo.fromDetails(
|
||||
Game game,
|
||||
@ -135,7 +151,7 @@ class DragStartInfo extends PositionInfo<DragStartDetails> {
|
||||
}
|
||||
|
||||
class DragUpdateInfo extends PositionInfo<DragUpdateDetails> {
|
||||
late final Vector2 delta = _game.unscaleVector(raw.delta.toVector2());
|
||||
late final EventDelta delta = EventDelta(_game, raw.delta);
|
||||
|
||||
DragUpdateInfo.fromDetails(
|
||||
Game game,
|
||||
@ -166,8 +182,9 @@ class ScaleStartInfo extends PositionInfo<ScaleStartDetails> {
|
||||
|
||||
class ScaleEndInfo extends BaseInfo<ScaleEndDetails> {
|
||||
final Game _game;
|
||||
late final Vector2 velocity =
|
||||
_game.unscaleVector(raw.velocity.pixelsPerSecond.toVector2());
|
||||
late final EventDelta velocity =
|
||||
EventDelta(_game, raw.velocity.pixelsPerSecond);
|
||||
|
||||
int get pointerCount => raw.pointerCount;
|
||||
|
||||
ScaleEndInfo.fromDetails(
|
||||
@ -179,8 +196,10 @@ class ScaleEndInfo extends BaseInfo<ScaleEndDetails> {
|
||||
class ScaleUpdateInfo extends PositionInfo<ScaleUpdateDetails> {
|
||||
int get pointerCount => raw.pointerCount;
|
||||
double get rotation => raw.rotation;
|
||||
late final Vector2 scale =
|
||||
_game.unscaleVector(Vector2(raw.horizontalScale, raw.verticalScale));
|
||||
late final EventDelta scale = EventDelta(
|
||||
_game,
|
||||
Offset(raw.horizontalScale, raw.verticalScale),
|
||||
);
|
||||
|
||||
ScaleUpdateInfo.fromDetails(
|
||||
Game game,
|
||||
|
||||
Reference in New Issue
Block a user