3. Disparos
Crear el objeto Bullet
Sección titulada «Crear el objeto Bullet»-
En Recursos, clic derecho en la carpeta
objects› Novo objeto… (nuevo objeto). Ponle el nombreBullet. -
En el Inspetor (Inspector), elige el sprite
tiro. -
En el panel Camadas (capas; a la izquierda, debajo de Recursos), haz clic en + Camada › Instâncias. Haz doble clic en el nombre y llámala
Tiros. Arrastra esa capa debajo deInstancias: la capa de arriba queda delante, así que los disparos van a aparecer detrás de la nave. Después haz clic de nuevo enInstancias, para que vuelva a ser la capa activa. Mira Capas.
Esta vez no coloques el Bullet en la room: los disparos los va a crear el código, en el momento en que la nave dispare.
El código del disparo
Sección titulada «El código del disparo»Abre el Bullet.hpp, borra los ejemplos y escribe:
#pragma once#include <brasa/brasa.hpp>
// El disparo de la nave: sube hasta salir de la pantalla.class Bullet : public brasa::Entity {public: BRASA_VARS(Bullet)
void onSpawn() override; void onUpdate() override;};Después el Bullet.cpp:
#include "Bullet.hpp"
using namespace brasa;
// onSpawn corre una vez, cuando nace el disparo. vspeed negativo = sube en la pantalla.// El motor mueve el disparo solo en cada step, sin necesitar código en el onUpdate.void Bullet::onSpawn() { vspeed = -5.0f; }
void Bullet::onUpdate() { // ¿Salió por arriba? Lo destruimos para no acumular disparos invisibles. if (y < -8.0f) destroy();}
BRASA_ENTITY(Bullet);vspeedes la velocidad vertical, en píxeles por paso. Brasa sumavspeeda laysola en cada paso. En la pantalla, laycrece hacia abajo, así que-5hace subir el disparo.- Cuando el disparo pasa la parte de arriba de la pantalla (
y < -8),destroy()quita esa instancia del juego. Sin eso, los disparos seguirían existiendo para siempre, fuera de la pantalla.
La acción de disparar
Sección titulada «La acción de disparar»El proyecto ya tiene las acciones de dirección. Falta una para el disparo:
-
Abre Projeto › Configurações do projeto… (Proyecto › Configuración del proyecto) y ve a Ações de entrada (acciones de entrada).
-
Haz clic en + Ação (agregar acción) y ponle el nombre
atirar(disparar). -
En su fila, haz clic en el +, elige Apertar a tecla… (pulsar la tecla) y pulsa la barra espaciadora.
-
Si quieres disparar también con el mando, haz clic en el + otra vez y elige Botão do controle › Pad:A (botón del mando).
-
Haz clic en Salvar (guardar).
El intervalo entre los disparos
Sección titulada «El intervalo entre los disparos»Sin una pausa, la nave soltaría 60 disparos por segundo. Crea una variable más para controlar eso: en el Inspetor del Player, + Variável › inteiro (entero), con el nombre intervaloTiro (intervalo de disparo) y el valor 10. Son 10 pasos entre un disparo y otro.
Disparar
Sección titulada «Disparar»En el Player.hpp, agrega la parte private, con una variable que dice si la nave puede disparar. El archivo queda así:
#pragma once#include <brasa/brasa.hpp>
// La nave. velocidade e intervaloTiro son variables del objeto: cámbialas en el Inspector, sin tocar el código.class Player : public brasa::Entity {public: BRASA_VARS(Player)
void onSpawn() override; void onUpdate() override;
private: bool canShoot_ = true; // pasa a false durante intervaloTiro steps después de cada disparo};canShoot_ pertenece a la nave. Empieza en true (puede disparar) y va a pasar a false por un instante después de cada disparo. El private: dice que solo el propio Player la toca.
En el Player.cpp, agrega el bloque del disparo al final del onUpdate. El archivo entero queda así:
#include "Player.hpp"
#include <algorithm>
using namespace brasa;
void Player::onSpawn() { animSpeed = 0.2f; // la llama del motor alterna entre los 2 frames}
void Player::onUpdate() { // Las acciones están en la configuración del proyecto (teclado y mando). // axis devuelve de -1 a 1: -1 = la primera acción, 1 = la segunda. float dx = axis("esquerda", "direita"); float dy = axis("cima", "baixo"); if (dx != 0.0f && dy != 0.0f) { // en diagonal, avanza a la misma velocidad dx *= 0.7071f; dy *= 0.7071f; }
// clamp mantiene la nave dentro de la pantalla (la nave mide 16 px, así que el margen es 8). const float maxX = static_cast<float>(roomWidth()) - 8.0f; const float maxY = static_cast<float>(roomHeight()) - 8.0f; x = std::clamp(x + dx * velocidade, 8.0f, maxX); y = std::clamp(y + dy * velocidade, 8.0f, maxY);
// held(acción) es verdadero mientras la tecla o el botón están pulsados. if (held("atirar") && canShoot_) { spawn<Bullet>(x, y - 8.0f, "Tiros"); // el disparo nace en la capa Tiros, detrás de la nave canShoot_ = false; after(intervaloTiro, [this] { canShoot_ = true; }); // solo dispara de nuevo dentro de algunos steps }}
BRASA_ENTITY(Player);El bloque nuevo, línea por línea:
held("atirar") && canShoot_: la acciónatirarestá mantenida y puede disparar.spawn<Bullet>(x, y - 8.0f, "Tiros")crea un disparo en la posición de la nave, un poco más arriba (8 píxeles), en la capaTiros.canShoot_ = falsebloquea nuevos disparos.after(intervaloTiro, ...)programa algo para dentro deintervaloTiropasos (10 pasos, un sexto de segundo). Cuando llegue el momento,canShoot_vuelve a sertrue.
Fíjate en que el Player.cpp usa el Bullet sin ningún #include más: en Brasa, todo objeto ve a todos los demás.
Pruébalo ahora
Sección titulada «Pruébalo ahora»Pulsa Play. Mantén la barra espaciadora: la nave dispara una ráfaga de disparos que suben por la pantalla.
Prueba a cambiar el intervaloTiro en el Inspector a 3 o a 30 y mira la diferencia.
Lo que aprendiste
Sección titulada «Lo que aprendiste»- Los objetos se pueden crear desde el código con
spawn<Objeto>(x, y, "Camada"). Mira Disparar. hspeedyvspeedmueven el objeto solos en cada paso.destroy()quita la instancia del juego.- Creas tus propias acciones en la configuración del proyecto y preguntas por ellas con
held. after(pasos, ...)ejecuta algo más tarde. Mira Esperar y repetir.
Siguiente parte: 4. Enemigos →
