* Add keyboard with focus node implementation * a * format and make it stabel compatible * Add mixin to game * fixes * add tests * format * docs * more docs * Update doc/keyboard-input.md Co-authored-by: Erick <erickzanardoo@gmail.com> * rename test * Apply suggestions from code review Co-authored-by: Luan Nico <luanpotter27@gmail.com> * fix test * Update tutorials/2_sprite_animations_gestures/README.md Co-authored-by: Luan Nico <luanpotter27@gmail.com> * docs * Apply suggestions from code review Co-authored-by: Jochum van der Ploeg <jochum@vdploeg.net> * yo Co-authored-by: Erick <erickzanardoo@gmail.com> Co-authored-by: Luan Nico <luanpotter27@gmail.com> Co-authored-by: Jochum van der Ploeg <jochum@vdploeg.net>
4.1 KiB
Keyboard Input
This includes documentation for keyboard inputs.
For other input documents, see also:
- Gesture Input: for mouse and touch pointer gestures
- Other Inputs: For joysticks, game pads, etc.
Intro
The keyboard API on flame relies on the Flutter's Focus widget.
To customize focus behavior, see Controlling focus.
There are two ways a game can be sensitive to key strokes; at the game level and at a component level.
For each we have a mixin that can me added to Games and BaseComponents, respectively.
Receive keyboard events in a game level
To make a Game sub class sensitive to key stroke, mix it with KeyboardEvents.
After that, it will be possible to override an onKeyEvent method.
This method receives two parameters, first the RawKeyEvent
that triggered the callback in the first place. The second is a set of the currently pressed LogicalKeyboardKey.
The return value should be a KeyEventResult.
KeyEventResult.handled will tell the framework that the key stroke was resolved inside of Flame and skip any other keyboard handler widgets apart of GameWidget.
KeyEventResult.ignored will tell the framework to keep testing this event in any other keyboard handler widget apart of GameWidget. If the event is not resolved by any handler, the framework will trigger SystemSoundType.alert.
KeyEventResult.skipRemainingHandlers is very similar to .ignored, apart from the fact that will skip any other handler widget and will straight up play the alert sound.
Minimal example:
class MyGame extends Game with KeyboardEvents {
// ...
@override
KeyEventResult onKeyEvent(
RawKeyEvent event,
Set<LogicalKeyboardKey> keysPressed,
) {
final isKeyDown = event is RawKeyDownEvent;
final isSpace = event == 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;
}
}
Receive keyboard events in a component level
To receive keyboard events directly in components, there is the mixin KeyboardHandler.
Similarly to Tappable and Draggable, KeyboardHandler can be mixed into any BaseComponent
subclass.
KeyboardHandlers must only be added to games that are mixed with HasKeyboardHandlerComponents.
⚠️ Attention: If
HasKeyboardHandlerComponentsis used, you must removeKeyboardEventsfrom the game mixin list to avoid conflicts.
After applying HasKeyboardHandlerComponents, it will be possible to override an onKeyEvent method.
This method receives two parameters. First the RawKeyEvent
that triggered the callback in the first place. The second is a set of the currently pressed LogicalKeyboardKeys.
The returned value should be true to allow the continuous propagation of the key event among other components.
To not allow any other component to receive the event, return false.
Controlling focus
On the widget level, it is possible to use the FocusNode API to control whether the game is focused or not.
GameWidget has an optional focusNode parameter that allow its focus to be controlled externally.
By default GameWidget has its autofocus set to true, which means it will get focused once it is mounted. To override that behavior, set autofocus to false.
For a more complete example see here.