feat(player): clamp permet pujar al passadís + porta tancada bloqueja via Map::collides
This commit is contained in:
1 parent
648a5932f8
commit
377e5d0b97
3 files changed
+37
-2
No files matched your search
@@ -6,6 +6,7 @@
|
||||
#include "game/entities/entity_factory.hpp"
|
||||
#include "game/entities/event_bus.hpp"
|
||||
#include "game/entities/player.hpp"
|
||||
#include "game/map/map.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -80,6 +81,12 @@ void Door::open() {
|
||||
if (state_ != State::CLOSED) { return; }
|
||||
state_ = State::OPENING;
|
||||
setAnimation(anim_opening_);
|
||||
// Marquem el passadís com a transitable: a partir d'aquest tic
|
||||
// `Map::collides` deixa de bloquejar el rect del passadís. La
|
||||
// transició d'animació OPENING → OPEN encara dura el seu temps,
|
||||
// però la geometria ja és permeable — coherent amb el feel de
|
||||
// "la porta s'obri i el jugador pot avançar al moment".
|
||||
Map::door_open = true;
|
||||
// Edge case: si `opening` té ≤1 frame i és loop=true, mai es
|
||||
// completarà. Per força, forcem loop=false del frame únic aquí. Els
|
||||
// placeholders defineixen `loop: false` explícitament al YAML, així
|
||||
|
||||
@@ -987,11 +987,27 @@ void Player::clampToPlayfield() {
|
||||
const auto MIN_X = static_cast<float>(map_.playfield_x - collision_x_offset);
|
||||
const auto MAX_X = static_cast<float>(
|
||||
map_.playfield_x + map_.playfield_w - collision_x_offset - collision_size);
|
||||
const auto MIN_Y = static_cast<float>(map_.playfield_y - collision_y_offset);
|
||||
auto min_y = static_cast<float>(map_.playfield_y - collision_y_offset);
|
||||
const auto MAX_Y = static_cast<float>(
|
||||
map_.playfield_y + map_.playfield_h - collision_y_offset - collision_size);
|
||||
|
||||
// Passadís de sortida: si la base box queda enterament dins del rang
|
||||
// X del passadís de la porta, deixem que pugi al strip del mur trasser
|
||||
// (fins a `door_corridor.y`). Fora del rang, MIN_Y es queda al
|
||||
// playfield. La regla "enterament dins" exigeix alinear-se al passadís
|
||||
// abans de pujar — la base box (12 px) hi cap amb 4 px de marge.
|
||||
if (map_.door_corridor_w > 0) {
|
||||
const float BASE_X = getPosX() + static_cast<float>(collision_x_offset);
|
||||
const float BASE_RIGHT = BASE_X + static_cast<float>(collision_size);
|
||||
const auto CORRIDOR_LEFT = static_cast<float>(map_.door_corridor_x);
|
||||
const auto CORRIDOR_RIGHT = static_cast<float>(map_.door_corridor_x + map_.door_corridor_w);
|
||||
if (BASE_X >= CORRIDOR_LEFT && BASE_RIGHT <= CORRIDOR_RIGHT) {
|
||||
min_y = static_cast<float>(map_.door_corridor_y - collision_y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
setPosX(std::clamp(getPosX(), MIN_X, MAX_X));
|
||||
setPosY(std::clamp(getPosY(), MIN_Y, MAX_Y));
|
||||
setPosY(std::clamp(getPosY(), min_y, MAX_Y));
|
||||
}
|
||||
|
||||
auto Player::getBaseBox() const -> SDL_FRect {
|
||||
|
||||
Reference in new issue
Block a user