输入
手势 Gestures
在package:flame/gestures.dart
中,你可以找到一整套mixin
,可以将它们放在game类实例中以接收触摸/输入事件。下面来列举出这些mixin及其函数的完整列表:
- TapDetector
- 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
- MultiTouchTapDetector
- onTap
- onTapCancel
- onTapDown
- onTapUp
- MultiTouchDragDetector
- onReceiveDrag
要注意,这些检测器中有很多会彼此冲突。比如你不能同时注册"垂直"和"水平"拖动,不是所有的拖动行为都会同时存在并使用的。
你也不能将高级检测器(MultiTouch*
)与基本检测器混合使用,因为高级检测器的优先级较高,会永远赢得"手势竞技场"的胜利,基本检测器将永远不会触发。比如,你可以同时使用MultiTouchDragDetector
和MultiTouchDragDetector
,但是如果尝试同时使用MultiTouchTapDetector
和PanDetector
,后面则不会触发任何事件。
Flame的GestureApi由Flutter的Gestures Widget提供,包括GestureDetector Widget 和RawGestureDetector Widget ,点击此处 阅读有关Flutter手势的更多信息。
举例
class MyGame extends Game with TapDetector {
// Other methods omitted
void onTapDown(TapDownDetails details) {
print("Player tap down on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
}
void onTapUp(TapUpDetails details) {
print("Player tap up on ${details.globalPosition.dx} - ${details.globalPosition.dy}");
}
}
你可以点击此处 查看完整示例。
可点击组件 TapableComponent
Flame还提供了一个简单的辅助工具,使我们可以轻松的处理PositionComponent
上的点击事件。
通过将HasTapableComponents
mixin添加至游戏中,并在组件内覆盖以下的函数,使你的组件轻松处理点击事件:
void onTapCancel() {}
void onTapDown(TapDownDetails details) {}
void onTapUp(TapUpDetails details) {}
最简用法示例:
import 'package:flame/components/component.dart';
import 'package:flame/components/mixins/tapable.dart';
class TapableComponent extends PositionComponent with Tapable {
// update and render omitted
void onTapUp(TapUpDetails details) {
print("tap up");
}
void onTapDown(TapDownDetails details) {
print("tap down");
}
void onTapCancel() {
print("tap cancel");
}
}
class MyGame extends BaseGame with HasTapableComponents {
MyGame() {
add(TapableComponent());
}
}
键盘
Flame提供了一种简单的函数来访问Flutter接收键盘输入的功能。
你只需将KeyboardEvents
mixin 添加至你的游戏类中。添加后,你需要实现onKeyEvent
函数,每次发生键盘事件时都会调用此函数,并且该函数将接收Flutter类RawKeyEvent
的实例。该项可用于获取发生的事件,比如按键是否按下、按下了哪个按键等。
简单例子:
import 'package:flame/game.dart';
import 'package:flame/keyboard.dart';
import 'package:flutter/services.dart';
class MyGame extends Game with KeyboardEvents {
// update and render omitted
void onKeyEvent(e) {
final bool isKeyDown = e is RawKeyDownEvent;
print(" Key: ${e.data.keyLabel} - isKeyDown: $isKeyDown");
}
}
点此 查看完整示例。
手柄 Joystick
Flame提供了一个组件,能够创建虚拟摇杆来为游戏输入信息。可以配置多个组合,例如两根摇杆,或一个摇杆加一些按钮,等等。
若要使用此功能,你需要创建JoystickComponent
, 按需对其进行配置,然后将其添加至game类中。
要从摇杆组件接收输入,你需要有一个实现了JoystickListener的类,并且需要将该类添加为先前创建的摇杆组件的listener。JoystickListener
可以实现为任何类,常见的做法是将其作为由摇杆控制的组件,比如播放器组件。
为了能更好理解,请看这个例子:
import 'package:flame/components/joystick/joystick_action.dart';
import 'package:flame/components/joystick/joystick_component.dart';
import 'package:flame/components/joystick/joystick_directional.dart';
import 'package:flame/game.dart';
import 'package:flame/gestures.dart';
import 'package:flutter/material.dart';
class MyGame extends BaseGame with MultiTouchDragDetector {
final player = Player();
final joystick = JoystickComponent(
componentPriority: 0,
directional: JoystickDirectional(
spriteBackgroundDirectional: Sprite('directional_background.png'), // optional
spriteKnobDirectional: Sprite('directional_knob.png'), // optional
isFixed: true, // optional
margin: const EdgeInsets.only(left: 100, bottom: 100), // optional
size: 80, // optional
color: Colors.blueGrey, // optional
opacityBackground: 0.5, // optional
opacityKnob: 0.8, // optional
),
actions: [
JoystickAction(
actionId: 1, // required
sprite: Sprite('action.png'), // optional
spritePressed: Sprite('action_pressed.png'), // optional
spriteBackgroundDirection: Sprite('action_direction_background.png'), // optional
enableDirection: false, // optional
size: 50, // optional
sizeFactorBackgroundDirection: 1.5, // optional
margin: const EdgeInsets.all(50), // optional
color: Colors.blueGrey, // optional
align: JoystickActionAlign.BOTTOM_RIGHT, // optional
opacityBackground: 0.5, // optional
opacityKnob: 0.8, // optional
),
],
);
MyGame() {
joystick.addObserver(player);
add(player);
add(joystick);
}
void onReceiveDrag(DragEvent drag) {
joystick.onReceiveDrag(drag);
super.onReceiveDrag(drag);
}
}
class Player extends Component implements JoystickListener {
void render(Canvas canvas) {}
void update(double dt) {}
void joystickAction(JoystickActionEvent event) {
// Do anything when click in action button.
print('Action: $event');
}
void joystickChangeDirectional(JoystickDirectionalEvent event) {
// Do anything when interact with directional.
print('Directional: $event');
}
}
JoyStickDirectionalEvent
JoystickDirectionalEvent({
JoystickMoveDirectional directional,
double intensity = 0.0,
double radAngle = 0.0,
});
enum JoystickMoveDirectional {
MOVE_UP,
MOVE_UP_LEFT,
MOVE_UP_RIGHT,
MOVE_RIGHT,
MOVE_DOWN,
MOVE_DOWN_RIGHT,
MOVE_DOWN_LEFT,
MOVE_LEFT,
IDLE
}
JoystickActionEvent
JoystickActionEvent({
int id,
double intensity = 0.0,
double radAngle = 0.0,
ActionEvent event,
});
enum ActionEvent { DOWN, UP, MOVE, CANCEL }
点此 查看完整示例。