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:
Erick
2021-04-25 14:54:04 -03:00
committed by GitHub
parent ccefeed1be
commit 91864d0b88
7 changed files with 134 additions and 15 deletions

View File

@ -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();

View File

@ -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
*/
);
}

View File

@ -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());

View 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;
}
}

View File

@ -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

View File

@ -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'),
);
}

View File

@ -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,