Line data Source code
1 : import 'package:flutter/gestures.dart';
2 :
3 : import '../../extensions.dart';
4 : import '../game/game.dart';
5 :
6 : /// [EventPosition] converts position based events to three different coordinate systems (global, local and game).
7 : ///
8 : /// global: coordinate system relative to the entire app; same as `globalPosition` in Flutter
9 : /// widget: coordinate system relative to the GameWidget widget; same as `localPosition` in Flutter
10 : /// game: same as `widget` but also applies any transformations from the camera or viewport to the coordinate system
11 : class EventPosition {
12 : final Game _game;
13 : final Offset _globalPosition;
14 :
15 : /// Coordinates of the event relative to the whole screen
16 12 : late final Vector2 global = _globalPosition.toVector2();
17 :
18 : /// Coordinates of the event relative to the game widget position/size
19 16 : late final Vector2 widget = _game.convertGlobalToLocalCoordinate(global);
20 :
21 : /// Coordinates of the event relative to the game position/size and transformations
22 16 : late final Vector2 game = _game.unprojectVector(widget);
23 :
24 4 : EventPosition(this._game, this._globalPosition);
25 : }
26 :
27 : /// [EventDelta] converts deltas based events to two different values (game and global).
28 : ///
29 : /// [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.
30 : /// [game]: the scalled value applied all the game transformations.
31 : class EventDelta {
32 : final Game _game;
33 : final Offset _delta;
34 :
35 : /// Raw value relative to the game transformations
36 : late final Vector2 global = _delta.toVector2();
37 :
38 : /// Scaled value relative to the game transformations
39 : late final Vector2 game = _game.unscaleVector(global);
40 :
41 0 : EventDelta(this._game, this._delta);
42 : }
43 :
44 : /// BaseInfo is the base class for Flame's input events.
45 : /// This base class just wraps Flutter's [raw] attribute.
46 : abstract class BaseInfo<T> {
47 : final T raw;
48 :
49 4 : BaseInfo(this.raw);
50 : }
51 :
52 : /// A more specialized wrapper of Flame's base class for input events.
53 : /// It adds the [eventPosition] field and is used by all position based
54 : /// events on Flame.
55 : abstract class PositionInfo<T> extends BaseInfo<T> {
56 : final Game _game;
57 : final Offset _globalPosition;
58 :
59 16 : late final eventPosition = EventPosition(_game, _globalPosition);
60 :
61 4 : PositionInfo(
62 : this._game,
63 : this._globalPosition,
64 : T raw,
65 4 : ) : super(raw);
66 : }
67 :
68 : class TapDownInfo extends PositionInfo<TapDownDetails> {
69 2 : TapDownInfo.fromDetails(
70 : Game game,
71 : TapDownDetails raw,
72 4 : ) : super(game, raw.globalPosition, raw);
73 : }
74 :
75 : class TapUpInfo extends PositionInfo<TapUpDetails> {
76 0 : TapUpInfo.fromDetails(
77 : Game game,
78 : TapUpDetails raw,
79 0 : ) : super(game, raw.globalPosition, raw);
80 : }
81 :
82 : class LongPressStartInfo extends PositionInfo<LongPressStartDetails> {
83 0 : LongPressStartInfo.fromDetails(
84 : Game game,
85 : LongPressStartDetails raw,
86 0 : ) : super(game, raw.globalPosition, raw);
87 : }
88 :
89 : class LongPressEndInfo extends PositionInfo<LongPressEndDetails> {
90 : late final Vector2 velocity =
91 : _game.unscaleVector(raw.velocity.pixelsPerSecond.toVector2());
92 :
93 0 : LongPressEndInfo.fromDetails(
94 : Game game,
95 : LongPressEndDetails raw,
96 0 : ) : super(game, raw.globalPosition, raw);
97 : }
98 :
99 : class LongPressMoveUpdateInfo extends PositionInfo<LongPressMoveUpdateDetails> {
100 0 : LongPressMoveUpdateInfo.fromDetails(
101 : Game game,
102 : LongPressMoveUpdateDetails raw,
103 0 : ) : super(game, raw.globalPosition, raw);
104 : }
105 :
106 : class ForcePressInfo extends PositionInfo<ForcePressDetails> {
107 : late final double pressure = raw.pressure;
108 :
109 0 : ForcePressInfo.fromDetails(
110 : Game game,
111 : ForcePressDetails raw,
112 0 : ) : super(game, raw.globalPosition, raw);
113 : }
114 :
115 : class PointerScrollInfo extends PositionInfo<PointerScrollEvent> {
116 : late final EventDelta scrollDelta = EventDelta(_game, raw.scrollDelta);
117 :
118 0 : PointerScrollInfo.fromDetails(
119 : Game game,
120 : PointerScrollEvent raw,
121 0 : ) : super(game, raw.position, raw);
122 : }
123 :
124 : class PointerHoverInfo extends PositionInfo<PointerHoverEvent> {
125 1 : PointerHoverInfo.fromDetails(
126 : Game game,
127 : PointerHoverEvent raw,
128 2 : ) : super(game, raw.position, raw);
129 : }
130 :
131 : class DragDownInfo extends PositionInfo<DragDownDetails> {
132 0 : DragDownInfo.fromDetails(
133 : Game game,
134 : DragDownDetails raw,
135 0 : ) : super(game, raw.globalPosition, raw);
136 : }
137 :
138 : class DragStartInfo extends PositionInfo<DragStartDetails> {
139 1 : DragStartInfo.fromDetails(
140 : Game game,
141 : DragStartDetails raw,
142 2 : ) : super(game, raw.globalPosition, raw);
143 : }
144 :
145 : class DragUpdateInfo extends PositionInfo<DragUpdateDetails> {
146 : late final EventDelta delta = EventDelta(_game, raw.delta);
147 :
148 0 : DragUpdateInfo.fromDetails(
149 : Game game,
150 : DragUpdateDetails raw,
151 0 : ) : super(game, raw.globalPosition, raw);
152 : }
153 :
154 : class DragEndInfo extends BaseInfo<DragEndDetails> {
155 : final Game _game;
156 : late final Vector2 velocity =
157 : _game.unscaleVector(raw.velocity.pixelsPerSecond.toVector2());
158 0 : double? get primaryVelocity => raw.primaryVelocity;
159 :
160 1 : DragEndInfo.fromDetails(
161 : this._game,
162 : DragEndDetails raw,
163 1 : ) : super(raw);
164 : }
165 :
166 : class ScaleStartInfo extends PositionInfo<ScaleStartDetails> {
167 0 : int get pointerCount => raw.pointerCount;
168 :
169 0 : ScaleStartInfo.fromDetails(
170 : Game game,
171 : ScaleStartDetails raw,
172 0 : ) : super(game, raw.focalPoint, raw);
173 : }
174 :
175 : class ScaleEndInfo extends BaseInfo<ScaleEndDetails> {
176 : final Game _game;
177 : late final EventDelta velocity = EventDelta(
178 : _game,
179 : raw.velocity.pixelsPerSecond,
180 : );
181 :
182 0 : int get pointerCount => raw.pointerCount;
183 :
184 0 : ScaleEndInfo.fromDetails(
185 : this._game,
186 : ScaleEndDetails raw,
187 0 : ) : super(raw);
188 : }
189 :
190 : class ScaleUpdateInfo extends PositionInfo<ScaleUpdateDetails> {
191 0 : int get pointerCount => raw.pointerCount;
192 0 : double get rotation => raw.rotation;
193 : late final EventDelta scale = EventDelta(
194 : _game,
195 : Offset(raw.horizontalScale, raw.verticalScale),
196 : );
197 :
198 0 : ScaleUpdateInfo.fromDetails(
199 : Game game,
200 : ScaleUpdateDetails raw,
201 0 : ) : super(game, raw.focalPoint, raw);
202 : }
|