mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 11:43:19 +08:00
Refactoring new API to use mixins
This commit is contained in:
committed by
Erick (CptBlackPixel)
parent
50fcc2c696
commit
a2336b926d
@ -1,12 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flame/game.dart';
|
import 'package:flame/game.dart';
|
||||||
|
import 'package:flame/gestures.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
final game = MyGame();
|
final game = MyGame();
|
||||||
runApp(game.widget);
|
runApp(game.widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyGame extends Game {
|
class MyGame extends Game with TapDetector, DoubleTapDetector, PanDetector {
|
||||||
final _whitePaint = Paint()..color = const Color(0xFFFFFFFF);
|
final _whitePaint = Paint()..color = const Color(0xFFFFFFFF);
|
||||||
final _bluePaint = Paint()..color = const Color(0xFF0000FF);
|
final _bluePaint = Paint()..color = const Color(0xFF0000FF);
|
||||||
final _greenPaint = Paint()..color = const Color(0xFF00FF00);
|
final _greenPaint = Paint()..color = const Color(0xFF00FF00);
|
||||||
@ -23,18 +24,10 @@ class MyGame extends Game {
|
|||||||
void onTap() {
|
void onTap() {
|
||||||
_paint = _paint == _whitePaint ? _bluePaint : _whitePaint;
|
_paint = _paint == _whitePaint ? _bluePaint : _whitePaint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
bool useDoubleTapDetectors() => true;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onDoubleTap() {
|
void onDoubleTap() {
|
||||||
_paint = _greenPaint;
|
_paint = _greenPaint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
bool usePanDetectors() => true;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onPanUpdate(DragUpdateDetails details) {
|
void onPanUpdate(DragUpdateDetails details) {
|
||||||
_rect = _rect.translate(details.delta.dx, details.delta.dy);
|
_rect = _rect.translate(details.delta.dx, details.delta.dy);
|
||||||
|
|||||||
215
lib/game.dart
215
lib/game.dart
@ -13,65 +13,13 @@ import 'components/component.dart';
|
|||||||
import 'components/mixins/has_game_ref.dart';
|
import 'components/mixins/has_game_ref.dart';
|
||||||
import 'components/mixins/tapable.dart';
|
import 'components/mixins/tapable.dart';
|
||||||
import 'position.dart';
|
import 'position.dart';
|
||||||
|
import 'gestures.dart';
|
||||||
|
|
||||||
/// Represents a generic game.
|
/// Represents a generic game.
|
||||||
///
|
///
|
||||||
/// Subclass this to implement the [update] and [render] methods.
|
/// Subclass this to implement the [update] and [render] methods.
|
||||||
/// Flame will deal with calling these methods properly when the game's widget is rendered.
|
/// Flame will deal with calling these methods properly when the game's widget is rendered.
|
||||||
abstract class Game {
|
abstract class Game {
|
||||||
bool useTapDetectors() => true;
|
|
||||||
void onTap() {}
|
|
||||||
void onTapCancel() {}
|
|
||||||
void onTapDown(TapDownDetails details) {}
|
|
||||||
void onTapUp(TapUpDetails details) {}
|
|
||||||
|
|
||||||
bool useSecondaryTapDetectors() => false;
|
|
||||||
void onSecondaryTapDown(TapDownDetails details) {}
|
|
||||||
void onSecondaryTapUp(TapUpDetails details) {}
|
|
||||||
void onSecondaryTapCancel() {}
|
|
||||||
|
|
||||||
bool useDoubleTapDetectors() => false;
|
|
||||||
void onDoubleTap() {}
|
|
||||||
|
|
||||||
bool useLongPressDetectors() => false;
|
|
||||||
void onLongPress() {}
|
|
||||||
void onLongPressStart(LongPressStartDetails details) {}
|
|
||||||
void onLongPressMoveUpdate(LongPressMoveUpdateDetails details) {}
|
|
||||||
void onLongPressUp() {}
|
|
||||||
void onLongPressEnd(LongPressEndDetails details) {}
|
|
||||||
|
|
||||||
bool useVerticalDragDetectors() => false;
|
|
||||||
void onVerticalDragDown(DragDownDetails details) {}
|
|
||||||
void onVerticalDragStart(DragStartDetails details) {}
|
|
||||||
void onVerticalDragUpdate(DragUpdateDetails details) {}
|
|
||||||
void onVerticalDragEnd(DragEndDetails details) {}
|
|
||||||
void onVerticalDragCancel() {}
|
|
||||||
|
|
||||||
bool useHorizontalDragDetectors() => false;
|
|
||||||
void onHorizontalDragDown(DragDownDetails details) {}
|
|
||||||
void onHorizontalDragStart(DragStartDetails details) {}
|
|
||||||
void onHorizontalDragUpdate(DragUpdateDetails details) {}
|
|
||||||
void onHorizontalDragEnd(DragEndDetails details) {}
|
|
||||||
void onHorizontalDragCancel() {}
|
|
||||||
|
|
||||||
bool useForcePressDetectors() => false;
|
|
||||||
void onForcePressStart(ForcePressDetails details) {}
|
|
||||||
void onForcePressPeak(ForcePressDetails details) {}
|
|
||||||
void onForcePressUpdate(ForcePressDetails details) {}
|
|
||||||
void onForcePressEnd(ForcePressDetails details) {}
|
|
||||||
|
|
||||||
bool usePanDetectors() => false;
|
|
||||||
void onPanDown(DragDownDetails details) {}
|
|
||||||
void onPanStart(DragStartDetails details) {}
|
|
||||||
void onPanUpdate(DragUpdateDetails details) {}
|
|
||||||
void onPanEnd(DragEndDetails details) {}
|
|
||||||
void onPanCancel() {}
|
|
||||||
|
|
||||||
bool useScaleDetectors() => false;
|
|
||||||
void onScaleStart(ScaleStartDetails details) {}
|
|
||||||
void onScaleUpdate(ScaleUpdateDetails details) {}
|
|
||||||
void onScaleEnd(ScaleEndDetails details) {}
|
|
||||||
|
|
||||||
// Widget Builder for this Game
|
// Widget Builder for this Game
|
||||||
final builder = WidgetBuilder();
|
final builder = WidgetBuilder();
|
||||||
|
|
||||||
@ -114,61 +62,142 @@ class WidgetBuilder {
|
|||||||
Widget build(Game game) {
|
Widget build(Game game) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
// Taps
|
// Taps
|
||||||
onTap: !game.useTapDetectors() ? null : () => game.onTap(),
|
onTap: game is TapDetector ? () => (game as TapDetector).onTap() : null,
|
||||||
onTapCancel: !game.useTapDetectors() ? null : () => game.onTapCancel(),
|
onTapCancel: game is TapDetector
|
||||||
onTapDown: !game.useTapDetectors() ? null : (TapDownDetails d) => game.onTapDown(d),
|
? () => (game as TapDetector).onTapCancel()
|
||||||
onTapUp: !game.useTapDetectors() ? null : (TapUpDetails d) => game.onTapUp(d),
|
: null,
|
||||||
|
onTapDown: game is TapDetector
|
||||||
|
? (TapDownDetails d) => (game as TapDetector).onTapDown(d)
|
||||||
|
: null,
|
||||||
|
onTapUp: game is TapDetector
|
||||||
|
? (TapUpDetails d) => (game as TapDetector).onTapUp(d)
|
||||||
|
: null,
|
||||||
|
|
||||||
// Secondary taps
|
// Secondary taps
|
||||||
onSecondaryTapDown: !game.useSecondaryTapDetectors() ? null : (TapDownDetails d) => game.onSecondaryTapDown(d),
|
onSecondaryTapDown: game is SecondaryTapDetector
|
||||||
onSecondaryTapUp: !game.useSecondaryTapDetectors() ? null : (TapUpDetails d) => game.onSecondaryTapUp(d),
|
? (TapDownDetails d) =>
|
||||||
onSecondaryTapCancel: !game.useSecondaryTapDetectors() ? null : () => game.onSecondaryTapCancel(),
|
(game as SecondaryTapDetector).onSecondaryTapDown(d)
|
||||||
|
: null,
|
||||||
|
onSecondaryTapUp: game is SecondaryTapDetector
|
||||||
|
? (TapUpDetails d) =>
|
||||||
|
(game as SecondaryTapDetector).onSecondaryTapUp(d)
|
||||||
|
: null,
|
||||||
|
onSecondaryTapCancel: game is SecondaryTapDetector
|
||||||
|
? () => (game as SecondaryTapDetector).onSecondaryTapCancel()
|
||||||
|
: null,
|
||||||
|
|
||||||
// Double tap
|
// Double tap
|
||||||
onDoubleTap: !game.useDoubleTapDetectors() ? null : () => game.onDoubleTap(),
|
onDoubleTap: game is DoubleTapDetector
|
||||||
|
? () => (game as DoubleTapDetector).onDoubleTap()
|
||||||
|
: null,
|
||||||
|
|
||||||
// Long presses
|
// Long presses
|
||||||
onLongPress: !game.useLongPressDetectors() ? null : () => game.onLongPress(),
|
onLongPress: game is LongPressDetector
|
||||||
onLongPressStart: !game.useLongPressDetectors() ? null : (LongPressStartDetails d) => game.onLongPressStart(d),
|
? () => (game as LongPressDetector).onLongPress()
|
||||||
onLongPressMoveUpdate: !game.useLongPressDetectors() ? null : (LongPressMoveUpdateDetails d) =>
|
: null,
|
||||||
game.onLongPressMoveUpdate(d),
|
onLongPressStart: game is LongPressDetector
|
||||||
onLongPressUp: !game.useLongPressDetectors() ? null : () => game.onLongPressUp(),
|
? (LongPressStartDetails d) =>
|
||||||
onLongPressEnd: !game.useLongPressDetectors() ? null : (LongPressEndDetails d) => game.onLongPressEnd(d),
|
(game as LongPressDetector).onLongPressStart(d)
|
||||||
|
: null,
|
||||||
|
onLongPressMoveUpdate: game is LongPressDetector
|
||||||
|
? (LongPressMoveUpdateDetails d) =>
|
||||||
|
(game as LongPressDetector).onLongPressMoveUpdate(d)
|
||||||
|
: null,
|
||||||
|
onLongPressUp: game is LongPressDetector
|
||||||
|
? () => (game as LongPressDetector).onLongPressUp()
|
||||||
|
: null,
|
||||||
|
onLongPressEnd: game is LongPressDetector
|
||||||
|
? (LongPressEndDetails d) =>
|
||||||
|
(game as LongPressDetector).onLongPressEnd(d)
|
||||||
|
: null,
|
||||||
|
|
||||||
// Vertical drag
|
// Vertical drag
|
||||||
onVerticalDragDown: !game.useVerticalDragDetectors() ? null : (DragDownDetails d) => game.onVerticalDragDown(d),
|
onVerticalDragDown: game is VerticalDragDetector
|
||||||
onVerticalDragStart: !game.useVerticalDragDetectors() ? null : (DragStartDetails d) => game.onVerticalDragStart(d),
|
? (DragDownDetails d) =>
|
||||||
onVerticalDragUpdate: !game.useVerticalDragDetectors() ? null : (DragUpdateDetails d) =>
|
(game as VerticalDragDetector).onVerticalDragDown(d)
|
||||||
game.onVerticalDragUpdate(d),
|
: null,
|
||||||
onVerticalDragEnd: !game.useVerticalDragDetectors() ? null : (DragEndDetails d) => game.onVerticalDragEnd(d),
|
onVerticalDragStart: game is VerticalDragDetector
|
||||||
onVerticalDragCancel: !game.useVerticalDragDetectors() ? null : () => game.onVerticalDragCancel(),
|
? (DragStartDetails d) =>
|
||||||
|
(game as VerticalDragDetector).onVerticalDragStart(d)
|
||||||
|
: null,
|
||||||
|
onVerticalDragUpdate: game is VerticalDragDetector
|
||||||
|
? (DragUpdateDetails d) =>
|
||||||
|
(game as VerticalDragDetector).onVerticalDragUpdate(d)
|
||||||
|
: null,
|
||||||
|
onVerticalDragEnd: game is VerticalDragDetector
|
||||||
|
? (DragEndDetails d) =>
|
||||||
|
(game as VerticalDragDetector).onVerticalDragEnd(d)
|
||||||
|
: null,
|
||||||
|
onVerticalDragCancel: game is VerticalDragDetector
|
||||||
|
? () => (game as VerticalDragDetector).onVerticalDragCancel()
|
||||||
|
: null,
|
||||||
|
|
||||||
// Horizontal drag
|
// Horizontal drag
|
||||||
onHorizontalDragDown: !game.useHorizontalDragDetectors() ? null : (DragDownDetails d) => game.onHorizontalDragDown(d),
|
onHorizontalDragDown: game is HorizontalDragDetector
|
||||||
onHorizontalDragStart: !game.useHorizontalDragDetectors() ? null : (DragStartDetails d) =>
|
? (DragDownDetails d) =>
|
||||||
game.onHorizontalDragStart(d),
|
(game as HorizontalDragDetector).onHorizontalDragDown(d)
|
||||||
onHorizontalDragUpdate: !game.useHorizontalDragDetectors() ? null : (DragUpdateDetails d) =>
|
: null,
|
||||||
game.onHorizontalDragUpdate(d),
|
onHorizontalDragStart: game is HorizontalDragDetector
|
||||||
onHorizontalDragEnd: !game.useHorizontalDragDetectors() ? null : (DragEndDetails d) => game.onHorizontalDragEnd(d),
|
? (DragStartDetails d) =>
|
||||||
onHorizontalDragCancel: !game.useHorizontalDragDetectors() ? null : () => game.onHorizontalDragCancel(),
|
(game as HorizontalDragDetector).onHorizontalDragStart(d)
|
||||||
|
: null,
|
||||||
|
onHorizontalDragUpdate: game is HorizontalDragDetector
|
||||||
|
? (DragUpdateDetails d) =>
|
||||||
|
(game as HorizontalDragDetector).onHorizontalDragUpdate(d)
|
||||||
|
: null,
|
||||||
|
onHorizontalDragEnd: game is HorizontalDragDetector
|
||||||
|
? (DragEndDetails d) =>
|
||||||
|
(game as HorizontalDragDetector).onHorizontalDragEnd(d)
|
||||||
|
: null,
|
||||||
|
onHorizontalDragCancel: game is HorizontalDragDetector
|
||||||
|
? () => (game as HorizontalDragDetector).onHorizontalDragCancel()
|
||||||
|
: null,
|
||||||
|
|
||||||
// Force presses
|
// Force presses
|
||||||
onForcePressStart: !game.useForcePressDetectors() ? null : (ForcePressDetails d) => game.onForcePressStart(d),
|
onForcePressStart: game is ForcePressDetector
|
||||||
onForcePressPeak: !game.useForcePressDetectors() ? null : (ForcePressDetails d) => game.onForcePressPeak(d),
|
? (ForcePressDetails d) =>
|
||||||
onForcePressUpdate: !game.useForcePressDetectors() ? null : (ForcePressDetails d) => game.onForcePressUpdate(d),
|
(game as ForcePressDetector).onForcePressStart(d)
|
||||||
onForcePressEnd: !game.useForcePressDetectors() ? null : (ForcePressDetails d) => game.onForcePressEnd(d),
|
: null,
|
||||||
|
onForcePressPeak: game is ForcePressDetector
|
||||||
|
? (ForcePressDetails d) =>
|
||||||
|
(game as ForcePressDetector).onForcePressPeak(d)
|
||||||
|
: null,
|
||||||
|
onForcePressUpdate: game is ForcePressDetector
|
||||||
|
? (ForcePressDetails d) =>
|
||||||
|
(game as ForcePressDetector).onForcePressUpdate(d)
|
||||||
|
: null,
|
||||||
|
onForcePressEnd: game is ForcePressDetector
|
||||||
|
? (ForcePressDetails d) =>
|
||||||
|
(game as ForcePressDetector).onForcePressEnd(d)
|
||||||
|
: null,
|
||||||
|
|
||||||
// Pan
|
// Pan
|
||||||
onPanDown: !game.usePanDetectors() ? null : (DragDownDetails d) => game.onPanDown(d),
|
onPanDown: game is PanDetector
|
||||||
onPanStart: !game.usePanDetectors() ? null : (DragStartDetails d) => game.onPanStart(d),
|
? (DragDownDetails d) => (game as PanDetector).onPanDown(d)
|
||||||
onPanUpdate: !game.usePanDetectors() ? null : (DragUpdateDetails d) => game.onPanUpdate(d),
|
: null,
|
||||||
onPanEnd: !game.usePanDetectors() ? null : (DragEndDetails d) => game.onPanEnd(d),
|
onPanStart: game is PanDetector
|
||||||
onPanCancel: !game.usePanDetectors() ? null : () => game.onPanCancel(),
|
? (DragStartDetails d) => (game as PanDetector).onPanStart(d)
|
||||||
|
: null,
|
||||||
|
onPanUpdate: game is PanDetector
|
||||||
|
? (DragUpdateDetails d) => (game as PanDetector).onPanUpdate(d)
|
||||||
|
: null,
|
||||||
|
onPanEnd: game is PanDetector
|
||||||
|
? (DragEndDetails d) => (game as PanDetector).onPanEnd(d)
|
||||||
|
: null,
|
||||||
|
onPanCancel: game is PanDetector
|
||||||
|
? () => (game as PanDetector).onPanCancel()
|
||||||
|
: null,
|
||||||
|
|
||||||
// Scales
|
// Scales
|
||||||
onScaleStart: !game.useScaleDetectors() ? null : (ScaleStartDetails d) => game.onScaleStart(d),
|
onScaleStart: game is ScaleDetector
|
||||||
onScaleUpdate: !game.useScaleDetectors() ? null : (ScaleUpdateDetails d) => game.onScaleUpdate(d),
|
? (ScaleStartDetails d) => (game as ScaleDetector).onScaleStart(d)
|
||||||
onScaleEnd: !game.useScaleDetectors() ? null : (ScaleEndDetails d) => game.onScaleEnd(d),
|
: null,
|
||||||
|
onScaleUpdate: game is ScaleDetector
|
||||||
|
? (ScaleUpdateDetails d) => (game as ScaleDetector).onScaleUpdate(d)
|
||||||
|
: null,
|
||||||
|
onScaleEnd: game is ScaleDetector
|
||||||
|
? (ScaleEndDetails d) => (game as ScaleDetector).onScaleEnd(d)
|
||||||
|
: null,
|
||||||
|
|
||||||
child: Container(
|
child: Container(
|
||||||
color: const Color(0xFF000000),
|
color: const Color(0xFF000000),
|
||||||
@ -184,7 +213,7 @@ class WidgetBuilder {
|
|||||||
/// It still needs to be subclasses to add your game logic, but the [update], [render] and [resize] methods have default implementations.
|
/// It still needs to be subclasses to add your game logic, but the [update], [render] and [resize] methods have default implementations.
|
||||||
/// This is the recommended structure to use for most games.
|
/// This is the recommended structure to use for most games.
|
||||||
/// It is based on the Component system.
|
/// It is based on the Component system.
|
||||||
abstract class BaseGame extends Game {
|
abstract class BaseGame extends Game with TapDetector {
|
||||||
/// The list of components to be updated and rendered by the base game.
|
/// The list of components to be updated and rendered by the base game.
|
||||||
OrderedSet<Component> components =
|
OrderedSet<Component> components =
|
||||||
OrderedSet(Comparing.on((c) => c.priority()));
|
OrderedSet(Comparing.on((c) => c.priority()));
|
||||||
|
|||||||
63
lib/gestures.dart
Normal file
63
lib/gestures.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
|
||||||
|
mixin TapDetector {
|
||||||
|
void onTap() {}
|
||||||
|
void onTapCancel() {}
|
||||||
|
void onTapDown(TapDownDetails details) {}
|
||||||
|
void onTapUp(TapUpDetails details) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin SecondaryTapDetector {
|
||||||
|
void onSecondaryTapDown(TapDownDetails details) {}
|
||||||
|
void onSecondaryTapUp(TapUpDetails details) {}
|
||||||
|
void onSecondaryTapCancel() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin DoubleTapDetector {
|
||||||
|
void onDoubleTap() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin LongPressDetector {
|
||||||
|
void onLongPress() {}
|
||||||
|
void onLongPressStart(LongPressStartDetails details) {}
|
||||||
|
void onLongPressMoveUpdate(LongPressMoveUpdateDetails details) {}
|
||||||
|
void onLongPressUp() {}
|
||||||
|
void onLongPressEnd(LongPressEndDetails details) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin VerticalDragDetector {
|
||||||
|
void onVerticalDragDown(DragDownDetails details) {}
|
||||||
|
void onVerticalDragStart(DragStartDetails details) {}
|
||||||
|
void onVerticalDragUpdate(DragUpdateDetails details) {}
|
||||||
|
void onVerticalDragEnd(DragEndDetails details) {}
|
||||||
|
void onVerticalDragCancel() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin HorizontalDragDetector {
|
||||||
|
void onHorizontalDragDown(DragDownDetails details) {}
|
||||||
|
void onHorizontalDragStart(DragStartDetails details) {}
|
||||||
|
void onHorizontalDragUpdate(DragUpdateDetails details) {}
|
||||||
|
void onHorizontalDragEnd(DragEndDetails details) {}
|
||||||
|
void onHorizontalDragCancel() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin ForcePressDetector {
|
||||||
|
void onForcePressStart(ForcePressDetails details) {}
|
||||||
|
void onForcePressPeak(ForcePressDetails details) {}
|
||||||
|
void onForcePressUpdate(ForcePressDetails details) {}
|
||||||
|
void onForcePressEnd(ForcePressDetails details) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin PanDetector {
|
||||||
|
void onPanDown(DragDownDetails details) {}
|
||||||
|
void onPanStart(DragStartDetails details) {}
|
||||||
|
void onPanUpdate(DragUpdateDetails details) {}
|
||||||
|
void onPanEnd(DragEndDetails details) {}
|
||||||
|
void onPanCancel() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin ScaleDetector {
|
||||||
|
void onScaleStart(ScaleStartDetails details) {}
|
||||||
|
void onScaleUpdate(ScaleUpdateDetails details) {}
|
||||||
|
void onScaleEnd(ScaleEndDetails details) {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user