Key-in event in Flutter Flame

In Flame, we have access to the keyboard as a data source, that is, a mechanism with which the user can interact with the application; as with other components in Flame, we have access to keyboard input at both the Game class and component level; although, its implementation is practically the same; let's look at both implementations.

With the KeyboardEvents class in the Game type classes or the KeyboardHandler class in components, we have functions that allow us to detect and respond to keyboard events performed by the user and also key combinations. key combinations and related events; we have constants like LogicalKeyboardKey.arrowUp to determine each key; let's see a practical implementation.

Game type class

Continuing with our application, we are going to place the keyboard input listener at the FlameGame class level:

class MyGame extends FlameGame with KeyboardEvents {
  ***
  @override
  KeyEventResult onKeyEvent(
    RawKeyEvent event,
    Set<LogicalKeyboardKey> keysPressed,
  ) {
    super.onKeyEvent(event, keysPressed);

    //print(keysPressed);
    print(event);

    return KeyEventResult.handled;
  }
}

When pressing different keys, with any of the events, we will see an output like the following:

{LogicalKeyboardKey#00301(keyId: "0x100000301", keyLabel: "Arrow Down", debugName: "Arrow Down")}

RawKeyUpEvent#881c1(logicalKey: LogicalKeyboardKey#00304(keyId: "0x100000304", keyLabel: "Arrow Up", debugName: "Arrow Up"), physicalKey: PhysicalKeyboardKey#70052(usbHidUsage: "0x00070052", debugName: "Arrow Up"))

In the above case, the arrow up or arrow up key was pressed.

For this experiment, we will not make any further adaptations in the application, since the game logic will be implemented in the components and not at the game level.

You can create conditions like:

keysPressed.contains(LogicalKeyboardKey.arrowUp)

To ask for the key pressed.

Component level

In order to use the events locally in the components, we must use the HasKeyboardHandlerComponents mixin at the FlameGame class level:

lib/main.dart

class <LevelGame> extends FlameGame
    with
        HasKeyboardHandlerComponents {}

And now, at the component level to which we are going to place the keyboard event listener, we use the KeyboardHandler mixin:

class <Component> extends <TypeComponent> with KeyboardHandler {}

Case study

With the previous configurations made both at the Game class level and in the component, we are going to make some modifications to the component class called "PlayerImageSpriteComponent", we are going to add the event to move the sprite:

lib/components/player_image_sprite_component.dart

import 'package:flame/components.dart';

class PlayerImageSpriteComponent extends SpriteComponent with KeyboardHandler {
 ***
  @override
  bool onKeyEvent(
    RawKeyEvent event,
    Set<LogicalKeyboardKey> keysPressed,
  ) {
    if (keysPressed.contains(LogicalKeyboardKey.arrowUp)) {
      position = Vector2(centerX, centerY--);
    } else if (keysPressed.contains(LogicalKeyboardKey.arrowDown)) {
      position = Vector2(centerX, centerY++);
    } else if (keysPressed.contains(LogicalKeyboardKey.arrowRight)) {
      position = Vector2(centerX++, centerY);
    } else if (keysPressed.contains(LogicalKeyboardKey.arrowLeft)) {
      position = Vector2(centerX--, centerY);
    }

    return true;
  }
}

As you can see in the code above, we can easily move the sprite using the keyboard arrows and modifying the position vector provided by the SpriteComponent/PositionComponent class; although this is not the optimal way to move the player, since we are not using the deltatime, it is a first approach.

Remember that this material is part of my course and complete book on Flutter Flame.

- Andrés Cruz

En español
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.