I block rotation fix
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <limits>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
// Piece rotation bitmasks (row-major 4x4). Bit 0 = (0,0).
|
// Piece rotation bitmasks (row-major 4x4). Bit 0 = (0,0).
|
||||||
@ -400,8 +401,28 @@ void Game::rotate(int dir) {
|
|||||||
|
|
||||||
// Try rotation at current position first
|
// Try rotation at current position first
|
||||||
if (!collides(p)) {
|
if (!collides(p)) {
|
||||||
cur = p;
|
// If rotation at current position would place cells above the top,
|
||||||
return;
|
// attempt to shift it down so the topmost block sits at gy == 0.
|
||||||
|
int minGy = std::numeric_limits<int>::max();
|
||||||
|
for (int cy = 0; cy < 4; ++cy) {
|
||||||
|
for (int cx = 0; cx < 4; ++cx) {
|
||||||
|
if (!cellFilled(p, cx, cy)) continue;
|
||||||
|
minGy = std::min(minGy, p.y + cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minGy < 0) {
|
||||||
|
Piece adj = p;
|
||||||
|
adj.y += -minGy;
|
||||||
|
if (!collides(adj)) {
|
||||||
|
cur = adj;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Can't shift into place without collision - fall through to kicks
|
||||||
|
} else {
|
||||||
|
cur = p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard SRS Wall Kicks
|
// Standard SRS Wall Kicks
|
||||||
@ -457,8 +478,30 @@ void Game::rotate(int dir) {
|
|||||||
test.x = cur.x + kick.first;
|
test.x = cur.x + kick.first;
|
||||||
test.y = cur.y + kick.second;
|
test.y = cur.y + kick.second;
|
||||||
if (!collides(test)) {
|
if (!collides(test)) {
|
||||||
cur = test;
|
// Prevent rotated piece from ending up above the visible playfield.
|
||||||
return;
|
// If any cell of `test` is above the top (gy < 0), try shifting it
|
||||||
|
// downward so the highest block sits at row 0. Accept the shift
|
||||||
|
// only if it doesn't collide; otherwise keep searching kicks.
|
||||||
|
int minGy = std::numeric_limits<int>::max();
|
||||||
|
for (int cy = 0; cy < 4; ++cy) {
|
||||||
|
for (int cx = 0; cx < 4; ++cx) {
|
||||||
|
if (!cellFilled(test, cx, cy)) continue;
|
||||||
|
minGy = std::min(minGy, test.y + cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minGy < 0) {
|
||||||
|
Piece adj = test;
|
||||||
|
adj.y += -minGy; // shift down so topmost block is at gy == 0
|
||||||
|
if (!collides(adj)) {
|
||||||
|
cur = adj;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// couldn't shift without collision, try next kick
|
||||||
|
} else {
|
||||||
|
cur = test;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user