Flutter - Flame输入事件

文章目录[x]
  1. 1:点击事件
  2. 2:拖动事件
  3. 3:手势输入
  4. 4:键盘输入
  5. 4.1:在游戏级别中接收键盘事件
  6. 4.2:在组件级别接收键盘事件
  7. 5:鼠标事件
  8. 5.1:悬停回调

在上一篇文章中,我们介绍了Flame中的碰撞检测。在这篇文章中,我们将介绍Flame中的输入事件包含如下:

  • 点击事件
  • 拖动事件
  • 手势输入
  • 键盘输入

点击事件

点击事件是与 Flame 游戏交互的最基本方法之一。当用户用手指触摸屏幕、用鼠标单击或用触控笔轻敲时,就会发生这些事件。点击可以“持续很长时间”,但手指在手势过程中不应该移动。因此,触摸屏幕,然后移动手指,然后松开 - 不是点击,而是拖动。同样,在鼠标移动时单击鼠标按钮也会被记录为拖动。

多个点击事件可以同时发生,特别是当用户有多根手指时。Flame 将正确处理这种情况,甚至可以使用它们的 pointerId 属性来跟踪事件。

对于那些想要响应点击的组件,直接混入TapCallbacks :

class MyComponent extends PositionComponent with TapCallbacks {
MyComponent() : super(size: Vector2(80, 60));

@override
void onTapUp(TapUpEvent event) {
// Do something in response to a tap event
}
}

可以重写如下事件:

  • onTapDown  点击按下
  • onLongTapDown  长按按下
  • onTapUp 点击收起
  • onTapCancel 点击取消

拖动事件

当用户将手指移过设备屏幕或按住鼠标按钮移动鼠标时,会发生拖动事件。

如果用户使用多个手指,则可能同时发生多个拖动事件。 Flame 可以正确处理此类情况,可以使用其 pointerId 属性来跟踪事件。

对于想要响应拖动的组件,混入DragCallbacks:

class MyComponent extends PositionComponent with DragCallbacks {
MyComponent() : super(size: Vector2(180, 120));

@override
void onDragStart(DragStartEvent event) {
// Do something in response to a drag event
}
}

可以重写如下事件:

  • onDragStart 拖动开始
  • onDragUpdate 拖拽更新
  • onDragEnd 拖拽结束
  • onDragCancel 拖拽取消

手势输入

这是直接附加在游戏类上的手势输入,大多数时候您希望检测组件上的输入,例如,请参阅 TapCallbacks 和 DragCallbacks。

在 package:flame/gestures.dart 中,可以找到一整套 mixin,它们可以包含在游戏类实例中,以便能够接收触摸输入事件。可以在下面看到这些 mixin 及其方法的完整列表:

- TapDetector
- onTap
- onTapCancel
- onTapDown
- onLongTapDown
- onTapUp

- SecondaryTapDetector
- onSecondaryTapDown
- onSecondaryTapUp
- onSecondaryTapCancel

- TertiaryTapDetector
- onTertiaryTapDown
- onTertiaryTapUp
- onTertiaryTapCancel

- 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

键盘输入

游戏可以通过两种方式对按键做出反应:在游戏级别和在组件级别。对于每种方式,都有一个 mixin,可以将其添加到 Game 或 Component 类中。

在游戏级别中接收键盘事件

要使 Game 子类对按键进行监听,可以混入KeyboardEvents。

之后,就可以重写 onKeyEvent 方法。

此方法接收两个参数,第一个是首先触发回调的 KeyEvent。第二个是当前按下的 LogicalKeyboardKey 的集合。

返回值是 KeyEventResult。

KeyEventResult.handled 将告诉框架按键已在 Flame 内部解析,并跳过除 GameWidget 之外的任何其他键盘处理程序小部件。

KeyEventResult.ignored 将告诉框架继续在除 GameWidget 之外的任何其他键盘处理程序小部件中测试此事件。如果任何处理程序都未解析该事件,则框架将触发 SystemSoundType.alert。

KeyEventResult.skipRemainingHandlers 与 .ignored 非常相似,除了它会跳过任何其他处理程序小部件并直接播放警报声音之外。

class MyGame extends FlameGame with KeyboardEvents {
// ...
@override
KeyEventResult onKeyEvent(
KeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final isKeyDown = event is KeyDownEvent;

final isSpace = keysPressed.contains(LogicalKeyboardKey.space);

if (isSpace && isKeyDown) {
if (keysPressed.contains(LogicalKeyboardKey.altLeft) ||
keysPressed.contains(LogicalKeyboardKey.altRight)) {
this.shootHarder();
} else {
this.shoot();
}
return KeyEventResult.handled;
}
return KeyEventResult.ignored;
}
}

在组件级别接收键盘事件

要在组件中直接接收键盘事件,可以混入KeyboardHandler。

与 TapCallbacks 和 DragCallbacks 类似,KeyboardHandler 可以混入到 Component 的任何子类中。

KeyboardHandler 只能添加到与 HasKeyboardHandlerComponents 混合的游戏中。

应用 KeyboardHandler 后,可以覆盖 onKeyEvent 方法。

此方法接收两个参数。首先是首先触发回调的 KeyEvent。第二个是一组当前按下的 LogicalKeyboardKeys。返回值应为 true,以允许按键事件在其他组件之间持续传播。要不允许任何其他组件接收事件,请返回 false。

Flame 还提供了一个名为 KeyboardListenerComponent 的默认实现,可用于处理键盘事件。与任何其他组件一样,它可以作为子组件添加到 FlameGame 或其他组件中。

鼠标事件

鼠标事件是 Flutter 的通用“鼠标移动”类型事件(适用于桌面或web)。

如果想在组件或游戏中与鼠标移动事件进行交互,则可以混入PointerMoveCallbacks。

例如:

class MyComponent extends PositionComponent with PointerMoveCallbacks {
MyComponent() : super(size: Vector2(80, 60));

@override
void onPointerMove(PointerMoveEvent event) {
// Do something in response to the mouse move (e.g. update coordinates)
}
}

mixin 为你的组件添加了两个可覆盖的方法:

  • onPointerMove:鼠标在组件内移动时调用
  • onPointerMoveStop:当组件悬停并且鼠标离开时调用一次

默认情况下,这些方法都不执行任何操作,需要重写它们才能执行任何功能。

悬停回调

如果想要具体了解组件是否正在悬停,或者想要挂接到悬停进入和退出事件,则可以混入HoverCallbacks:

class MyComponent extends PositionComponent with HoverCallbacks {

MyComponent() : super(size: Vector2(80, 60));

@override
void update(double dt) {
// use `isHovered` to know if the component is being hovered
}

@override
void onHoverEnter() {
// Do something in response to the mouse entering the component
}

@override
void onHoverExit() {
// Do something in response to the mouse leaving the component
}
}
点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像

Title - Artist
0:00