feat(player): clamp permet pujar al passadís + porta tancada bloqueja via Map::collides

This commit is contained in:
JailDesigner committed 2026-04-26 10:09:04 +02:00
1 parent 648a5932f8
commit 377e5d0b97
3 files changed
+37 -2

No files matched your search

+7
View File
@@ -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í
+18 -2
View File
@@ -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 {