refactor(player): mou height de jump a collision per coherència amb les entitats
This commit is contained in:
1 parent
64390f8ad7
commit
4758d5d8a4
4 files changed
+54
-35
No files matched your search
@@ -15,6 +15,11 @@ collision:
|
|||||||
# `size` es reserva per a la col·lisió amb murs/sarcòfags i per enfilar
|
# `size` es reserva per a la col·lisió amb murs/sarcòfags i per enfilar
|
||||||
# els passadissos. Centrada en el mateix punt que la caixa base.
|
# els passadissos. Centrada en el mateix punt que la caixa base.
|
||||||
hit_size: 8
|
hit_size: 8
|
||||||
|
# Alçada del cos en píxels per al filtre de col·lisió per altura: un
|
||||||
|
# actor saltant amb jump_z > height passa per damunt sense col·lisió.
|
||||||
|
# Mateix camp i semàntica que als YAML d'entitats (mummy, rolling_rock,
|
||||||
|
# etc.) — així el filtre queda uniforme per a tots els colls·lisionables.
|
||||||
|
height: 24
|
||||||
|
|
||||||
# Animacions en mapa (clau = nom). Camps per animació:
|
# Animacions en mapa (clau = nom). Camps per animació:
|
||||||
# frames → llista d'índexs dins de l'spritesheet.
|
# frames → llista d'índexs dins de l'spritesheet.
|
||||||
@@ -73,12 +78,10 @@ turn:
|
|||||||
# gravity → acceleració descendent constant (px/s²).
|
# gravity → acceleració descendent constant (px/s²).
|
||||||
# landing_stun_ms → temps en què el jugador queda paralitzat en aterrar
|
# landing_stun_ms → temps en què el jugador queda paralitzat en aterrar
|
||||||
# (no es pot moure ni tornar a saltar).
|
# (no es pot moure ni tornar a saltar).
|
||||||
# height → alçada del cos del jugador en píxels. S'usa per al
|
# L'alçada del cos viu al bloc `collision:` (`height`), igual que la resta
|
||||||
# filtratge de col·lisions per altura: un jugador
|
# d'entitats: és una propietat de col·lisió, no de la física del salt.
|
||||||
# saltant per damunt d'aquest valor no col·lisiona.
|
|
||||||
# Amb impulse=240 i gravity=600: pic ≈ 48 px, temps total en l'aire ≈ 0.8 s.
|
# Amb impulse=240 i gravity=600: pic ≈ 48 px, temps total en l'aire ≈ 0.8 s.
|
||||||
jump:
|
jump:
|
||||||
impulse: 240
|
impulse: 240
|
||||||
gravity: 600
|
gravity: 600
|
||||||
landing_stun_ms: 200
|
landing_stun_ms: 200
|
||||||
height: 24
|
|
||||||
@@ -15,6 +15,11 @@ collision:
|
|||||||
# `size` es reserva per a la col·lisió amb murs/sarcòfags i per enfilar
|
# `size` es reserva per a la col·lisió amb murs/sarcòfags i per enfilar
|
||||||
# els passadissos. Centrada en el mateix punt que la caixa base.
|
# els passadissos. Centrada en el mateix punt que la caixa base.
|
||||||
hit_size: 8
|
hit_size: 8
|
||||||
|
# Alçada del cos en píxels per al filtre de col·lisió per altura: un
|
||||||
|
# actor saltant amb jump_z > height passa per damunt sense col·lisió.
|
||||||
|
# Mateix camp i semàntica que als YAML d'entitats (mummy, rolling_rock,
|
||||||
|
# etc.) — així el filtre queda uniforme per a tots els colls·lisionables.
|
||||||
|
height: 24
|
||||||
|
|
||||||
# Animacions en mapa (clau = nom). Camps per animació:
|
# Animacions en mapa (clau = nom). Camps per animació:
|
||||||
# frames → llista d'índexs dins de l'spritesheet.
|
# frames → llista d'índexs dins de l'spritesheet.
|
||||||
@@ -73,12 +78,10 @@ turn:
|
|||||||
# gravity → acceleració descendent constant (px/s²).
|
# gravity → acceleració descendent constant (px/s²).
|
||||||
# landing_stun_ms → temps en què el jugador queda paralitzat en aterrar
|
# landing_stun_ms → temps en què el jugador queda paralitzat en aterrar
|
||||||
# (no es pot moure ni tornar a saltar).
|
# (no es pot moure ni tornar a saltar).
|
||||||
# height → alçada del cos del jugador en píxels. S'usa per al
|
# L'alçada del cos viu al bloc `collision:` (`height`), igual que la resta
|
||||||
# filtratge de col·lisions per altura: un jugador
|
# d'entitats: és una propietat de col·lisió, no de la física del salt.
|
||||||
# saltant per damunt d'aquest valor no col·lisiona.
|
|
||||||
# Amb impulse=240 i gravity=600: pic ≈ 48 px, temps total en l'aire ≈ 0.8 s.
|
# Amb impulse=240 i gravity=600: pic ≈ 48 px, temps total en l'aire ≈ 0.8 s.
|
||||||
jump:
|
jump:
|
||||||
impulse: 240
|
impulse: 240
|
||||||
gravity: 600
|
gravity: 600
|
||||||
landing_stun_ms: 200
|
landing_stun_ms: 200
|
||||||
height: 24
|
|
||||||
@@ -77,28 +77,7 @@ void Player::loadFrom(const std::string& yaml_path) {
|
|||||||
|
|
||||||
readSpriteSize(yaml, yaml_path, sprite_w, sprite_h);
|
readSpriteSize(yaml, yaml_path, sprite_w, sprite_h);
|
||||||
|
|
||||||
if (!yaml.contains("collision")) {
|
readCollisionBlock(yaml, yaml_path);
|
||||||
throw std::runtime_error("Player: manca bloc `collision:` a " + yaml_path);
|
|
||||||
}
|
|
||||||
const auto& c = yaml["collision"];
|
|
||||||
collision_size = c["size"].get_value<int>();
|
|
||||||
base_size = c["base_size"].get_value<int>();
|
|
||||||
|
|
||||||
// Col·lisió centrada en el quadrat inferior del sprite. Si la caixa és
|
|
||||||
// més gran que la base (cas habitual, 16 vs 12) el padding és simètric
|
|
||||||
// a cada costat; si són iguals, padding=0 i la caixa coincideix amb la
|
|
||||||
// base sense offsets.
|
|
||||||
collision_padding = (collision_size - base_size) / 2;
|
|
||||||
collision_x_offset = -collision_padding;
|
|
||||||
collision_y_offset = (sprite_h - base_size) - collision_padding;
|
|
||||||
|
|
||||||
// Hit-box opcional (actor-actor). Si no hi és, s'iguala a la base
|
|
||||||
// per preservar compatibilitat amb YAMLs antics. Concèntrica amb la
|
|
||||||
// caixa de col·lisió: offset interior = (collision_size - hit_size) / 2.
|
|
||||||
hit_size = c.contains("hit_size") ? c["hit_size"].get_value<int>() : collision_size;
|
|
||||||
const int HIT_INSET = (collision_size - hit_size) / 2;
|
|
||||||
hit_x_offset = collision_x_offset + HIT_INSET;
|
|
||||||
hit_y_offset = collision_y_offset + HIT_INSET;
|
|
||||||
|
|
||||||
// Bloc opcional `inertia:` — si manca, `brake_time_ms` queda a 0 i
|
// Bloc opcional `inertia:` — si manca, `brake_time_ms` queda a 0 i
|
||||||
// la inèrcia de frenada no s'activa (parada instantània com abans).
|
// la inèrcia de frenada no s'activa (parada instantània com abans).
|
||||||
@@ -130,15 +109,43 @@ void Player::loadFrom(const std::string& yaml_path) {
|
|||||||
readJumpBlock(yaml);
|
readJumpBlock(yaml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::readCollisionBlock(const fkyaml::node& yaml, const std::string& yaml_path) {
|
||||||
|
if (!yaml.contains("collision")) {
|
||||||
|
throw std::runtime_error("Player: manca bloc `collision:` a " + yaml_path);
|
||||||
|
}
|
||||||
|
const auto& c = yaml["collision"];
|
||||||
|
collision_size = c["size"].get_value<int>();
|
||||||
|
base_size = c["base_size"].get_value<int>();
|
||||||
|
|
||||||
|
// Col·lisió centrada en el quadrat inferior del sprite. Si la caixa és
|
||||||
|
// més gran que la base (cas habitual, 16 vs 12) el padding és simètric
|
||||||
|
// a cada costat; si són iguals, padding=0 i la caixa coincideix amb la
|
||||||
|
// base sense offsets.
|
||||||
|
collision_padding = (collision_size - base_size) / 2;
|
||||||
|
collision_x_offset = -collision_padding;
|
||||||
|
collision_y_offset = (sprite_h - base_size) - collision_padding;
|
||||||
|
|
||||||
|
// Hit-box opcional (actor-actor). Si no hi és, s'iguala a la base
|
||||||
|
// per preservar compatibilitat amb YAMLs antics. Concèntrica amb la
|
||||||
|
// caixa de col·lisió: offset interior = (collision_size - hit_size) / 2.
|
||||||
|
hit_size = c.contains("hit_size") ? c["hit_size"].get_value<int>() : collision_size;
|
||||||
|
const int HIT_INSET = (collision_size - hit_size) / 2;
|
||||||
|
hit_x_offset = collision_x_offset + HIT_INSET;
|
||||||
|
hit_y_offset = collision_y_offset + HIT_INSET;
|
||||||
|
|
||||||
|
// Alçada del cos, llegida del mateix bloc per coherència amb la
|
||||||
|
// resta d'entitats (mummy, sarcophagus, etc.). 0 = sense filtre per
|
||||||
|
// altura — el salt no esquiva l'altre jugador.
|
||||||
|
body_height = c.contains("height") ? c["height"].get_value<int>() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::readJumpBlock(const fkyaml::node& yaml) {
|
void Player::readJumpBlock(const fkyaml::node& yaml) {
|
||||||
jump_config = JumpConfig{};
|
jump_config = JumpConfig{};
|
||||||
body_height = 0;
|
|
||||||
if (!yaml.contains("jump")) { return; }
|
if (!yaml.contains("jump")) { return; }
|
||||||
const auto& j = yaml["jump"];
|
const auto& j = yaml["jump"];
|
||||||
if (j.contains("impulse")) { jump_config.impulse_px_per_s = j["impulse"].get_value<float>(); }
|
if (j.contains("impulse")) { jump_config.impulse_px_per_s = j["impulse"].get_value<float>(); }
|
||||||
if (j.contains("gravity")) { jump_config.gravity_px_per_s2 = j["gravity"].get_value<float>(); }
|
if (j.contains("gravity")) { jump_config.gravity_px_per_s2 = j["gravity"].get_value<float>(); }
|
||||||
if (j.contains("landing_stun_ms")) { jump_config.landing_stun_ms = j["landing_stun_ms"].get_value<int>(); }
|
if (j.contains("landing_stun_ms")) { jump_config.landing_stun_ms = j["landing_stun_ms"].get_value<int>(); }
|
||||||
if (j.contains("height")) { body_height = j["height"].get_value<int>(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::applyCardinal(Cardinal c) {
|
void Player::applyCardinal(Cardinal c) {
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ class Player : public AnimatedSprite {
|
|||||||
inline static int hit_x_offset = 0;
|
inline static int hit_x_offset = 0;
|
||||||
inline static int hit_y_offset = 0;
|
inline static int hit_y_offset = 0;
|
||||||
|
|
||||||
// Alçada del cos del jugador en píxels (camp `jump.height` del YAML).
|
// Alçada del cos del jugador en píxels (camp `collision.height` del
|
||||||
|
// YAML, mateixa convenció que entitats com mummy o rolling_rock).
|
||||||
// L'usen els filtres de col·lisió per altura: si un altre actor ens
|
// L'usen els filtres de col·lisió per altura: si un altre actor ens
|
||||||
// creua mentre `jump_z_` és superior a aquest valor, no col·lisionem.
|
// creua mentre `jump_z_` és superior a aquest valor, no col·lisionem.
|
||||||
inline static int body_height = 0;
|
inline static int body_height = 0;
|
||||||
@@ -370,8 +371,13 @@ class Player : public AnimatedSprite {
|
|||||||
};
|
};
|
||||||
static JumpConfig jump_config;
|
static JumpConfig jump_config;
|
||||||
|
|
||||||
// Llig el bloc `jump:` del YAML i n'omple `jump_config` + `body_height`.
|
// Llig el bloc `collision:` del YAML i n'omple les caixes (size/base/
|
||||||
// Membre estàtic perquè accedeixi als estàtics privats sense exposar-los.
|
// hit) + `body_height`. Llança si el bloc no existeix. Membre estàtic
|
||||||
|
// per accedir als estàtics privats sense exposar-los.
|
||||||
|
static void readCollisionBlock(const fkyaml::node& yaml, const std::string& yaml_path);
|
||||||
|
|
||||||
|
// Llig el bloc `jump:` del YAML i n'omple `jump_config`. Si el bloc
|
||||||
|
// manca, deixa la mecànica del salt desactivada.
|
||||||
static void readJumpBlock(const fkyaml::node& yaml);
|
static void readJumpBlock(const fkyaml::node& yaml);
|
||||||
|
|
||||||
// Estat de la màquina d'estats. Mutat per `tick`/`applyMovement`. Per
|
// Estat de la màquina d'estats. Mutat per `tick`/`applyMovement`. Per
|
||||||
|
|||||||
Reference in new issue
Block a user