fix(games): complete font (U/W + A-Z), fix Tetris gravity, frame + center overlays
- Font: add missing glyphs (U, W and complete A-Z) to both Snake and Tetris 5x7 bitmap fonts so PAUSE/RESUME/NEW GAME render correctly. - Tetris: the gravity loop never advanced nextTick after a step, so the piece dropped almost instantly every frame. Advance nextTick by speed after each step (matching Snake) so gravity honours the configured rate. - Both: draw a 1px frame around the whole 240x296 window (right/bottom edges were previously absent) and clear the playfield to black behind PAUSE/GAME OVER text for contrast. - Both: fix centering of overlay labels (GAME OVER, 5 RESUME, 5 NEW GAME).
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+16
-4
@@ -57,6 +57,10 @@ static const Glyph GLYPHS[] = {
|
||||
{'V', {0b10001,0b10001,0b10001,0b10001,0b10001,0b01010,0b00100}},
|
||||
{'W', {0b10001,0b10001,0b10001,0b10101,0b10101,0b11011,0b10001}},
|
||||
{'Y', {0b10001,0b10001,0b01010,0b00100,0b00100,0b00100,0b00100}},
|
||||
{'J', {0b00010,0b00010,0b00010,0b00010,0b10010,0b10010,0b01100}},
|
||||
{'Q', {0b01110,0b10001,0b10001,0b10001,0b10101,0b10010,0b01101}},
|
||||
{'U', {0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}},
|
||||
{'Z', {0b11111,0b00010,0b00100,0b01000,0b10000,0b10000,0b11111}},
|
||||
{'0', {0b01110,0b10011,0b10101,0b10101,0b11001,0b10001,0b01110}},
|
||||
{'1', {0b00100,0b01100,0b00100,0b00100,0b00100,0b00100,0b01110}},
|
||||
{'2', {0b01110,0b10001,0b00001,0b00110,0b01000,0b10000,0b11111}},
|
||||
@@ -213,6 +217,10 @@ static void render() {
|
||||
XSetForeground(dpy, gc, C_DIM);
|
||||
XDrawRectangle(dpy, back, gc, gx0 - 1, gy0 - 1, gw + 2, gh + 2);
|
||||
|
||||
// frame the whole window (right/bottom edges too)
|
||||
XSetForeground(dpy, gc, C_DIM);
|
||||
XDrawRectangle(dpy, back, gc, 0, 0, winW - 1, winH - 1);
|
||||
|
||||
// food
|
||||
if (foodx >= 0) {
|
||||
XSetForeground(dpy, gc, C_FOOD);
|
||||
@@ -233,14 +241,18 @@ static void render() {
|
||||
draw_text(gx0 + gw - 11 * 6, 2, 1, C_DIM, buf);
|
||||
}
|
||||
|
||||
if (state == PAUSED || state == GAMEOVER) {
|
||||
XSetForeground(dpy, gc, C_BG);
|
||||
XFillRectangle(dpy, back, gc, 0, 0, winW, winH);
|
||||
}
|
||||
if (state == PAUSED) {
|
||||
draw_text(winW / 2 - 3 * 6 * 2, winH / 2 - 7 * 2, 2, C_FG, "PAUSE");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 + 7 * 2, 1, C_DIM, "5 RESUME");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 - 7 * 2, 2, C_FG, "PAUSE");
|
||||
draw_text(winW / 2 - 4 * 6, winH / 2 + 7 * 2, 1, C_DIM, "5 RESUME");
|
||||
} else if (state == GAMEOVER) {
|
||||
draw_text(winW / 2 - 4 * 6 * 2, winH / 2 - 14, 2, C_FG, "GAME OVER");
|
||||
draw_text(winW / 2 - 9 * 6, winH / 2 - 14, 2, C_FG, "GAME OVER");
|
||||
snprintf(buf, sizeof(buf), "SCORE %d", score);
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 + 4, 1, C_DIM, buf);
|
||||
draw_text(winW / 2 - 9 * 6, winH / 2 + 4 + 9, 1, C_DIM, "5 NEW GAME");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 + 4 + 9, 1, C_DIM, "5 NEW GAME");
|
||||
}
|
||||
|
||||
XCopyArea(dpy, back, win, gc, 0, 0, winW, winH, 0, 0);
|
||||
|
||||
+23
-7
@@ -27,7 +27,7 @@ static const int WIN_W = 240;
|
||||
static const int WIN_H = 296;
|
||||
static const int PCOLS = 10;
|
||||
static const int PROWS = 20;
|
||||
static const int CELL = 12;
|
||||
static const int CELL = 14;
|
||||
|
||||
// ---- 5x7 bitmap font ----
|
||||
struct Glyph { char ch; unsigned char r[7]; };
|
||||
@@ -56,6 +56,13 @@ static const Glyph GLYPHS[] = {
|
||||
{'V', {0b10001,0b10001,0b10001,0b10001,0b10001,0b01010,0b00100}},
|
||||
{'X', {0b10001,0b10001,0b01010,0b00100,0b01010,0b10001,0b10001}},
|
||||
{'Y', {0b10001,0b10001,0b01010,0b00100,0b00100,0b00100,0b00100}},
|
||||
{'D', {0b11110,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}},
|
||||
{'J', {0b00010,0b00010,0b00010,0b00010,0b10010,0b10010,0b01100}},
|
||||
{'K', {0b10001,0b10010,0b10100,0b11000,0b10100,0b10010,0b10001}},
|
||||
{'Q', {0b01110,0b10001,0b10001,0b10001,0b10101,0b10010,0b01101}},
|
||||
{'U', {0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}},
|
||||
{'W', {0b10001,0b10001,0b10001,0b10101,0b10101,0b11011,0b10001}},
|
||||
{'Z', {0b11111,0b00010,0b00100,0b01000,0b10000,0b10000,0b11111}},
|
||||
{'0', {0b01110,0b10011,0b10101,0b10101,0b11001,0b10001,0b01110}},
|
||||
{'1', {0b00100,0b01100,0b00100,0b00100,0b00100,0b00100,0b01110}},
|
||||
{'2', {0b01110,0b10001,0b00001,0b00110,0b01000,0b10000,0b11111}},
|
||||
@@ -101,7 +108,7 @@ static int board[PCOLS][PROWS]; // 0 empty, else type+1
|
||||
static int curType = 0, curRot = 0, curX = 3, curY = 0;
|
||||
static int nextType = 0;
|
||||
static int score = 0, best = 0, lines = 0, level = 1;
|
||||
static int speed = 800; // ms per gravity step
|
||||
static int speed = 1000; // ms per gravity step
|
||||
static unsigned long nextTick = 0;
|
||||
static bool running = true;
|
||||
|
||||
@@ -176,7 +183,7 @@ static void lock_piece() {
|
||||
score += pts[cleared] * level;
|
||||
if (score > best) best = score;
|
||||
int nl = 1 + lines / 10;
|
||||
if (nl != level) { level = nl; speed = 800 - (level - 1) * 40; if (speed < 250) speed = 250; }
|
||||
if (nl != level) { level = nl; speed = 1000 - (level - 1) * 40; if (speed < 300) speed = 300; }
|
||||
}
|
||||
spawn();
|
||||
}
|
||||
@@ -250,6 +257,10 @@ static void render() {
|
||||
XSetForeground(dpy, gc, C_DIM);
|
||||
XDrawRectangle(dpy, back, gc, px0 - 1, py0 - 1, PCOLS * CELL + 2, PROWS * CELL + 2);
|
||||
|
||||
// frame the whole window (right/bottom edges too)
|
||||
XSetForeground(dpy, gc, C_DIM);
|
||||
XDrawRectangle(dpy, back, gc, 0, 0, winW - 1, winH - 1);
|
||||
|
||||
// settled blocks
|
||||
for (int x = 0; x < PCOLS; x++)
|
||||
for (int y = 0; y < PROWS; y++)
|
||||
@@ -298,13 +309,17 @@ static void render() {
|
||||
snprintf(buf, sizeof(buf), "LEVEL %d", level); draw_text(sx, ty + 18, 1, C_DIM, buf);
|
||||
if (best > 0) { snprintf(buf, sizeof(buf), "BEST %d", best); draw_text(sx, ty + 27, 1, C_DIM, buf); }
|
||||
|
||||
if (state == PAUSED || state == GAMEOVER) {
|
||||
XSetForeground(dpy, gc, C_BG);
|
||||
XFillRectangle(dpy, back, gc, 0, 0, winW, winH);
|
||||
}
|
||||
if (state == PAUSED) {
|
||||
draw_text(winW / 2 - 3 * 6 * 2, winH / 2 - 7, 2, C_FG, "PAUSE");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 + 10, 1, C_DIM, "5 RESUME");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 - 7, 2, C_FG, "PAUSE");
|
||||
draw_text(winW / 2 - 4 * 6, winH / 2 + 10, 1, C_DIM, "5 RESUME");
|
||||
} else if (state == GAMEOVER) {
|
||||
draw_text(winW / 2 - 5 * 6 * 2, winH / 2 - 14, 2, C_FG, "GAME OVER");
|
||||
draw_text(winW / 2 - 9 * 6, winH / 2 - 14, 2, C_FG, "GAME OVER");
|
||||
snprintf(buf, sizeof(buf), "SCORE %d", score); draw_text(winW / 2 - 5 * 6, winH / 2 + 4, 1, C_DIM, buf);
|
||||
draw_text(winW / 2 - 9 * 6, winH / 2 + 13, 1, C_DIM, "5 NEW GAME");
|
||||
draw_text(winW / 2 - 5 * 6, winH / 2 + 13, 1, C_DIM, "5 NEW GAME");
|
||||
}
|
||||
|
||||
XCopyArea(dpy, back, win, gc, 0, 0, winW, winH, 0, 0);
|
||||
@@ -441,6 +456,7 @@ int main() {
|
||||
}
|
||||
if (running && now_ms() >= nextTick) {
|
||||
if (state == PLAYING) step();
|
||||
if (state == PLAYING) nextTick = now_ms() + speed;
|
||||
else nextTick = now_ms() + 80;
|
||||
render();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user