diff --git a/src/include/Tetris.h b/src/include/Tetris.h index 5715c3f..3c750e3 100644 --- a/src/include/Tetris.h +++ b/src/include/Tetris.h @@ -169,6 +169,7 @@ struct ParticleEffect int boardY; int velocityX; int velocityY; + int size; COLORREF color; }; @@ -211,7 +212,7 @@ extern UpgradeUiState upgradeUiState; extern FeedbackState feedbackState; extern ClearEffectState clearEffectState; extern FloatingTextEffect floatingTextEffects[8]; -extern ParticleEffect particleEffects[24]; +extern ParticleEffect particleEffects[96]; extern int currentScreen; extern int currentMode; extern int currentFallInterval; diff --git a/src/source/TetrisLogic.cpp b/src/source/TetrisLogic.cpp index cf25aae..25113a5 100644 --- a/src/source/TetrisLogic.cpp +++ b/src/source/TetrisLogic.cpp @@ -19,7 +19,7 @@ UpgradeUiState upgradeUiState = { 0, 0, 0, 0, {} }; FeedbackState feedbackState = { 0, _T(""), _T("") }; ClearEffectState clearEffectState = { 0, 0, 0, {} }; FloatingTextEffect floatingTextEffects[8] = {}; -ParticleEffect particleEffects[24] = {}; +ParticleEffect particleEffects[96] = {}; int currentScreen = SCREEN_MENU; int currentMode = MODE_CLASSIC; int currentFallInterval = 500; @@ -253,7 +253,7 @@ void ResetVisualEffects() floatingTextEffects[i].ticks = 0; } - for (int i = 0; i < 24; i++) + for (int i = 0; i < 96; i++) { particleEffects[i].ticks = 0; } @@ -278,7 +278,7 @@ bool TickVisualEffects() } } - for (int i = 0; i < 24; i++) + for (int i = 0; i < 96; i++) { if (particleEffects[i].ticks > 0) { @@ -307,24 +307,85 @@ static void AddFloatingText(int boardX, int boardY, const TCHAR* text, COLORREF } } -static void AddParticle(int boardX, int boardY, COLORREF color) +static void AddParticle(int boardX, int boardY, int velocityX, int velocityY, int size, COLORREF color) { - for (int i = 0; i < 24; i++) + for (int i = 0; i < 96; i++) { if (particleEffects[i].ticks <= 0) { - particleEffects[i].ticks = 10 + rand() % 5; + particleEffects[i].ticks = 12 + rand() % 7; particleEffects[i].totalTicks = particleEffects[i].ticks; particleEffects[i].boardX = boardX; particleEffects[i].boardY = boardY; - particleEffects[i].velocityX = (rand() % 11) - 5; - particleEffects[i].velocityY = -8 + (rand() % 5); + particleEffects[i].velocityX = velocityX; + particleEffects[i].velocityY = velocityY; + particleEffects[i].size = size; particleEffects[i].color = color; return; } } } +static void AddBurstParticles(int boardX, int boardY, COLORREF baseColor, bool strongBurst) +{ + int burstCount = strongBurst ? 5 : 3; + for (int i = 0; i < burstCount; i++) + { + int angleSeed = rand() % 8; + int speed = strongBurst ? (9 + rand() % 9) : (6 + rand() % 7); + int velocityX = 0; + int velocityY = 0; + + switch (angleSeed) + { + case 0: + velocityX = speed; + velocityY = -rand() % 4; + break; + case 1: + velocityX = -speed; + velocityY = -rand() % 4; + break; + case 2: + velocityX = (rand() % 5) - 2; + velocityY = -speed; + break; + case 3: + velocityX = (rand() % 5) - 2; + velocityY = speed / 2; + break; + case 4: + velocityX = speed; + velocityY = -speed; + break; + case 5: + velocityX = -speed; + velocityY = -speed; + break; + case 6: + velocityX = speed; + velocityY = speed / 3; + break; + default: + velocityX = -speed; + velocityY = speed / 3; + break; + } + + velocityX += (rand() % 7) - 3; + velocityY += (rand() % 7) - 3; + + COLORREF color = (i % 3 == 0) ? RGB(255, 248, 220) : baseColor; + AddParticle( + boardX + (rand() % 31) - 15, + boardY + (rand() % 31) - 15, + velocityX, + velocityY, + strongBurst ? (4 + rand() % 5) : (3 + rand() % 4), + color); + } +} + void TriggerLineClearEffect(const int* rows, int rowCount, int linesCleared) { if (rows == nullptr || rowCount <= 0 || linesCleared <= 0) @@ -346,10 +407,23 @@ void TriggerLineClearEffect(const int* rows, int rowCount, int linesCleared) { clearEffectState.rows[i] = rows[i]; rowSum += rows[i]; - for (int x = 0; x < nGameWidth; x += 3) + for (int x = 0; x < nGameWidth; x++) { COLORREF particleColor = BrickColor[(x + rows[i]) % 7]; - AddParticle(x * 100 + 50, rows[i] * 100 + 50, particleColor); + int centerX = x * 100 + 50; + int centerY = rows[i] * 100 + 50; + AddBurstParticles(centerX, centerY, particleColor, linesCleared >= 4); + + if (linesCleared >= 4) + { + AddParticle( + centerX, + centerY, + ((x < nGameWidth / 2) ? -1 : 1) * (16 + rand() % 12), + -16 - rand() % 10, + 4 + rand() % 3, + RGB(255, 238, 120)); + } } } diff --git a/src/source/TetrisRender.cpp b/src/source/TetrisRender.cpp index f9843fd..db6708c 100644 --- a/src/source/TetrisRender.cpp +++ b/src/source/TetrisRender.cpp @@ -871,7 +871,7 @@ void TDrawScreen(HDC hdc, HWND hWnd) } } - for (int i = 0; i < 24; i++) + for (int i = 0; i < 96; i++) { if (particleEffects[i].ticks <= 0 || particleEffects[i].totalTicks <= 0) { @@ -879,9 +879,13 @@ void TDrawScreen(HDC hdc, HWND hWnd) } int elapsed = particleEffects[i].totalTicks - particleEffects[i].ticks; - int particleX = gameRect.left + particleEffects[i].boardX * grid / 100 + SS(particleEffects[i].velocityX * elapsed / 2); - int particleY = gameRect.top + particleEffects[i].boardY * grid / 100 + SS(particleEffects[i].velocityY * elapsed / 2 + elapsed * elapsed / 10); - int particleSize = SS(3 + (elapsed % 2)); + int particleX = gameRect.left + particleEffects[i].boardX * grid / 100 + SS(particleEffects[i].velocityX * elapsed); + int particleY = gameRect.top + particleEffects[i].boardY * grid / 100 + SS(particleEffects[i].velocityY * elapsed + elapsed * elapsed / 4); + int particleSize = SS(particleEffects[i].size * particleEffects[i].ticks / particleEffects[i].totalTicks); + if (particleSize < SS(2)) + { + particleSize = SS(2); + } RECT particleRect = {