3. Tiros
Criar o objeto Bullet
Seção intitulada “Criar o objeto Bullet”-
Em Recursos, botão direito na pasta
objects› Novo objeto…. Dê o nomeBullet. -
No Inspetor, escolha o sprite
tiro. -
No painel Camadas (à esquerda, embaixo de Recursos), clique em + Camada › Instâncias. Dê dois cliques no nome e chame de
Tiros. Arraste essa camada para baixo deInstancias: a camada de cima fica na frente, então os tiros vão aparecer atrás da nave. Depois clique de novo emInstancias, para ela voltar a ser a camada ativa. Veja Camadas.
Desta vez não coloque o Bullet na room: os tiros vão ser criados pelo código, na hora em que a nave atirar.
O código do tiro
Seção intitulada “O código do tiro”Abra o Bullet.hpp, apague os exemplos e escreva:
#pragma once#include <brasa/brasa.hpp>
// O tiro da nave: sobe até sair da tela.class Bullet : public brasa::Entity {public: BRASA_VARS(Bullet)
void onSpawn() override; void onUpdate() override;};Depois o Bullet.cpp:
#include "Bullet.hpp"
using namespace brasa;
// onSpawn roda uma vez, quando o tiro nasce. vspeed negativo = sobe na tela.// A engine move o tiro sozinha a cada step, sem precisar de código no onUpdate.void Bullet::onSpawn() { vspeed = -5.0f; }
void Bullet::onUpdate() { // Saiu pelo topo? Destruímos para não acumular tiros invisíveis. if (y < -8.0f) destroy();}
BRASA_ENTITY(Bullet);vspeedé a velocidade vertical, em pixels por passo. A Brasa somavspeedaoysozinha a cada passo. Na tela, oycresce para baixo, então-5faz o tiro subir.- Quando o tiro passa do topo da tela (
y < -8),destroy()remove essa instância do jogo. Sem isso, os tiros continuariam existindo para sempre, fora da tela.
A ação de atirar
Seção intitulada “A ação de atirar”O projeto já tem as ações de direção. Falta uma para o tiro:
-
Abra Projeto › Configurações do projeto… e vá até Ações de entrada.
-
Clique em + Ação e dê o nome
atirar. -
Na linha dela, clique no +, escolha Apertar a tecla… e aperte a barra de espaço.
-
Se quiser atirar também com o controle, clique no + de novo e escolha Botão do controle › Pad:A.
-
Clique em Salvar.
O intervalo entre os tiros
Seção intitulada “O intervalo entre os tiros”Sem uma pausa, a nave soltaria 60 tiros por segundo. Crie mais uma variável para controlar isso: no Inspetor do Player, + Variável › inteiro, com o nome intervaloTiro e o valor 10. São 10 passos entre um tiro e outro.
No Player.hpp, acrescente a parte private, com uma variável que diz se a nave pode atirar. O arquivo fica assim:
#pragma once#include <brasa/brasa.hpp>
// A nave. velocidade e intervaloTiro são variáveis do objeto: mude no Inspetor, sem mexer no código.class Player : public brasa::Entity {public: BRASA_VARS(Player)
void onSpawn() override; void onUpdate() override;
private: bool canShoot_ = true; // vira false por intervaloTiro steps depois de cada tiro};canShoot_ pertence à nave. Ela começa true (pode atirar) e vai virar false por um instante depois de cada tiro. O private: diz que só o próprio Player mexe nela.
No Player.cpp, acrescente o bloco do tiro no fim do onUpdate. O arquivo inteiro fica assim:
#include "Player.hpp"
#include <algorithm>
using namespace brasa;
void Player::onSpawn() { animSpeed = 0.2f; // a chama do motor alterna entre os 2 frames}
void Player::onUpdate() { // As ações ficam em Configurações do projeto (teclado e controle). // axis devolve de -1 a 1: -1 = a primeira ação, 1 = a segunda. float dx = axis("esquerda", "direita"); float dy = axis("cima", "baixo"); if (dx != 0.0f && dy != 0.0f) { // na diagonal, anda com a mesma velocidade dx *= 0.7071f; dy *= 0.7071f; }
// clamp mantém a nave dentro da tela (a nave tem 16 px, então a margem é 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(ação) é verdadeiro enquanto a tecla ou o botão estão pressionados. if (held("atirar") && canShoot_) { spawn<Bullet>(x, y - 8.0f, "Tiros"); // o tiro nasce na camada Tiros, atrás da nave canShoot_ = false; after(intervaloTiro, [this] { canShoot_ = true; }); // só atira de novo daqui a alguns steps }}
BRASA_ENTITY(Player);O bloco novo, linha por linha:
held("atirar") && canShoot_: a açãoatirarestá segurada e pode atirar.spawn<Bullet>(x, y - 8.0f, "Tiros")cria um tiro na posição da nave, um pouco acima (8 pixels), na camadaTiros.canShoot_ = falsebloqueia novos tiros.after(intervaloTiro, ...)agenda algo para daqui aintervaloTiropassos (10 passos, um sexto de segundo). Quando chegar a hora,canShoot_volta a sertrue.
Repare que o Player.cpp usa o Bullet sem nenhum #include a mais: na Brasa, todo objeto enxerga todos os outros.
Teste agora
Seção intitulada “Teste agora”Aperte Play. Segure a barra de espaço: a nave dispara uma rajada de tiros que sobem pela tela.
Experimente mudar o intervaloTiro no Inspetor para 3 ou para 30 e veja a diferença.
O que você aprendeu
Seção intitulada “O que você aprendeu”- Objetos podem ser criados pelo código com
spawn<Objeto>(x, y, "Camada"). Veja Atirar. hspeedevspeedmovem o objeto sozinhos a cada passo.destroy()remove a instância do jogo.- Você cria as suas próprias ações nas Configurações do projeto e pergunta por elas com
held. after(passos, ...)executa algo mais tarde. Veja Esperar e repetir.
Próxima parte: 4. Inimigos →
