Pular para o conteúdo
Baixar

Colisão

A colisão usa a caixa de colisão do sprite, ajustada no editor de sprite. Duas instâncias colidem quando as caixas se sobrepõem; só encostar a borda não conta. Instâncias sem sprite não colidem, e o angle é ignorado.

Função O que faz Exemplo
void onCollide<T>(std::function<void(T&)> callback) Registra uma função chamada a cada passo em que esta instância encosta num T. Registre no onSpawn. onCollide<Coin>([](Coin& c) { c.destroy(); });
void onTouchStart<T>(std::function<void(T&)> callback) Como o onCollide, mas roda uma vez, quando o contato começa. Bom para moedas, portas e bandeiras. onTouchStart<Coin>([](Coin& c) { c.destroy(); });
void onTouchEnd<T>(std::function<void(T&)> callback) Roda uma vez, quando o contato termina. Não dispara para uma instância destruída. onTouchEnd<Water>([this](Water&) { gravity = 0.25f; });
bool collidesAt<T>(float atX, float atY) true se esta instância encostaria num T se estivesse em (atX, atY). if (!collidesAt<Wall>(x + 2, y)) x += 2;
T* findAt<T>(float atX, float atY) A primeira instância de T encostada nessa posição, ou nullptr. if (Enemy* e = findAt<Enemy>(x, y + 1)) e->destroy();
bool placeFree(float atX, float atY) true se nenhuma instância sólida encostaria nessa posição. if (placeFree(x, y + 1)) vspeed += 0.3f;

Para andar parando nas paredes, veja moveAndStop em Movimento.

Todas estas funções também aceitam o nome do objeto entre aspas no lugar do <T>. É assim que se reage a um objeto sem código. O callback recebe um Entity&.

Função Exemplo
Entity* touching(std::string_view object) if (touching("Espinho")) restart();
bool collidesAt(std::string_view object, float atX, float atY) if (collidesAt("Chao", x, y + 1)) ...
Entity* findAt(std::string_view object, float atX, float atY) if (Entity* e = findAt("Caixa", x + 1, y)) e->x += 1;
void onCollide(std::string_view object, std::function<void(Entity&)> callback) onCollide("Lava", [this](Entity&) { destroy(); });
void onTouchStart(std::string_view object, std::function<void(Entity&)> callback) onTouchStart("Espinho", [this](Entity&) { restart(); });
void onTouchEnd(std::string_view object, std::function<void(Entity&)> callback) onTouchEnd("Agua", [this](Entity&) { gravity = 0.25f; });
  • mask é o nome de um sprite. Quando definido, a caixa de colisão vem dele, e não do sprite atual: trocar de animação não muda a caixa. No editor, é a Máscara do objeto.
  • flipX espelha o desenho e a caixa de colisão em volta da origem.
  • O onCollide roda depois do movimento do passo, uma vez para cada T encostado.
  • Uma instância que já nasce encostada dispara o onTouchStart no primeiro passo.
  • Um onCollide registrado dentro de outro já pode disparar no mesmo passo.
  • Sólido se marca no Inspetor do objeto, ou no código com solid = true.

Estas continuam funcionando:

Função O que faz
T* touching<T>() A primeira instância de T encostada agora, ou nullptr.
T* touching<T>(float atX, float atY) O mesmo, numa posição.
std::vector<T*> touchingAll<T>() Todas as instâncias de T encostadas agora.
std::optional<Rect> collisionBox() const A caixa de colisão no mundo, na posição atual.
std::optional<Rect> collisionBoxAt(float atX, float atY) const A caixa se a instância estivesse em (atX, atY).