feat(lighting): seed estable per emissor (no deriva pel moviment)
This commit is contained in:
1 parent
0046d526b0
commit
5cc8e349a5
5 files changed
+35
-15
No files matched your search
@@ -266,6 +266,14 @@ class Entity {
|
||||
[[nodiscard]] auto getLightFlicker() const -> bool { return light_flicker_; }
|
||||
void setLightFlicker(bool f) { light_flicker_ = f; }
|
||||
|
||||
// Identificador estable per al flicker. Cada Entity rep un valor
|
||||
// únic a la construcció (contador estàtic) i el conserva fins a la
|
||||
// mort — així el patró del flicker no "deriva" quan l'entitat es
|
||||
// mou. Si l'entitat respawneja, la nova instància tindrà una seed
|
||||
// nova; com que el cicle visual ja queda trencat per la mort, no és
|
||||
// un problema.
|
||||
[[nodiscard]] auto getLightSeed() const -> int { return light_seed_; }
|
||||
|
||||
// Centre de la llum en píxels del canvas. Per defecte és el centre del
|
||||
// `pixel_rect_` (que és la caixa de render: sprite top-left + mida).
|
||||
// Virtual perquè entitats amb desplaçament visual sobre la posició
|
||||
@@ -287,6 +295,12 @@ class Entity {
|
||||
bool blocks_movement_{false};
|
||||
int height_{0};
|
||||
int light_radius_{0};
|
||||
// Comptador global d'instàncies; cada Entity nova s'emporta el
|
||||
// valor incrementat com a seed propi. Estàtic perquè no calgui
|
||||
// estat extern (sense risc de threads: les entitats es construeixen
|
||||
// sempre des del fil del joc).
|
||||
static inline int s_next_light_seed{0};
|
||||
int light_seed_{++s_next_light_seed};
|
||||
bool light_flicker_{false};
|
||||
bool dead_{false};
|
||||
SDL_FlipMode flip_{SDL_FLIP_NONE};
|
||||
|
||||
@@ -146,6 +146,11 @@ class Player : public AnimatedSprite {
|
||||
// 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; }
|
||||
// Seed estable per al flicker: reusem `id_` (0 o 1 en multijugador
|
||||
// local) amb un offset gran per evitar col·lisions amb el contador
|
||||
// d'Entity (que arrenca des de 1). Així P1 i P2 oscil·len en fases
|
||||
// pròpies que no s'encavalquen amb cap entitat.
|
||||
[[nodiscard]] auto getLightSeed() const -> int { return id_ + 1000; }
|
||||
[[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);
|
||||
|
||||
@@ -1022,13 +1022,13 @@ void GameScene::applyLightingPass() {
|
||||
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 = PLAYER_FLICKER});
|
||||
emitters.push_back({.cx = C.x, .cy = C.y, .radius = PLAYER_R, .seed = p->getLightSeed(), .flicker = PLAYER_FLICKER});
|
||||
}
|
||||
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, .flicker = e->getLightFlicker()});
|
||||
emitters.push_back({.cx = C.x, .cy = C.y, .radius = R, .seed = e->getLightSeed(), .flicker = e->getLightFlicker()});
|
||||
}
|
||||
Lighting::apply(Screen::get().getCanvasArgb(),
|
||||
Screen::get().getCanvasWidth(),
|
||||
|
||||
Reference in new issue
Block a user