#pragma once #include #include // Para shared_ptr #include // Para string #include #include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite #include "game/gameplay/room.hpp" #include "game/gameplay/tile_collider.hpp" // Para TileCollider::Tile #include "game/options.hpp" // Para Cheat, Options #include "utils/defines.hpp" // Para PlayArea, Tile, Flip struct JA_Sound_t; class Player { public: // --- Enums y Structs --- enum class State { ON_GROUND, ON_SLOPE, ON_AIR, }; enum class Direction { LEFT, RIGHT, UP, DOWN, NONE }; // --- Constantes de física --- static constexpr float HORIZONTAL_VELOCITY = 75.0F; static constexpr float HORIZONTAL_ACCEL = 500.0F; static constexpr float MAX_VY = 160.0F; static constexpr float JUMP_VELOCITY = -178.5F; static constexpr float GRAVITY_FORCE = 360.0F; static constexpr float LOW_JUMP_GRAVITY_MULT = 3.0F; struct SpawnData { float x = 0; float y = 0; float vx = 0; float vy = 0; int last_grounded_position = 0; State state = State::ON_GROUND; SDL_FlipMode flip = SDL_FLIP_NONE; }; struct Data { SpawnData spawn_data; std::string animations_path; std::shared_ptr room = nullptr; }; // --- Constructor y Destructor --- explicit Player(const Data& player); ~Player() = default; // --- Interfaz pública --- void render(); void update(float delta_time); [[nodiscard]] auto isOnBorder() const -> bool { return border_ != Room::Border::NONE; } [[nodiscard]] auto getBorder() const -> Room::Border { return border_; } void switchBorders(); auto getRect() -> SDL_FRect { return {.x = x_, .y = y_, .w = WIDTH, .h = HEIGHT}; } auto getCollider() -> SDL_FRect& { return collider_box_; } auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = sprite_->getFlip()}; } static auto skinToAnimationPath(const std::string& skin_name) -> std::string; void setRoom(std::shared_ptr room) { room_ = std::move(room); } void setAdjacentRoom(std::shared_ptr room, Room::Border direction); void clearAdjacentRoom(); [[nodiscard]] auto isAlive() const -> bool { return is_alive_; } [[nodiscard]] auto getVY() const -> float { return vy_; } void applyPlatformDisplacement(float dx, float surface_y); void clearPlatformFlag() { on_platform_ = false; } void setPaused(bool value) { is_paused_ = value; } void setIgnoreInput(bool value) { ignore_input_ = value; } [[nodiscard]] auto getIgnoreInput() const -> bool { return ignore_input_; } #ifdef _DEBUG void setDebugPosition(float x, float y); void finalizeDebugTeleport(); #endif private: // --- Constantes --- static constexpr int WIDTH = 12; static constexpr int HEIGHT = 24; // --- Contexto de colisión (selección de room + traducción de coordenadas) --- struct CollisionContext { const TileCollider& tc; float offset_x; float offset_y; }; auto getCollisionContext() const -> CollisionContext; // --- Objetos y punteros --- std::shared_ptr room_; std::shared_ptr adjacent_room_; Room::Border adjacent_direction_{Room::Border::NONE}; std::unique_ptr sprite_; // --- Posición y física --- float x_ = 0.0F; float y_ = 0.0F; float vx_ = 0.0F; float vy_ = 0.0F; Direction wanna_go_ = Direction::NONE; bool wanna_jump_ = false; bool wanna_down_ = false; bool jump_held_ = false; bool down_held_ = false; // --- Estado --- State state_ = State::ON_GROUND; State previous_state_ = State::ON_GROUND; // --- Colisión --- SDL_FRect collider_box_{}; int slope_tile_x_{0}; int slope_tile_y_{0}; TileCollider::Tile slope_type_{TileCollider::Tile::EMPTY}; // --- Variables de juego --- bool is_alive_ = true; bool is_paused_ = false; bool ignore_input_ = false; bool on_platform_ = false; bool turning_ = false; Direction facing_ = Direction::RIGHT; Room::Border border_ = Room::Border::TOP; int last_grounded_position_ = 0; // --- Renderizado y sonido --- JA_Sound_t* jump_sound_ = nullptr; JA_Sound_t* land_sound_ = nullptr; // --- Pipeline de update --- void handleInput(); void updateVelocity(float delta_time); void applyGravity(float delta_time); void handleJumpAndDrop(); void moveHorizontal(float delta_time); void moveVertical(float delta_time); void followSlope(); void exitSlope(); void detectSlopeEntry(); void checkFalling(); // --- Gestión de estado --- void transitionToState(State state); void startJump(); // --- Geometría y renderizado --- void syncSpriteAndCollider(); void placeSprite(); void animate(float delta_time); auto handleBorders() const -> Room::Border; // --- Inicialización --- void initSprite(const std::string& animations_path); void initSounds(); void applySpawnValues(const SpawnData& spawn); // --- Utilidad --- void markAsDead(); };