fix(lighting): llig flicker tambe del YAML del jugador

This commit is contained in:
JailDesigner committed 2026-05-12 22:26:17 +02:00
1 parent fc9947b87f
commit 0046d526b0
3 files changed
+24 -10

No files matched your search

+11 -6
View File
@@ -142,13 +142,18 @@ void Player::loadFrom(const std::string& yaml_path) {
// desactivada i els hazards toquen al primer frame, com abans.
readImmunityBlock(yaml);
// Bloc opcional `light: { radius: N }` — radi en píxels del cercle
// de llum emès pel jugador. 0 = no emet. La forma del gradient és
// global (data/config/lighting.yaml), no per jugador.
// Bloc opcional `light:` — radi i flicker. Extret a un mètode per
// mantenir `loadFrom` sota el llindar de complexitat de clang-tidy.
readLightBlock(yaml);
}
void Player::readLightBlock(const fkyaml::node& yaml) {
light_radius = 0;
if (yaml.contains("light") && yaml["light"].contains("radius")) {
light_radius = yaml["light"]["radius"].get_value<int>();
}
light_flicker = false;
if (!yaml.contains("light")) { return; }
const auto& l = yaml["light"];
if (l.contains("radius")) { light_radius = l["radius"].get_value<int>(); }
if (l.contains("flicker")) { light_flicker = l["flicker"].get_value<bool>(); }
}
void Player::readCollisionBlock(const fkyaml::node& yaml, const std::string& yaml_path) {
+11 -3
View File
@@ -125,10 +125,12 @@ class Player : public AnimatedSprite {
inline static int body_height = 0;
// Radi de la llum emesa pel jugador (en píxels del canvas), llegit
// del bloc opcional `light: { radius: N }` del YAML. 0 = no emet.
// Es declara estàtic com la resta de configs del jugador (immunity,
// jump, ...): tots els jugadors del mateix YAML comparteixen el valor.
// del bloc opcional `light: { radius: N, flicker: bool }` del YAML.
// 0 = no emet. Es declara estàtic com la resta de configs del jugador
// (immunity, jump, ...): tots els jugadors del mateix YAML comparteixen
// el valor. `light_flicker` activa la modulació "tipus foc" del radi.
inline static int light_radius = 0;
inline static bool light_flicker = false;
// Ha de cridar-se abans d'instanciar Player; GameScene ho fa al ctor.
static void loadFrom(const std::string& yaml_path);
@@ -143,6 +145,7 @@ class Player : public AnimatedSprite {
// sprite es dibuixa amb `pos_.y - jump_z_`, i la llum ha de seguir-lo
// per a que el cercle "salti" amb el jugador, no es quedi al sòl.
[[nodiscard]] static auto getLightRadius() -> int { return light_radius; }
[[nodiscard]] static auto getLightFlicker() -> bool { return light_flicker; }
[[nodiscard]] auto getLightCenter() const -> SDL_FPoint;
Player(const std::string& anim_key, int id, float x, float y, const Controls& controls, const Map::Info& map_info, int paint_tile_index = -1);
@@ -755,6 +758,11 @@ class Player : public AnimatedSprite {
// readers — `loadFrom` el crida al final.
static void readImmunityBlock(const fkyaml::node& yaml);
// Llig el bloc opcional `light: { radius: N, flicker: bool }` del
// YAML i pobla `light_radius` / `light_flicker`. Si manca, els
// valors queden a 0 / false (jugador sense llum).
static void readLightBlock(const fkyaml::node& yaml);
// Activa l'estat ATTACKING en la direcció cardinal indicada (la
// direcció cap on mira el jugador) i publica `whip_spawn` al bus
// perquè el GameScene cree el `WhipAttack` corresponent. Posa el
+2 -1
View File
@@ -1018,10 +1018,11 @@ void GameScene::applyLightingPass() {
// `Lighting::apply` salta el cercle al filtre intern. No fem un
// gating extern aquí (els jugadors són només 1-2 actors i el cost
// d'afegir-los al vector és menyspreable).
const bool PLAYER_FLICKER = Player::getLightFlicker();
for (const auto& p : players_) {
if (p->isOutOfPlay()) { continue; }
const auto C = p->getLightCenter();
emitters.push_back({.cx = C.x, .cy = C.y, .radius = PLAYER_R, .flicker = false});
emitters.push_back({.cx = C.x, .cy = C.y, .radius = PLAYER_R, .flicker = PLAYER_FLICKER});
}
for (const auto* e : entity_manager_.getEntities()) {
const int R = e->getLightRadius();