feat(game_scene): wire lighting pass entre actors i HUD

This commit is contained in:
JailDesigner committed 2026-05-12 21:12:06 +02:00
1 parent ebb161f1f5
commit d1d5679d14
2 files changed
+44

No files matched your search

+37
View File
@@ -16,6 +16,7 @@
#include "core/input/global_inputs.hpp"
#include "core/input/key_config.hpp"
#include "core/locale/locale.hpp"
#include "core/rendering/lighting.hpp"
#include "core/rendering/notifier.hpp"
#include "core/rendering/render_info.hpp"
#include "core/rendering/screen.hpp"
@@ -1005,6 +1006,36 @@ void GameScene::updateRoomTransition(int delta_ms) {
}
}
void GameScene::applyLightingPass() {
// Atajo: si la sala està totalment il·luminada i ningú emet,
// `Lighting::apply` ja s'autosalta amb les mateixes condicions.
// Recollim igualment perquè el cas comú durant el desenvolupament
// serà tocar `Map::light_level` per sales concretes.
std::vector<Lighting::Emitter> emitters;
emitters.reserve(players_.size() + entity_manager_.entityCount());
const int PLAYER_R = Player::getLightRadius();
// Quan el YAML del jugador no declara `light:`, `PLAYER_R` és 0 i
// `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).
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});
}
for (const auto* e : entity_manager_.getEntities()) {
const int R = e->getLightRadius();
if (R <= 0) { continue; }
const auto C = e->getLightCenter();
emitters.push_back({.cx = C.x, .cy = C.y, .radius = R});
}
Lighting::apply(Screen::get().getCanvasArgb(),
Screen::get().getCanvasWidth(),
Screen::get().getCanvasHeight(),
Map::light_level,
emitters);
}
void GameScene::renderRoomFade() {
// Delegació als FadeToBlack: les durades, la direcció i el progrés
// viuen dins de cada instància. Comportament:
@@ -1708,6 +1739,12 @@ void GameScene::render() {
}
}
// Pasada d'il·luminació: oscureix el canvas segons `Map::light_level`
// i hi obre cercles brillants al voltant dels emissors (jugadors,
// antorxes, mòmies, ...). Va abans del fade i del HUD perquè el
// fade pinta negre encima i la UI ha de quedar llegible.
applyLightingPass();
// Fade del món: pintat ENTRE actors i HUD perquè el marcador, les
// notificacions i el service menu queden per damunt sense afectar-se.
// Inactiu si l'estat és PLAYING.
+7
View File
@@ -271,6 +271,13 @@ class GameScene : public Scene {
void renderRoomFade();
void renderRoomText();
// Pasada d'il·luminació CPU sobre el canvas, entre els actors i el
// HUD: recull els emissors actius (jugadors + entitats amb
// `light_radius>0`) i aplica el gradient amb `Map::light_level`
// com a llum de sala. El HUD/notificacions queden fora de la
// multiplicació perquè es pinten després.
void applyLightingPass();
// Configuració, estat i transició de la sub-FSM de game over
// (CONTINUE? + GAME OVER). Lligada al mateix `game.yaml` que la
// RoomFsm via `GameOverFsm::loadConfig`.