Combate
El combate no es tanto un sistema discreto como uno más abstracto: se trata de la interacción compleja de varios sistemas diferentes trabajando juntos, y la complejidad de la implementación depende mucho de la complejidad del diseño.
En este juego, el ámbito del diseño es muy sencillo. El jugador tiene una forma de atacar: saltar encima de un enemigo. Los enemigos tienen dos formas distintas de atacar al jugador: cuerpo a cuerpo y por contacto, en función del tipo de enemigo.
Para el ataque del jugador y el ataque cuerpo a cuerpo del enemigo, los fundamentos son prácticamente los mismos. Tenemos una o más cajas de impacto colocadas en la malla esquelética del personaje en función de cómo puedan atacar cuerpo a cuerpo, junto a una o más cajas de daño para hacer una aproximación de la zona que queremos que admita prueba de posicionamiento.
En el caso del ataque por contacto del enemigo, utilizamos la cápsula de colisión del enemigo para comprobar si el jugador ha entrado en contacto con ella y se ejecutan las mismas acciones de impacto que para el cuerpo a cuerpo. Puedes ver la implementación de lo que ocurre cuando un personaje recibe un impacto en nuestra clase base de personaje que está aquí: Parrot\Source\Parrot\Public\Character\ParrotCharacterBase.h. La lógica funcional se encuentra aquí y en las subclases ParrotPlayerCharacter.h y ParrotEnemyCharacterBase.h.
El personaje jugable
La configuración para el jugador tiene un sistema de funcionamiento propio a la hora de atacar a un enemigo. Cuando el jugador se solapa con una caja de daño de un enemigo, el enemigo da esta información al jugador para preguntar si el ataque ha sido válido. De ser así, comprueba si el jugador se encuentra en la parte superior de la caja de daño para garantizar que el jugador va a aterrizar en la parte superior y no va a golpear desde los lados o desde abajo. Si el ataque es válido, el enemigo enviará una señal al jugador para que dé un salto. Si el jugador todavía está pulsando el botón de salto cuando entra en contacto con la caja de daño, saltará más alto. Soltar antes de entrar en contacto con la caja de daño dará lugar a un salto más bajo.
El personaje enemigo
La configuración del enemigo es un poco más complicada por varios motivos. Queremos que los ataques cuerpo a cuerpo resulten realistas, así que las cajas de daño del enemigo se colocan en los filos de las armas. Las cajas de impacto, las cajas de daño y la configuración de la cápsula de colisión se pueden ver en el visor del blueprint de un personaje enemigo, como, por ejemplo, el que hay aquí: Blueprints > Enemy > Skeleton > BP_EnemyCharacter_Skeleton.
En este ejemplo, puedes ver la caja de daño en la cabeza, la caja de impacto en la espada y la cápsula de colisión. Cada uno de estos activadores impulsa sus eventos superpuestos a las funciones principales en la clase base del personaje.
Además, las animaciones de ataque envían eventos de notificación que solo habilitan las cajas de impacto del arma durante la parte de la animación en la que se blande el arma. De esta forma, parece que el jugador está siendo golpeado por el arma, y no solo entrando en contacto con un enemigo y recibiendo daño en cualquier momento aleatorio. Estas notificaciones de animación se insertan en la animación del ataque en puntos específicos para activar la caja de daño y, a continuación, desactivarla. Puedes ver las notificaciones de animación en Blueprints > Enemy/EnemyBase > BP_AnimNotify_EnemyAttackBegin y Blueprints > Enemy > EnemyBase > BP_AnimNotify_EnemyAttackEnd con la configuración de la animación de ataque de un personaje enemigo específico, como Assets> Quaternius > PirateKit > Characters > Headless_Skeleton > Animations > Characters_Skeleton_Headless_Anim_CharacterArmature_Sword.
El personaje enemigo es el que comprueba si hay solapamientos y activa los eventos, lo que significa que el enemigo activa tanto su propia función HitCharacter() como la función HitCharacter() del jugador cuando se detectan solapamientos adecuados.
Puedes ver el código que actúa sobre el solapamiento de la caja de impacto y la caja de daño aquí: Parrot\Source\Parrot\Public\Character\ParrotEnemyCharacterBase.h en las funciones HitBeginOverlap() y HurtBeginOverlap().
Combate de jefe
Para nuestra pelea de jefe, hay una funcionalidad adicional cuando el jugador golpea al jefe para reproducir una secuencia de «ira». Puedes ver el código de blueprint que activa una respuesta del jefe aquí.: Blueprints > Enemy > BossShark > BP_EnemyCharacter_BossShark.
La secuencia de «ira» es una secuencia temporizada sencilla que reproduce una animación telegrafiada de «sacudida de cabeza» antes de aumentar la velocidad de marcha del jefe y habilitar un componente de llamas verdes en cascada para los efectos visuales. Esta secuencia también desactiva la caja de daño, por lo que el jefe es invencible.