hard drop shake effect added
This commit is contained in:
@ -1983,6 +1983,39 @@ void GameRenderer::renderCoopPlayingState(
|
|||||||
}
|
}
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
// Hard-drop impact shake (match classic feel)
|
||||||
|
float impactStrength = 0.0f;
|
||||||
|
float impactEased = 0.0f;
|
||||||
|
std::array<uint8_t, CoopGame::COLS * CoopGame::ROWS> impactMask{};
|
||||||
|
std::array<float, CoopGame::COLS * CoopGame::ROWS> impactWeight{};
|
||||||
|
if (game->hasHardDropShake()) {
|
||||||
|
impactStrength = static_cast<float>(game->hardDropShakeStrength());
|
||||||
|
impactStrength = std::clamp(impactStrength, 0.0f, 1.0f);
|
||||||
|
impactEased = impactStrength * impactStrength;
|
||||||
|
const auto& impactCells = game->getHardDropCells();
|
||||||
|
const auto& boardRef = game->boardRef();
|
||||||
|
for (const auto& cell : impactCells) {
|
||||||
|
if (cell.x < 0 || cell.x >= CoopGame::COLS || cell.y < 0 || cell.y >= CoopGame::ROWS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int idx = cell.y * CoopGame::COLS + cell.x;
|
||||||
|
impactMask[idx] = 1;
|
||||||
|
impactWeight[idx] = 1.0f;
|
||||||
|
|
||||||
|
int depth = 0;
|
||||||
|
for (int ny = cell.y + 1; ny < CoopGame::ROWS && depth < 4; ++ny) {
|
||||||
|
if (!boardRef[ny * CoopGame::COLS + cell.x].occupied) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++depth;
|
||||||
|
int nidx = ny * CoopGame::COLS + cell.x;
|
||||||
|
impactMask[nidx] = 1;
|
||||||
|
float weight = std::max(0.15f, 1.0f - depth * 0.35f);
|
||||||
|
impactWeight[nidx] = std::max(impactWeight[nidx], weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw settled blocks
|
// Draw settled blocks
|
||||||
const auto& board = game->boardRef();
|
const auto& board = game->boardRef();
|
||||||
for (int y = 0; y < CoopGame::ROWS; ++y) {
|
for (int y = 0; y < CoopGame::ROWS; ++y) {
|
||||||
@ -1992,6 +2025,18 @@ void GameRenderer::renderCoopPlayingState(
|
|||||||
if (!cell.occupied || cell.value <= 0) continue;
|
if (!cell.occupied || cell.value <= 0) continue;
|
||||||
float px = gridX + x * finalBlockSize;
|
float px = gridX + x * finalBlockSize;
|
||||||
float py = gridY + y * finalBlockSize + dropOffset;
|
float py = gridY + y * finalBlockSize + dropOffset;
|
||||||
|
|
||||||
|
const int cellIdx = y * CoopGame::COLS + x;
|
||||||
|
float weight = impactWeight[cellIdx];
|
||||||
|
if (impactStrength > 0.0f && weight > 0.0f && impactMask[cellIdx]) {
|
||||||
|
float cellSeed = static_cast<float>((x * 37 + y * 61) % 113);
|
||||||
|
float t = static_cast<float>(nowTicks % 10000) * 0.018f + cellSeed;
|
||||||
|
float amplitude = 6.0f * impactEased * weight;
|
||||||
|
float freq = 2.0f + weight * 1.3f;
|
||||||
|
px += amplitude * std::sin(t * freq);
|
||||||
|
py += amplitude * 0.75f * std::cos(t * (freq + 1.1f));
|
||||||
|
}
|
||||||
|
|
||||||
drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, cell.value - 1);
|
drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, cell.value - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user