Hasta este momento, hemos usado el teclado como fuente principal para interactuar con el juego, pero, esto trae como inconveniente de que solo podríamos emplear dispositivos que cuenten con un teclado, como sería un PC o Mac, dejando a la aplicación fuera de otros dispositivos como teléfonos con Android e iOS; para que este tipo de aplicación, en la cual es necesario desplazar al player en todos los ejes (o solamente de izquierda a derecha y viceversa, como en el caso del juego del dinosaurio) podemos implementar un joystick virtual; Flame dispone de este tipo de componentes ya listos para usar en nuestra aplicación.
Un joystick virtual luce como el siguiente:
En definitiva, puedes ver que constan de dos componentes:
Comencemos implementando una clase joystick como la siguiente:
lib\components\hud\joystick.dart
import 'package:flame/components.dart';
import 'package:flutter/material.dart';
class Joystick extends JoystickComponent {
Joystick(
{required PositionComponent knob,
required PositionComponent background,
required EdgeInsets margin})
: super(knob: knob, background: background, margin: margin);
}
La clase JoystickComponent existe en la API de Flame y para implementar la misma, tenemos que definir dos propiedades fundamentales:
Ambos son PositionComponent por lo tanto, pueden ser un Sprite o una figura geométrica como un círculo.
Existen otras propiedades para personalizar el joystick como puedes consultar en la documentación oficial, pero, estas son las principales o claves.
Finalmente, creamos otro archivo y clase, con el cual, implementaremos la clase Joystick personalizada definida anteriormente y que llamaremos como Hud de heads-up display que es un término común en los videojuegos para referirse al apartado de iconos, mapas, vida, etc sobre el personaje. En esta clase implementamos la propiedad de knob y background del joystick como un par de círculos con colores, además, de posicionar el mismo en la pantalla mediante el margen:
lib\components\hud\hud.dart
import 'dart:async';
import 'package:flame/components.dart';
import 'package:flame/palette.dart';
import 'package:flutter/widgets.dart';
import 'package:parallax06/hud/joystick.dart';
class HudComponent extends PositionComponent {
late Joystick joystick;
@override
void onLoad() {
final joystickKnobPaint = BasicPalette.red.withAlpha(200).paint();
final joystickBackgroundPaint = BasicPalette.black.withAlpha(100).paint();
joystick = Joystick(
knob: CircleComponent(radius: 30.0, paint: joystickKnobPaint),
background:
CircleComponent(radius: 100, paint: joystickBackgroundPaint),
margin: const EdgeInsets.only(left: 40, top: 100));
add(joystick);
}
}
Finalmente, desde el main, agregamos una instancia de la clase anterior:
lib\main.dart
import 'package:parallax06/hud/hud_component.dart';
***
class MyGame extends FlameGame
with HasKeyboardHandlerComponents, HasCollisionDetection {
***
late HudComponent hudComponent;
@override
void onLoad() async {
***
hudComponent = HudComponent();
add(hudComponent);
}
***
}
El componente de Joystick de Flame, tiene todo lo necesario para implementar la movilidad en nuestros componentes; mediante el tipo enumerado:
joystick.direction
Conocemos el estado del knob o mando:
enum JoystickDirection {
up,
upLeft,
upRight,
right,
down,
downRight,
downLeft,
left,
idle,
}
También tenemos otras opciones que podemos usar para determinar el desplazamiento del knob; es decir, mientras más lejos el usuario lleve el mando:
Más alto será el vector:
[-1.0,-67.0] (joystick.delta)
Y mientras más cerca esté el knob del centro (mientras menos se desplace):
Más bajo será el vector:
[-1.0,-21.0] (joystick.delta)
Con este vector también tenemos el ángulo, es decir que si movemos el knob hacia arriba, tendremos un valor negativo en el Y:
[X,-72.0] (joystick.delta)
Y positivo si va hacia abajo:
[X,72.0] (joystick.delta)
Y la misma lógica se aplica para el eje de las X. Con esto, podemos usar de manera directa esta propiedad para desplazar al player sin necesidad de hacer comparaciones adicionales; finalmente, el desplazamiento del player mediante el joystick queda como:
lib\components\player_component.dart
class PlayerComponent extends Character with HasGameRef<MyGame> {
***
final double _maxVelocity = 5.0;
@override
void update(double dt) {
***
_movePlayerJoystick(dt);
}
void _movePlayerJoystick(double delta) {
if (gameRef.hudComponent.joystick.direction != JoystickDirection.idle) {
position.add(gameRef.hudComponent.joystick.delta * _maxVelocity * delta);
}
}
}
Es importante mencionar que podemos tener habilitados (como es el caso para nuestra aplicación) dos o más funciones para el desplazamiento, en nuestro proyecto sería el desplazamiento mediante teclado y también mediante el joystick.
Finalmente, al ejecutar la aplicación, tendremos:
Claro está, que el joystick lo puedes implementar en los juegos anteriores para utilizar el juego en otros dispositivos que no cuenten con teclados.
Este material forma parte de mi curso y libro completo sobre el desarrollo de juegos en 2D con Flutter y Flame.
- Andrés Cruz
In englishDesarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter
Acepto recibir anuncios de interes sobre este Blog.
!Cursos desde!
4$
En Academia
Ver los cursos!Libros desde!
1$
Ver los libros