72 lines
2.1 KiB
C++
72 lines
2.1 KiB
C++
// LineEffect.h - Line clearing visual and audio effects
|
|
#pragma once
|
|
#include <SDL3/SDL.h>
|
|
#include <vector>
|
|
#include <random>
|
|
|
|
class LineEffect {
|
|
public:
|
|
struct Particle {
|
|
float x, y;
|
|
float vx, vy;
|
|
float size;
|
|
float alpha;
|
|
SDL_Color color;
|
|
|
|
Particle(float px, float py);
|
|
void update();
|
|
void render(SDL_Renderer* renderer);
|
|
bool isAlive() const { return alpha > 0.0f; }
|
|
};
|
|
|
|
enum class AnimationState {
|
|
IDLE,
|
|
FLASH_WHITE,
|
|
EXPLODE_BLOCKS,
|
|
BLOCKS_DROP
|
|
};
|
|
|
|
LineEffect();
|
|
~LineEffect();
|
|
|
|
bool init(SDL_Renderer* renderer);
|
|
void shutdown();
|
|
|
|
// Start line clear effect for the specified rows
|
|
void startLineClear(const std::vector<int>& rows, int gridX, int gridY, int blockSize);
|
|
|
|
// Update and render the effect
|
|
bool update(float deltaTime); // Returns true if effect is complete
|
|
void render(SDL_Renderer* renderer, int gridX, int gridY, int blockSize);
|
|
|
|
// Audio
|
|
void playLineClearSound(int lineCount);
|
|
|
|
bool isActive() const { return state != AnimationState::IDLE; }
|
|
|
|
private:
|
|
SDL_Renderer* renderer{nullptr};
|
|
AnimationState state{AnimationState::IDLE};
|
|
float timer{0.0f};
|
|
std::vector<int> clearingRows;
|
|
std::vector<Particle> particles;
|
|
std::mt19937 rng{std::random_device{}()};
|
|
|
|
// Audio resources
|
|
SDL_AudioStream* audioStream{nullptr};
|
|
std::vector<int16_t> lineClearSample;
|
|
std::vector<int16_t> tetrisSample;
|
|
|
|
// Animation timing - Flash then immediate explosion effect
|
|
static constexpr float FLASH_DURATION = 0.12f; // Very brief white flash
|
|
static constexpr float EXPLODE_DURATION = 0.15f; // Quick explosive effect
|
|
static constexpr float DROP_DURATION = 0.05f; // Almost instant block drop
|
|
|
|
void createParticles(int row, int gridX, int gridY, int blockSize);
|
|
void updateParticles();
|
|
void renderFlash(int gridX, int gridY, int blockSize);
|
|
void renderExplosion();
|
|
bool loadAudioSample(const std::string& path, std::vector<int16_t>& sample);
|
|
void initAudio();
|
|
};
|