En Flame, tenemos acceso al teclado como fuente de datos, es decir, un mecanismo con el cual el usuario puede interactuar con la aplicación; al igual que ocurre con otros componentes en Flame, tenemos acceso a la entrada de datos por el teclado tanto a nivel de la clase tipo Game y de componentes; aunque, su implementación es prácticamente la misma; veamos ambas implementaciones.
Con la clase KeyboardEvents en las clases tipo Game o la clase KeyboardHandler en componentes, tenemos funciones que permiten detectar y responder a eventos del teclado realizados por el usuario y tambien combinación de teclas. combinaciones de teclas y eventos relacionados; tenemos constantes como LogicalKeyboardKey.arrowUp para determinar cada tecla; veamos una implementación practica.
Clase tipo Game
Siguiendo con nuestra aplicación, vamos a colocar a nivel de la clase FlameGame, el escuchador de las entradas de teclado:
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;
}
}
Al presionar distintas teclas, con cualquiera de los eventos, veremos una salida como la siguiente:
{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"))
En el caso anterior, se presionó la tecla de flecha arriba o arrow up.
Para este experimento, no realizaremos ninguna adaptación más en la aplicación ya que, la lógica del juego va a estar implementada en los componentes y no a nivel de juego.
Puedes crear condiciones como:
keysPressed.contains(LogicalKeyboardKey.arrowUp)
Para preguntar por la tecla presionada.
Nivel de componente
Para poder utilizar los eventos localmente en los componentes, debemos de utilizar el mixin HasKeyboardHandlerComponents a nivel de la clase FlameGame:
lib/main.dart
class <LevelGame> extends FlameGame
with
HasKeyboardHandlerComponents {}
Y ahora, a nivel del componente al cual vamos a colocar el escucha del evento de teclado, usamos el mixin de KeyboardHandler:
class <Component> extends <TypeComponent> with KeyboardHandler {}
Caso práctico
Con las configuraciones anteriores realizadas tanto a nivel de la clase Game como en el componente, vamos a realizar algunas modificaciones sobre la clase componente llamada "PlayerImageSpriteComponent", vamos a agregar el evento para mover el 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;
}
}
Como puedes apreciar en el código anterior, podemos mover fácilmente el sprite utilizando las flechas del teclado y modificando el vector position provisto por la clase SpriteComponent/PositionComponent; aunque esta no es la forma obtima de mover al player, ya que, no estamos usando el deltatime, es un primer acercamiento.
Recuerda que este material forma parte de mi curso y libro completo sobre Flutter Flame.
- Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter