Ir al contenido
Descargar

Colisión

La colisión usa la caja de colisión del sprite, ajustada en el editor de sprite. Dos instancias chocan cuando las cajas se superponen; tocarse solo por el borde no cuenta. Las instancias sin sprite no chocan, y el angle se ignora.

Función Qué hace Ejemplo
void onCollide<T>(std::function<void(T&)> callback) Registra una función que se llama en cada paso en que esta instancia toca un T. Regístrala en el onSpawn. onCollide<Coin>([](Coin& c) { c.destroy(); });
void onTouchStart<T>(std::function<void(T&)> callback) Como el onCollide, pero se ejecuta una vez, cuando empieza el contacto. Va bien para monedas, puertas y banderas. onTouchStart<Coin>([](Coin& c) { c.destroy(); });
void onTouchEnd<T>(std::function<void(T&)> callback) Se ejecuta una vez, cuando termina el contacto. No se dispara para una instancia destruida. onTouchEnd<Water>([this](Water&) { gravity = 0.25f; });
bool collidesAt<T>(float atX, float atY) true si esta instancia tocaría un T si estuviera en (atX, atY). if (!collidesAt<Wall>(x + 2, y)) x += 2;
T* findAt<T>(float atX, float atY) La primera instancia de T tocada en esa posición, o nullptr. if (Enemy* e = findAt<Enemy>(x, y + 1)) e->destroy();
bool placeFree(float atX, float atY) true si ninguna instancia sólida sería tocada en esa posición. if (placeFree(x, y + 1)) vspeed += 0.3f;

Para avanzar deteniéndote en las paredes, mira moveAndStop en Movimiento.

Todas estas funciones también aceptan el nombre del objeto entre comillas en lugar del <T>. Así es como se reacciona a un objeto sin código. El callback recibe un Entity&.

Función Ejemplo
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 es el nombre de un sprite. Cuando está definido, la caja de colisión viene de él, y no del sprite actual: cambiar de animación no cambia la caja. En el editor, es la Máscara del objeto.
  • flipX espeja el dibujo y la caja de colisión alrededor del origen.
  • El onCollide se ejecuta después del movimiento del paso, una vez por cada T tocado.
  • Una instancia que ya nace tocando dispara el onTouchStart en el primer paso.
  • Un onCollide registrado dentro de otro ya puede dispararse en el mismo paso.
  • Sólido se marca en el Inspector del objeto, o en el código con solid = true.

Estas siguen funcionando:

Función Qué hace
T* touching<T>() La primera instancia de T tocada ahora, o nullptr.
T* touching<T>(float atX, float atY) Lo mismo, en una posición.
std::vector<T*> touchingAll<T>() Todas las instancias de T tocadas ahora.
std::optional<Rect> collisionBox() const La caja de colisión en el mundo, en la posición actual.
std::optional<Rect> collisionBoxAt(float atX, float atY) const La caja si la instancia estuviera en (atX, atY).