smooth scroll added

This commit is contained in:
2025-11-30 09:30:50 +01:00
parent 8279ccbe6d
commit 8b350bfb9e
6 changed files with 77 additions and 6 deletions

View File

@ -103,6 +103,24 @@ void Game::setPaused(bool p) {
paused = p;
}
void Game::setSoftDropping(bool on) {
if (softDropping == on) {
return;
}
double oldStep = softDropping ? (gravityMs / 5.0) : gravityMs;
softDropping = on;
double newStep = softDropping ? (gravityMs / 5.0) : gravityMs;
if (oldStep <= 0.0 || newStep <= 0.0) {
return;
}
double progress = fallAcc / oldStep;
progress = std::clamp(progress, 0.0, 1.0);
fallAcc = progress * newStep;
}
void Game::refillBag() {
bag.clear();
for (int i=0;i<PIECE_COUNT;++i) bag.push_back(static_cast<PieceType>(i));

View File

@ -28,7 +28,7 @@ public:
void tickGravity(double frameMs); // advance gravity accumulator & drop
void softDropBoost(double frameMs); // accelerate fall while held
void hardDrop(); // instant drop & lock
void setSoftDropping(bool on) { softDropping = on; } // mark if player holds Down
void setSoftDropping(bool on); // mark if player holds Down
void move(int dx); // horizontal move
void rotate(int dir); // +1 cw, -1 ccw (simple wall-kick)
void holdCurrent(); // swap with hold (once per spawn)

View File

@ -47,14 +47,14 @@ void GameRenderer::drawBlockTexture(SDL_Renderer* renderer, SDL_Texture* blocksT
SDL_RenderTexture(renderer, blocksTex, &srcRect, &dstRect);
}
void GameRenderer::drawPiece(SDL_Renderer* renderer, SDL_Texture* blocksTex, const Game::Piece& piece, float ox, float oy, float tileSize, bool isGhost) {
void GameRenderer::drawPiece(SDL_Renderer* renderer, SDL_Texture* blocksTex, const Game::Piece& piece, float ox, float oy, float tileSize, bool isGhost, float pixelOffsetY) {
if (piece.type >= PIECE_COUNT) return;
for (int cy = 0; cy < 4; ++cy) {
for (int cx = 0; cx < 4; ++cx) {
if (Game::cellFilled(piece, cx, cy)) {
float px = ox + (piece.x + cx) * tileSize;
float py = oy + (piece.y + cy) * tileSize;
float py = oy + (piece.y + cy) * tileSize + pixelOffsetY;
if (isGhost) {
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
@ -239,6 +239,59 @@ void GameRenderer::renderPlayingState(
bool allowActivePieceRender = true;
auto computeFallOffset = [&]() -> float {
if (game->isPaused()) {
return 0.0f;
}
double gravityMs = game->getGravityMs();
if (gravityMs <= 0.0) {
return 0.0f;
}
double effectiveMs = game->isSoftDropping() ? std::max(5.0, gravityMs / 5.0) : gravityMs;
double accumulator = std::clamp(game->getFallAccumulator(), 0.0, effectiveMs);
if (effectiveMs <= 0.0) {
return 0.0f;
}
float progress = static_cast<float>(accumulator / effectiveMs);
progress = std::clamp(progress, 0.0f, 1.0f);
return progress * finalBlockSize;
};
float activePieceOffset = (!game->isPaused()) ? computeFallOffset() : 0.0f;
if (activePieceOffset > 0.0f) {
const auto& boardRef = game->boardRef();
const Game::Piece& piece = game->current();
float maxAllowed = finalBlockSize;
for (int cy = 0; cy < 4; ++cy) {
for (int cx = 0; cx < 4; ++cx) {
if (!Game::cellFilled(piece, cx, cy)) {
continue;
}
int gx = piece.x + cx;
int gy = piece.y + cy;
if (gx < 0 || gx >= Game::COLS) {
continue;
}
int testY = gy + 1;
int emptyRows = 0;
if (testY < 0) {
emptyRows -= testY; // number of rows until we reach row 0
testY = 0;
}
while (testY >= 0 && testY < Game::ROWS) {
if (boardRef[testY * Game::COLS + gx] != 0) {
break;
}
++emptyRows;
++testY;
}
float cellLimit = (emptyRows > 0) ? finalBlockSize : 0.0f;
maxAllowed = std::min(maxAllowed, cellLimit);
}
}
activePieceOffset = std::min(activePieceOffset, maxAllowed);
}
// Draw ghost piece (where current piece will land)
if (allowActivePieceRender) {
Game::Piece ghostPiece = game->current();
@ -274,7 +327,7 @@ void GameRenderer::renderPlayingState(
// Draw the falling piece
if (allowActivePieceRender) {
drawPiece(renderer, blocksTex, game->current(), gridX, gridY, finalBlockSize, false);
drawPiece(renderer, blocksTex, game->current(), gridX, gridY, finalBlockSize, false, activePieceOffset);
}
// Draw line clearing effects

View File

@ -50,7 +50,7 @@ public:
private:
// Helper functions for drawing game elements
static void drawBlockTexture(SDL_Renderer* renderer, SDL_Texture* blocksTex, float x, float y, float size, int blockType);
static void drawPiece(SDL_Renderer* renderer, SDL_Texture* blocksTex, const Game::Piece& piece, float ox, float oy, float tileSize, bool isGhost = false);
static void drawPiece(SDL_Renderer* renderer, SDL_Texture* blocksTex, const Game::Piece& piece, float ox, float oy, float tileSize, bool isGhost = false, float pixelOffsetY = 0.0f);
static void drawSmallPiece(SDL_Renderer* renderer, SDL_Texture* blocksTex, PieceType pieceType, float x, float y, float tileSize);
// Helper function for drawing rectangles