feat(whip): separa draw_rect i damage_rect; sprites 80×32 / 16×96; feet_y delegat a l'owner; recover_* per al cooldown
This commit is contained in:
1 parent
121558b1fd
commit
8f66961c7b
15 files changed
+353
-127
No files matched your search
@@ -660,47 +660,36 @@ void Player::enterAttacking(Cardinal facing) {
|
||||
// p.ex. just després d'un canvi d'input).
|
||||
applyCardinal(facing);
|
||||
|
||||
// Geometria de spawn de la hitbox: alineada al rectangle de
|
||||
// col·lisió del jugador, no al sprite (que té perspectiva falsa amb
|
||||
// el cap dalt). La hitbox és `range_px × tile_size` (E/W) o
|
||||
// `tile_size × range_px` (N/S); el GameScene la consumeix per
|
||||
// crear el WhipAttack amb la mida adequada per direcció.
|
||||
const auto BOX = getBaseBox();
|
||||
const float RANGE_PX = whip_config.range_tiles * static_cast<float>(Map::tile_size);
|
||||
float spawn_x = 0.0F;
|
||||
float spawn_y = 0.0F;
|
||||
if (facing == Cardinal::NONE) { return; }
|
||||
|
||||
// Mapa de Cardinal → int al payload (vegeu `WhipSpawnPayload`).
|
||||
int dir_int = 0;
|
||||
switch (facing) {
|
||||
case Cardinal::EAST:
|
||||
spawn_x = BOX.x + BOX.w;
|
||||
spawn_y = BOX.y;
|
||||
dir_int = 3;
|
||||
break;
|
||||
case Cardinal::WEST:
|
||||
spawn_x = BOX.x - RANGE_PX;
|
||||
spawn_y = BOX.y;
|
||||
dir_int = 4;
|
||||
break;
|
||||
case Cardinal::NORTH:
|
||||
spawn_x = BOX.x;
|
||||
spawn_y = BOX.y - RANGE_PX;
|
||||
dir_int = 1;
|
||||
break;
|
||||
case Cardinal::SOUTH:
|
||||
spawn_x = BOX.x;
|
||||
spawn_y = BOX.y + BOX.h;
|
||||
dir_int = 2;
|
||||
break;
|
||||
case Cardinal::EAST:
|
||||
dir_int = 3;
|
||||
break;
|
||||
case Cardinal::WEST:
|
||||
dir_int = 4;
|
||||
break;
|
||||
case Cardinal::NONE:
|
||||
return;
|
||||
}
|
||||
|
||||
// Passem el pixel_rect (16×32 a sam/morcus) al payload; el WhipAttack
|
||||
// en deriva tant la draw_rect (sprite del látigo, més gran) com la
|
||||
// damage_rect (al nivell dels peus, retallada per bloquejadors).
|
||||
if (bus_ != nullptr) {
|
||||
const float RANGE_PX = whip_config.range_tiles * static_cast<float>(Map::tile_size);
|
||||
bus_->publish("whip_spawn", WhipSpawnPayload{
|
||||
.owner = this,
|
||||
.direction = dir_int,
|
||||
.spawn_x = spawn_x,
|
||||
.spawn_y = spawn_y,
|
||||
.owner_box = getPosition(),
|
||||
.range_px = RANGE_PX,
|
||||
});
|
||||
}
|
||||
@@ -1141,8 +1130,12 @@ auto Player::animationName(bool moving) const -> const char* {
|
||||
}
|
||||
// ATTACKING té dues sub-fases: durant `swing_ms` el sprite és
|
||||
// `attack_*` (animació del braç llançant el látigo); durant
|
||||
// `cooldown_ms` posterior tornem al `stand_*` de la direcció. Fem
|
||||
// la decisió comparant el remaining_ms_ amb el cooldown configurat.
|
||||
// `cooldown_ms` posterior canviem a `recover_*` per a frames
|
||||
// pròpis de recuperació. Mentre l'art no estiga dibuixat, els
|
||||
// YAMLs apunten `recover_*` als mateixos frames que `stand_*` —
|
||||
// visualment és idèntic, però la separació deixa l'arquitectura
|
||||
// preparada perquè en afegir frames reals només calga tocar el
|
||||
// YAML, no el codi.
|
||||
if (state_ == State::ATTACKING) {
|
||||
const bool IN_SWING = (attacking_remaining_ms_ > static_cast<float>(whip_config.cooldown_ms));
|
||||
if (IN_SWING) {
|
||||
@@ -1158,13 +1151,13 @@ auto Player::animationName(bool moving) const -> const char* {
|
||||
}
|
||||
switch (facing_) {
|
||||
case Facing::UP:
|
||||
return "stand_up";
|
||||
return "recover_up";
|
||||
case Facing::DOWN:
|
||||
return "stand_down";
|
||||
return "recover_down";
|
||||
case Facing::SIDE:
|
||||
break;
|
||||
}
|
||||
return "stand";
|
||||
return "recover";
|
||||
}
|
||||
switch (facing_) {
|
||||
case Facing::UP:
|
||||
|
||||
Reference in new issue
Block a user