#pragma once #include #include // Para shared_ptr #include "core/rendering/sprites/animated_sprite.hpp" // Para AnimatedSprite class Surface; // Direcció de la dissolució enum class DissolveDirection { NONE, DOWN, UP }; // Sprite que pot dissoldre's o generar-se de forma aleatòria en X mil·lisegons. // progress_ va de 0.0 (totalment visible) a 1.0 (totalment invisible). class DissolveSprite : public AnimatedSprite { public: explicit DissolveSprite(const AnimationResource& data); DissolveSprite(std::shared_ptr surface, SDL_FRect pos); ~DissolveSprite() override = default; void update(float delta_time) override; void render() override; // Progrés manual [0.0 = totalment visible, 1.0 = totalment invisible] void setProgress(float progress); [[nodiscard]] auto getProgress() const -> float { return progress_; } // Inicia una dissolució temporal (visible → invisible en duration_ms) void startDissolve(float duration_ms, DissolveDirection dir = DissolveDirection::NONE); // Inicia una generació temporal (invisible → visible en duration_ms) void startGenerate(float duration_ms, DissolveDirection dir = DissolveDirection::NONE); void stopTransition(); [[nodiscard]] auto isTransitionDone() const -> bool; // Substitució de color: en reconstruir, substitueix source per target void setColorReplace(Uint8 source, Uint8 target); private: enum class TransitionMode { NONE, DISSOLVING, GENERATING }; std::shared_ptr surface_display_; // Superfície amb els píxels filtrats float progress_{0.0F}; // [0=visible, 1=invisible] DissolveDirection direction_{DissolveDirection::NONE}; TransitionMode transition_mode_{TransitionMode::NONE}; float transition_duration_{0.0F}; float transition_elapsed_{0.0F}; SDL_FRect prev_clip_{.x = 0, .y = 0, .w = 0, .h = 0}; bool needs_rebuild_{false}; Uint8 source_color_{255}; // 255 = transparent = sense replace per defecte Uint8 target_color_{0}; void rebuildDisplaySurface(); [[nodiscard]] static auto computePixelRank(int col, int row, int frame_h, DissolveDirection dir) -> float; };