mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-18 05:38:39 +08:00
Merge branch 'develop' into develop
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
## [next]
|
## [next]
|
||||||
|
|
||||||
|
## 0.17.0
|
||||||
- Fixing FlareAnimation API to match convention
|
- Fixing FlareAnimation API to match convention
|
||||||
- Fixing FlareComponent renderization
|
- Fixing FlareComponent renderization
|
||||||
- Added default render fucntion for Box2D ChainShape
|
- Added default render fucntion for Box2D ChainShape
|
||||||
|
- New GestureDetector API to Game
|
||||||
|
|
||||||
## 0.16.1
|
## 0.16.1
|
||||||
- Added `Bgm` class for easy looping background music management.
|
- Added `Bgm` class for easy looping background music management.
|
||||||
|
|||||||
6
FAQ.md
6
FAQ.md
@@ -52,6 +52,12 @@ If you are using `BaseGame`, you have a `camera` attribute that allows you to of
|
|||||||
|
|
||||||
For a more in-depth tutorial on how the camera works (in general & in Flame) and how to use it, check [erickzanardo](https://github.com/erickzanardo)'s [excellent tutorial](https://fireslime.xyz/articles/20190911_Basic_Camera_Usage_In_Flame.html), published via FireSlime.
|
For a more in-depth tutorial on how the camera works (in general & in Flame) and how to use it, check [erickzanardo](https://github.com/erickzanardo)'s [excellent tutorial](https://fireslime.xyz/articles/20190911_Basic_Camera_Usage_In_Flame.html), published via FireSlime.
|
||||||
|
|
||||||
|
## How to handle touch events on your game?
|
||||||
|
|
||||||
|
You can always use all the Widgets and features that Flutter already provide for that, but Flame wraps gesture detector callbacks on its base Game class so it can ben a little easier to handle those events, you can find more about it on the input documentation page:
|
||||||
|
|
||||||
|
https://flame-engine.org/docs/input.md
|
||||||
|
|
||||||
## Other questions?
|
## Other questions?
|
||||||
|
|
||||||
Didn't find what you needed here? Please head to [FireSlime's Discord channel](https://discord.gg/pxrBmy4) where the community might help you with more questions.
|
Didn't find what you needed here? Please head to [FireSlime's Discord channel](https://discord.gg/pxrBmy4) where the community might help you with more questions.
|
||||||
|
|||||||
27
README.md
27
README.md
@@ -63,7 +63,7 @@ Just drop it in your `pubspec.yaml`:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
dependencies:
|
dependencies:
|
||||||
flame: ^0.16.1
|
flame: ^0.17.0
|
||||||
```
|
```
|
||||||
|
|
||||||
And start using it!
|
And start using it!
|
||||||
@@ -263,21 +263,26 @@ A very simple `BaseGame` implementation example can be seen below:
|
|||||||
|
|
||||||
### Input
|
### Input
|
||||||
|
|
||||||
In order to handle user input, you can use the libraries provided by Flutter for regular apps: [Gesture Recognizers](https://flutter.io/gestures/).
|
Inside `package:flame/gestures.dart` you can find a whole set of `mixin` which can be included on your game class instance to be able to receive touch input events
|
||||||
|
|
||||||
However, in order to bind them, use the `Flame.util.addGestureRecognizer` method; in doing so, you'll make sure they are properly unbound when the game widget is not being rendered, and so the rest of your screens will work appropriately.
|
__Example__
|
||||||
|
|
||||||
For example, to add a tap listener ("on click"):
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
Flame.util.addGestureRecognizer(new TapGestureRecognizer()
|
class MyGame extends Game with TapDetector {
|
||||||
..onTapDown = (TapDownDetails evt) => game.handleInput(evt.globalPosition.dx, evt.globalPosition.dy));
|
// Other methods ommited
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapDown(TapDownDetails details) {
|
||||||
|
print("Player tap down on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTapUp(TapUpDetails details) {
|
||||||
|
print("Player tap up on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `game` is a reference to your game object and `handleInput` is a method you create to handle the input inside your game.
|
|
||||||
|
|
||||||
If your game doesn't have other screens, just call this after your `runApp` call, in the `main` method.
|
|
||||||
|
|
||||||
[Complete Input Guide](doc/input.md)
|
[Complete Input Guide](doc/input.md)
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Put the pub package as your dependency by dropping the following in your `pubspe
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
dependencies:
|
dependencies:
|
||||||
flame: ^0.16.1
|
flame: ^0.17.0
|
||||||
```
|
```
|
||||||
|
|
||||||
And start using it!
|
And start using it!
|
||||||
|
|||||||
72
doc/examples/gestures/.gitignore
vendored
Normal file
72
doc/examples/gestures/.gitignore
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Android related
|
||||||
|
**/android/**/gradle-wrapper.jar
|
||||||
|
**/android/.gradle
|
||||||
|
**/android/captures/
|
||||||
|
**/android/gradlew
|
||||||
|
**/android/gradlew.bat
|
||||||
|
**/android/local.properties
|
||||||
|
**/android/**/GeneratedPluginRegistrant.java
|
||||||
|
|
||||||
|
# iOS/XCode related
|
||||||
|
**/ios/**/*.mode1v3
|
||||||
|
**/ios/**/*.mode2v3
|
||||||
|
**/ios/**/*.moved-aside
|
||||||
|
**/ios/**/*.pbxuser
|
||||||
|
**/ios/**/*.perspectivev3
|
||||||
|
**/ios/**/*sync/
|
||||||
|
**/ios/**/.sconsign.dblite
|
||||||
|
**/ios/**/.tags*
|
||||||
|
**/ios/**/.vagrant/
|
||||||
|
**/ios/**/DerivedData/
|
||||||
|
**/ios/**/Icon?
|
||||||
|
**/ios/**/Pods/
|
||||||
|
**/ios/**/.symlinks/
|
||||||
|
**/ios/**/profile
|
||||||
|
**/ios/**/xcuserdata
|
||||||
|
**/ios/.generated/
|
||||||
|
**/ios/Flutter/App.framework
|
||||||
|
**/ios/Flutter/Flutter.framework
|
||||||
|
**/ios/Flutter/Generated.xcconfig
|
||||||
|
**/ios/Flutter/app.flx
|
||||||
|
**/ios/Flutter/app.zip
|
||||||
|
**/ios/Flutter/flutter_assets/
|
||||||
|
**/ios/ServiceDefinitions.json
|
||||||
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# Exceptions to above rules.
|
||||||
|
!**/ios/**/default.mode1v3
|
||||||
|
!**/ios/**/default.mode2v3
|
||||||
|
!**/ios/**/default.pbxuser
|
||||||
|
!**/ios/**/default.perspectivev3
|
||||||
|
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||||
10
doc/examples/gestures/.metadata
Normal file
10
doc/examples/gestures/.metadata
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: 841707365a9be08f2219cbafc52c52d6af5355aa
|
||||||
|
channel: master
|
||||||
|
|
||||||
|
project_type: app
|
||||||
3
doc/examples/gestures/README.md
Normal file
3
doc/examples/gestures/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# gestures
|
||||||
|
|
||||||
|
A flame game showcasing the use of gestures callbacks
|
||||||
45
doc/examples/gestures/lib/main.dart
Normal file
45
doc/examples/gestures/lib/main.dart
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flame/game.dart';
|
||||||
|
import 'package:flame/gestures.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final game = MyGame();
|
||||||
|
runApp(game.widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyGame extends Game with TapDetector, DoubleTapDetector, PanDetector {
|
||||||
|
final _whitePaint = Paint()..color = const Color(0xFFFFFFFF);
|
||||||
|
final _bluePaint = Paint()..color = const Color(0xFF0000FF);
|
||||||
|
final _greenPaint = Paint()..color = const Color(0xFF00FF00);
|
||||||
|
|
||||||
|
Paint _paint;
|
||||||
|
|
||||||
|
Rect _rect = const Rect.fromLTWH(50, 50, 50, 50);
|
||||||
|
|
||||||
|
MyGame() {
|
||||||
|
_paint = _whitePaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onTap() {
|
||||||
|
_paint = _paint == _whitePaint ? _bluePaint : _whitePaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onDoubleTap() {
|
||||||
|
_paint = _greenPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onPanUpdate(DragUpdateDetails details) {
|
||||||
|
_rect = _rect.translate(details.delta.dx, details.delta.dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(double dt) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void render(Canvas canvas) {
|
||||||
|
canvas.drawRect(_rect, _paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
doc/examples/gestures/pubspec.yaml
Normal file
16
doc/examples/gestures/pubspec.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: gestures
|
||||||
|
description: A flame game showcasing the use of gestures callbacks
|
||||||
|
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.1.0 <3.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
flame:
|
||||||
|
path: ../../../
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
uses-material-design: false
|
||||||
87
doc/input.md
87
doc/input.md
@@ -1,41 +1,84 @@
|
|||||||
# Input
|
# Input
|
||||||
|
|
||||||
In order to handle user input, you can use the libraries provided by Flutter for regular apps: [Gesture Recognizers](https://flutter.io/gestures/).
|
Inside `package:flame/gestures.dart` you can find a whole set of `mixin` which can be included on your game class instance to be able to receive touch input events. Bellow you can see the full list of these `mixin`s and its methods:
|
||||||
|
|
||||||
However, in order to bind them, use the `Flame.util.addGestureRecognizer` method; in doing so, you'll make sure they are properly unbound when the game widget is not being rendered, and so the rest of your screens will work appropriately.
|
|
||||||
|
|
||||||
For example, to add a tap listener ("on click"):
|
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
Flame.util.addGestureRecognizer(new TapGestureRecognizer()
|
- TapDetector
|
||||||
..onTapDown = (TapDownDetails evt) => game.handleInput(evt.globalPosition.dx, evt.globalPosition.dy));
|
- onTap
|
||||||
|
- onTapCancel
|
||||||
|
- onTapDown
|
||||||
|
- onTapUp
|
||||||
|
|
||||||
|
- SecondaryTapDetector
|
||||||
|
- onSecondaryTapDown
|
||||||
|
- onSecondaryTapUp
|
||||||
|
- onSecondaryTapCancel
|
||||||
|
|
||||||
|
- DoubleTapDetector
|
||||||
|
- onDoubleTap
|
||||||
|
|
||||||
|
- LongPressDetector
|
||||||
|
- onLongPress
|
||||||
|
- onLongPressStart
|
||||||
|
- onLongPressMoveUpdate
|
||||||
|
- onLongPressUp
|
||||||
|
- onLongPressEnd
|
||||||
|
|
||||||
|
- VerticalDragDetector
|
||||||
|
- onVerticalDragDown
|
||||||
|
- onVerticalDragStart
|
||||||
|
- onVerticalDragUpdate
|
||||||
|
- onVerticalDragEnd
|
||||||
|
- onVerticalDragCancel
|
||||||
|
|
||||||
|
- HorizontalDragDetector
|
||||||
|
- onHorizontalDragDown
|
||||||
|
- onHorizontalDragStart
|
||||||
|
- onHorizontalDragUpdate
|
||||||
|
- onHorizontalDragEnd
|
||||||
|
- onHorizontalDragCancel
|
||||||
|
|
||||||
|
- ForcePressDetector
|
||||||
|
- onForcePressStart
|
||||||
|
- onForcePressPeak
|
||||||
|
- onForcePressUpdate
|
||||||
|
- onForcePressEnd
|
||||||
|
|
||||||
|
- PanDetector
|
||||||
|
- onPanDown
|
||||||
|
- onPanStart
|
||||||
|
- onPanUpdate
|
||||||
|
- onPanEnd
|
||||||
|
- onPanCancel
|
||||||
|
|
||||||
|
- ScaleDetector
|
||||||
|
- onScaleStart
|
||||||
|
- onScaleUpdate
|
||||||
|
- onScaleEnd
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `game` is a reference to your game object and `handleInput` is a method you create to handle the input inside your game.
|
Many of these detectors can conflict with each other, for example, you can't register both Vertical and Horizontal drags, so not all of then can be used together.
|
||||||
|
|
||||||
If your game doesn't have other screens, just call this after your `runApp` call, in the `main` method.
|
All of these methods are basically a mirror from the callbacks available on the [GestureDetector widget](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html), you can also read more about Flutter's gestures [here](https://api.flutter.dev/flutter/gestures/gestures-library.html).
|
||||||
|
|
||||||
Here are some example of more complex Gesture Recognizers:
|
## Example
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
MyGame() {
|
class MyGame extends Game with TapDetector {
|
||||||
// other init...
|
// Other methods ommited
|
||||||
|
|
||||||
Flame.util.addGestureRecognizer(createDragRecognizer());
|
@override
|
||||||
Flame.util.addGestureRecognizer(createTapRecognizer());
|
void onTapDown(TapDownDetails details) {
|
||||||
|
print("Player tap down on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
|
||||||
}
|
}
|
||||||
|
|
||||||
GestureRecognizer createDragRecognizer() {
|
@override
|
||||||
return new ImmediateMultiDragGestureRecognizer()
|
void onTapUp(TapUpDetails details) {
|
||||||
..onStart = (Offset position) => this.handleDrag(position);
|
print("Player tap up on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
|
||||||
}
|
}
|
||||||
|
|
||||||
TapGestureRecognizer createTapRecognizer() {
|
|
||||||
return new TapGestureRecognizer()
|
|
||||||
..onTapUp = (TapUpDetails details) => this.handleTap(details.globalPosition);;
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
__ATTENTION:__ `Flame.util.addGestureRecognizer` must be called after the `runApp`, otherwise Flutter's `GestureBinding` will not be initialized yet and exceptions will occur.
|
You can also check a more complete example [here](/doc/examples/gestures).
|
||||||
|
|
||||||
## Tapable components
|
## Tapable components
|
||||||
|
|
||||||
|
|||||||
26
doc/util.md
26
doc/util.md
@@ -55,11 +55,14 @@ Flame provides a simple utility class to help you handle countdowns and event li
|
|||||||
__Countdown example:__
|
__Countdown example:__
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
import 'package:flame/game.dart';
|
import 'dart:ui';
|
||||||
import 'package:flame/time.dart';
|
|
||||||
import 'package:flame/text_config.dart';
|
|
||||||
|
|
||||||
class MyGame extends MyGame {
|
import 'package:flame/game.dart';
|
||||||
|
import 'package:flame/position.dart';
|
||||||
|
import 'package:flame/text_config.dart';
|
||||||
|
import 'package:flame/time.dart';
|
||||||
|
|
||||||
|
class MyGame extends Game {
|
||||||
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
|
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
|
||||||
final countdown = Timer(2);
|
final countdown = Timer(2);
|
||||||
|
|
||||||
@@ -77,7 +80,8 @@ class MyGame extends MyGame {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void render(Canvas canvas) {
|
void render(Canvas canvas) {
|
||||||
textConfig.render(canvas, "Countdown: ${countdown.current.toString()}", Position(10, 100));
|
textConfig.render(canvas, "Countdown: ${countdown.current.toString()}",
|
||||||
|
Position(10, 100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,11 +90,14 @@ class MyGame extends MyGame {
|
|||||||
__Interval example:__
|
__Interval example:__
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
import 'package:flame/game.dart';
|
import 'dart:ui';
|
||||||
import 'package:flame/time.dart';
|
|
||||||
import 'package:flame/text_config.dart';
|
|
||||||
|
|
||||||
class MyGame extends MyGame {
|
import 'package:flame/game.dart';
|
||||||
|
import 'package:flame/position.dart';
|
||||||
|
import 'package:flame/text_config.dart';
|
||||||
|
import 'package:flame/time.dart';
|
||||||
|
|
||||||
|
class MyGame extends Game {
|
||||||
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
|
final TextConfig textConfig = TextConfig(color: const Color(0xFFFFFFFF));
|
||||||
Timer interval;
|
Timer interval;
|
||||||
|
|
||||||
@@ -105,6 +112,7 @@ class MyGame extends MyGame {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void update(double dt) {
|
void update(double dt) {
|
||||||
|
interval.update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
185
lib/game.dart
185
lib/game.dart
@@ -12,31 +12,14 @@ import 'package:ordered_set/ordered_set.dart';
|
|||||||
import 'components/component.dart';
|
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 'flame.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 {
|
||||||
TapGestureRecognizer _createTapGestureRecognizer() => TapGestureRecognizer()
|
|
||||||
..onTapUp = (TapUpDetails details) {
|
|
||||||
onTapUp(details);
|
|
||||||
}
|
|
||||||
..onTapDown = (TapDownDetails details) {
|
|
||||||
onTapDown(details);
|
|
||||||
}
|
|
||||||
..onTapCancel = () {
|
|
||||||
onTapCancel();
|
|
||||||
};
|
|
||||||
|
|
||||||
void onTapCancel() {}
|
|
||||||
void onTapDown(TapDownDetails details) {}
|
|
||||||
void onTapUp(TapUpDetails details) {}
|
|
||||||
|
|
||||||
TapGestureRecognizer _gestureRecognizer;
|
|
||||||
|
|
||||||
// Widget Builder for this Game
|
// Widget Builder for this Game
|
||||||
final builder = WidgetBuilder();
|
final builder = WidgetBuilder();
|
||||||
|
|
||||||
@@ -67,26 +50,162 @@ abstract class Game {
|
|||||||
Widget get widget => builder.build(this);
|
Widget get widget => builder.build(this);
|
||||||
|
|
||||||
// Called when the Game widget is attached
|
// Called when the Game widget is attached
|
||||||
void onAttach() {
|
void onAttach() {}
|
||||||
if (_gestureRecognizer != null) {
|
|
||||||
Flame.util.removeGestureRecognizer(_gestureRecognizer);
|
|
||||||
}
|
|
||||||
_gestureRecognizer = _createTapGestureRecognizer();
|
|
||||||
Flame.util.addGestureRecognizer(_gestureRecognizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when the Game widget is detached
|
// Called when the Game widget is detached
|
||||||
void onDetach() {
|
void onDetach() {}
|
||||||
if (_gestureRecognizer != null) {
|
|
||||||
Flame.util.removeGestureRecognizer(_gestureRecognizer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WidgetBuilder {
|
class WidgetBuilder {
|
||||||
Offset offset = Offset.zero;
|
Offset offset = Offset.zero;
|
||||||
Widget build(Game game) => Directionality(
|
|
||||||
textDirection: TextDirection.ltr, child: EmbeddedGameWidget(game));
|
Widget build(Game game) {
|
||||||
|
return GestureDetector(
|
||||||
|
// Taps
|
||||||
|
onTap: game is TapDetector ? () => (game as TapDetector).onTap() : null,
|
||||||
|
onTapCancel: game is TapDetector
|
||||||
|
? () => (game as TapDetector).onTapCancel()
|
||||||
|
: 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
|
||||||
|
onSecondaryTapDown: game is SecondaryTapDetector
|
||||||
|
? (TapDownDetails d) =>
|
||||||
|
(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
|
||||||
|
onDoubleTap: game is DoubleTapDetector
|
||||||
|
? () => (game as DoubleTapDetector).onDoubleTap()
|
||||||
|
: null,
|
||||||
|
|
||||||
|
// Long presses
|
||||||
|
onLongPress: game is LongPressDetector
|
||||||
|
? () => (game as LongPressDetector).onLongPress()
|
||||||
|
: null,
|
||||||
|
onLongPressStart: game is LongPressDetector
|
||||||
|
? (LongPressStartDetails 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
|
||||||
|
onVerticalDragDown: game is VerticalDragDetector
|
||||||
|
? (DragDownDetails d) =>
|
||||||
|
(game as VerticalDragDetector).onVerticalDragDown(d)
|
||||||
|
: null,
|
||||||
|
onVerticalDragStart: game is VerticalDragDetector
|
||||||
|
? (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
|
||||||
|
onHorizontalDragDown: game is HorizontalDragDetector
|
||||||
|
? (DragDownDetails d) =>
|
||||||
|
(game as HorizontalDragDetector).onHorizontalDragDown(d)
|
||||||
|
: null,
|
||||||
|
onHorizontalDragStart: game is HorizontalDragDetector
|
||||||
|
? (DragStartDetails d) =>
|
||||||
|
(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
|
||||||
|
onForcePressStart: game is ForcePressDetector
|
||||||
|
? (ForcePressDetails d) =>
|
||||||
|
(game as ForcePressDetector).onForcePressStart(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
|
||||||
|
onPanDown: game is PanDetector
|
||||||
|
? (DragDownDetails d) => (game as PanDetector).onPanDown(d)
|
||||||
|
: null,
|
||||||
|
onPanStart: game is PanDetector
|
||||||
|
? (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
|
||||||
|
onScaleStart: game is ScaleDetector
|
||||||
|
? (ScaleStartDetails d) => (game as ScaleDetector).onScaleStart(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(
|
||||||
|
color: const Color(0xFF000000),
|
||||||
|
child: Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: EmbeddedGameWidget(game))),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a more complete and opinionated implementation of Game.
|
/// This is a more complete and opinionated implementation of Game.
|
||||||
@@ -94,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) {}
|
||||||
|
}
|
||||||
@@ -113,6 +113,10 @@ class Util {
|
|||||||
/// This properly binds a gesture recognizer to your game.
|
/// This properly binds a gesture recognizer to your game.
|
||||||
///
|
///
|
||||||
/// Use this in order to get it to work in case your app also contains other widgets.
|
/// Use this in order to get it to work in case your app also contains other widgets.
|
||||||
|
///
|
||||||
|
/// Read more at: https://flame-engine.org/docs/input.md
|
||||||
|
///
|
||||||
|
/// @Deprecated('This method can lead to confuse behaviour, use the gestures methods provided by the Game class')
|
||||||
void addGestureRecognizer(GestureRecognizer recognizer) {
|
void addGestureRecognizer(GestureRecognizer recognizer) {
|
||||||
if (GestureBinding.instance == null) {
|
if (GestureBinding.instance == null) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: flame
|
name: flame
|
||||||
description: A minimalist Flutter game engine, provides a nice set of somewhat independent modules you can choose from.
|
description: A minimalist Flutter game engine, provides a nice set of somewhat independent modules you can choose from.
|
||||||
version: 0.16.1
|
version: 0.17.0
|
||||||
author: Luan Nico <luannico27@gmail.com>
|
author: Luan Nico <luannico27@gmail.com>
|
||||||
homepage: https://github.com/flame-engine/flame
|
homepage: https://github.com/flame-engine/flame
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user