4. Inimigos
Criar os objetos
Seção intitulada “Criar os objetos”-
Crie o objeto
Enemy(Novo objeto… na pastaobjects). No Inspetor, escolha o spriteinimigo. No painel Camadas, crie mais uma camada de Instâncias, chamadaInimigos, e arraste para baixo deTiros. Depois clique de novo emInstancias. -
Crie o objeto
Spawnere deixe sem sprite. Ele não aparece no jogo: o trabalho dele é só criar inimigos. -
Arraste o
Spawnerpara a roomMain. Pode ser em qualquer lugar; no editor ele aparece como um quadradinho. OEnemynão vai na room: quem cria os inimigos é oSpawner.
O inimigo
Seção intitulada “O inimigo”Abra o Enemy.hpp, apague os exemplos e escreva:
#pragma once#include <brasa/brasa.hpp>
// Inimigo que cai do topo da tela.class Enemy : public brasa::Entity {public: BRASA_VARS(Enemy)
void onSpawn() override; void onUpdate() override;};E o Enemy.cpp:
#include "Enemy.hpp"
using namespace brasa;
void Enemy::onSpawn() { animSpeed = 0.1f; // random(a, b) sorteia um número entre a e b: cada inimigo cai numa velocidade diferente. vspeed = random(0.8f, 1.6f); // Quando um Bullet encosta em mim, o tiro e eu somos destruídos. // Os outros objetos (Bullet, Player...) já são conhecidos aqui, sem #include. onCollide<Bullet>([this](Bullet& bullet) { bullet.destroy(); destroy(); });}
void Enemy::onUpdate() { // roomHeight() é a altura da tela; passou dela (com folga), o inimigo escapou. if (y > static_cast<float>(roomHeight()) + 16.0f) destroy();}
BRASA_ENTITY(Enemy);random(0.8f, 1.6f)sorteia um número entre 0,8 e 1,6. Cada inimigo cai numa velocidade diferente, o que deixa o jogo menos previsível.onCollide<Bullet>(...)diz: “quando eu encostar numBullet, faça isto”. A Brasa confere as caixas de colisão a cada passo e chama a lambda. O tiro que acertou chega comobullet, e os dois são destruídos.- No
onUpdate, o inimigo que passou do fim da tela é destruído.
O Spawner
Seção intitulada “O Spawner”Abra o Spawner.hpp, apague os exemplos e escreva:
#pragma once#include <brasa/brasa.hpp>
// Cria inimigos no topo da tela, cada vez mais rápido.class Spawner : public brasa::Entity {public: BRASA_VARS(Spawner)
void onSpawn() override;
private: void scheduleNext(); // agenda o próximo inimigo int spawned_ = 0;};O Spawner tem uma função só dele, scheduleNext, e conta quantos inimigos já criou em spawned_.
Agora o Spawner.cpp:
#include "Spawner.hpp"
#include <algorithm>
using namespace brasa;
// O Spawner não precisa de onUpdate: ele agenda o próximo inimigo com after(),// que chama a função depois de N steps (a 60 steps por segundo).void Spawner::onSpawn() { scheduleNext(); }
void Spawner::scheduleNext() { // O intervalo encurta aos poucos (de 1 s até no mínimo 0,25 s): o jogo fica mais difícil. const int interval = std::max(15, 60 - spawned_ * 2); after(interval, [this] { ++spawned_; const float margin = 16.0f; spawn<Enemy>(random(margin, static_cast<float>(roomWidth()) - margin), -16.0f, "Inimigos"); scheduleNext(); // agenda o seguinte });}
BRASA_ENTITY(Spawner);Como ele funciona:
- Quando o
Spawnernasce,onSpawnchamascheduleNext(). scheduleNextcalcula um intervalo: 60 passos (1 segundo) no começo, 2 passos a menos a cada inimigo, até o mínimo de 15.std::max(15, ...)garante esse mínimo.after(interval, ...)espera esse tempo e cria umEnemynuma posiçãoxsorteada, logo acima da tela (y = -16).- Depois chama
scheduleNext()de novo, e o ciclo continua para sempre.
Teste agora
Seção intitulada “Teste agora”Aperte Play. Os inimigos começam a cair, cada vez mais rápido. Atire neles: tiro e inimigo somem juntos. Por enquanto, encostar na nave não faz nada; isso vem na próxima parte.
O que você aprendeu
Seção intitulada “O que você aprendeu”- Um objeto sem sprite pode ter um trabalho invisível, como o
Spawner. random(a, b)sorteia números. Veja Sorteio.onCollide<Objeto>(...)reage quando dois objetos se encostam. Veja Colisões.- Uma função que se agenda de novo com
aftercria uma repetição com intervalo variável.
Próxima parte: 5. Pontos e vidas →
