migrades portes i plataformes a solidActor
This commit is contained in:
91
source/game/gameplay/solid_actor_manager.hpp
Normal file
91
source/game/gameplay/solid_actor_manager.hpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SolidActor;
|
||||
|
||||
/**
|
||||
* @brief Gestor de actores sólidos dinámicos (AABB) de una habitación.
|
||||
*
|
||||
* Paralelo al TileCollider: proporciona sweeps axis-aligned del Player
|
||||
* contra una lista de AABBs de entidades (puertas, plataformas móviles,
|
||||
* bloques empujables, ascensores, etc). El manager NO es propietario de
|
||||
* los actores — sus entidades concretas viven en sus respectivos managers
|
||||
* (DoorManager, PlatformManager, ...). Este manager solo mantiene una
|
||||
* lista de raw pointers para consultas de colisión.
|
||||
*
|
||||
* Cross-room: igual que CollisionMap::updateBorders, este manager acepta
|
||||
* punteros a los managers de las rooms adyacentes (setAdjacent). Cuando
|
||||
* el Player está cerca del borde, los sweeps iteran también sobre los
|
||||
* actores vecinos, trasladando sus AABBs por ±PlayArea::WIDTH/HEIGHT
|
||||
* para ponerlos en el sistema de coordenadas de la room actual.
|
||||
*/
|
||||
class SolidActorManager {
|
||||
public:
|
||||
struct FloorHit {
|
||||
float y{-1};
|
||||
SolidActor* carrier{nullptr};
|
||||
};
|
||||
|
||||
struct AdjacentActors {
|
||||
SolidActorManager* upper{nullptr};
|
||||
SolidActorManager* lower{nullptr};
|
||||
SolidActorManager* left{nullptr};
|
||||
SolidActorManager* right{nullptr};
|
||||
};
|
||||
|
||||
SolidActorManager() = default;
|
||||
~SolidActorManager() = default;
|
||||
|
||||
SolidActorManager(const SolidActorManager&) = delete;
|
||||
auto operator=(const SolidActorManager&) -> SolidActorManager& = delete;
|
||||
SolidActorManager(SolidActorManager&&) = delete;
|
||||
auto operator=(SolidActorManager&&) -> SolidActorManager& = delete;
|
||||
|
||||
// Registro de actores (el manager no es propietario)
|
||||
void registerActor(SolidActor* actor);
|
||||
void unregisterActor(SolidActor* actor);
|
||||
void clear();
|
||||
|
||||
// Cross-room: punteros a los managers de las rooms adyacentes
|
||||
void setAdjacent(const AdjacentActors& adjacent);
|
||||
void clearAdjacent();
|
||||
|
||||
// Sweeps del Player (paralelos a TileCollider). Todas las coordenadas
|
||||
// están en el sistema de la room actual (room-local pixel space).
|
||||
|
||||
/// Devuelve el x del borde derecho del primer actor bloqueante cuyo AABB
|
||||
/// esté "a la izquierda" del Player y solape su rect (px, py, pw, ph).
|
||||
/// Collision::NONE si no hay colisión.
|
||||
[[nodiscard]] auto checkWallLeft(float px, float py, float pw, float ph) const -> float;
|
||||
|
||||
/// Devuelve el x del borde izquierdo del primer actor bloqueante cuyo AABB
|
||||
/// esté "a la derecha" del Player y solape su rect. Collision::NONE si no.
|
||||
[[nodiscard]] auto checkWallRight(float px, float py, float pw, float ph) const -> float;
|
||||
|
||||
/// Devuelve el y del borde inferior del primer techo bloqueante que solape
|
||||
/// la parte superior del Player a (px, py, pw). Collision::NONE si no.
|
||||
[[nodiscard]] auto checkCeiling(float px, float py, float pw) const -> float;
|
||||
|
||||
/// Devuelve el suelo más cercano debajo de los pies del Player dentro del
|
||||
/// rango vertical [foot_y_cur, foot_y_new]. Los actores ONEWAY_TOP solo
|
||||
/// colisionan si foot_y_cur <= r.y (el Player venía desde arriba).
|
||||
/// Si el actor tiene CARRY_ON_TOP, FloorHit.carrier apunta a él.
|
||||
[[nodiscard]] auto checkFloor(float px, float foot_y_cur, float pw, float foot_y_new) const -> FloorHit;
|
||||
|
||||
/// Devuelve true si hay algún actor con top justo debajo de los pies
|
||||
/// (dentro de 1 px). Usado por checkFalling para no desengancharse de
|
||||
/// plataformas móviles.
|
||||
[[nodiscard]] auto hasGroundBelow(float px, float foot_y, float pw) const -> bool;
|
||||
|
||||
private:
|
||||
// Itera sobre todos los actores relevantes (locales + vecinos) aplicando
|
||||
// el offset correcto a los AABBs vecinos. La lambda recibe (actor, aabb_world).
|
||||
template <typename Fn>
|
||||
void forEachActor(Fn&& fn) const;
|
||||
|
||||
std::vector<SolidActor*> actors_;
|
||||
AdjacentActors adjacent_{};
|
||||
};
|
||||
Reference in New Issue
Block a user