games: fix font glyphs, Snake edge-wrap, snappier Snake

Font: add missing bitmap glyphs (/ # * + =) to both Snake and Tetris so
control labels like '4/6 MOVE' and '# PAUSE' render correctly. Also hoist
XSetForeground out of the per-pixel loop in draw_text (both games).

Snake: remove the wall-collision death; the head now wraps through the
opposite edge ((hx+COLS)%COLS, (hy+ROWS)%ROWS). Base speed raised from
70->100 px/sec (~128ms -> ~90ms per step) so it feels less laggy; the
+1 px/sec per 5 food progressive difficulty is unchanged.
This commit is contained in:
Luxferre
2026-10-23 20:32:50 +03:00
parent fdcdb89684
commit 58071b374c
6 changed files with 21 additions and 12 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14 -9
View File
@@ -70,6 +70,11 @@ static const Glyph GLYPHS[] = {
{'7', {0b11111,0b00001,0b00010,0b00100,0b01000,0b01000,0b01000}}, {'7', {0b11111,0b00001,0b00010,0b00100,0b01000,0b01000,0b01000}},
{'8', {0b01110,0b10001,0b10001,0b01110,0b10001,0b10001,0b01110}}, {'8', {0b01110,0b10001,0b10001,0b01110,0b10001,0b10001,0b01110}},
{'9', {0b01110,0b10001,0b10001,0b01111,0b00001,0b00010,0b01100}}, {'9', {0b01110,0b10001,0b10001,0b01111,0b00001,0b00010,0b01100}},
{'/', {0b00001,0b00010,0b00100,0b00100,0b01000,0b01000,0b10000}},
{'#', {0b01010,0b01010,0b11111,0b01010,0b11111,0b01010,0b01010}},
{'*', {0b00100,0b01010,0b11111,0b01010,0b00100,0b00000,0b00000}},
{'+', {0b00000,0b00100,0b00100,0b11111,0b00100,0b00100,0b00000}},
{'=', {0b00000,0b00000,0b11111,0b00000,0b11111,0b00000,0b00000}},
}; };
static const int NGLYPH = int(sizeof(GLYPHS) / sizeof(GLYPHS[0])); static const int NGLYPH = int(sizeof(GLYPHS) / sizeof(GLYPHS[0]));
@@ -101,8 +106,8 @@ static int ndirx = 1, ndiry = 0; // buffered next direction
static int foodx, foody; static int foodx, foody;
static int score = 0; static int score = 0;
static int best = 0; static int best = 0;
static int speed = 130; // ms per step (derived from pps below) static int speed = 90; // ms per step (derived from pps below)
static int pps = 70; // base speed px/sec; +1 px/sec per 5 food eaten static int pps = 100; // base speed px/sec; +1 px/sec per 5 food eaten
static unsigned long nextTick = 0; static unsigned long nextTick = 0;
static bool running = true; static bool running = true;
static unsigned long now_ms() { static unsigned long now_ms() {
@@ -160,7 +165,7 @@ static void reset_game() {
dirx = 1; diry = 0; dirx = 1; diry = 0;
ndirx = 1; ndiry = 0; ndirx = 1; ndiry = 0;
score = 0; score = 0;
pps = 70; pps = 100;
update_speed(); update_speed();
place_food(); place_food();
state = PLAYING; state = PLAYING;
@@ -174,7 +179,9 @@ static void step() {
} }
int hx = snake[snakelen - 1][0] + dirx; int hx = snake[snakelen - 1][0] + dirx;
int hy = snake[snakelen - 1][1] + diry; int hy = snake[snakelen - 1][1] + diry;
if (hx < 0 || hx >= COLS || hy < 0 || hy >= ROWS) { state = GAMEOVER; return; } // wrap through the opposite edge instead of dying at the wall
hx = (hx + COLS) % COLS;
hy = (hy + ROWS) % ROWS;
// self collision (ignore current tail cell since it will move, unless growing) // self collision (ignore current tail cell since it will move, unless growing)
for (int i = 0; i < snakelen - 1; i++) { for (int i = 0; i < snakelen - 1; i++) {
if (snake[i][0] == hx && snake[i][1] == hy) { state = GAMEOVER; return; } if (snake[i][0] == hx && snake[i][1] == hy) { state = GAMEOVER; return; }
@@ -204,17 +211,15 @@ static void step() {
static void draw_text(int x, int y, int scale, unsigned long col, const char* s) { static void draw_text(int x, int y, int scale, unsigned long col, const char* s) {
int cx = x; int cx = x;
XSetForeground(dpy, gc, col);
for (const char* p = s; *p; p++) { for (const char* p = s; *p; p++) {
const unsigned char* g = glyph(*p); const unsigned char* g = glyph(*p);
for (int r = 0; r < 7; r++) { for (int r = 0; r < 7; r++) {
unsigned char row = g[r]; unsigned char row = g[r];
for (int b = 0; b < 5; b++) { for (int b = 0; b < 5; b++)
if (row & (1 << (4 - b))) { if (row & (1 << (4 - b)))
XSetForeground(dpy, gc, col);
XFillRectangle(dpy, back, gc, cx + b * scale, y + r * scale, scale, scale); XFillRectangle(dpy, back, gc, cx + b * scale, y + r * scale, scale, scale);
} }
}
}
cx += 6 * scale; cx += 6 * scale;
} }
} }
+7 -3
View File
@@ -72,6 +72,11 @@ static const Glyph GLYPHS[] = {
{'7', {0b11111,0b00001,0b00010,0b00100,0b01000,0b01000,0b01000}}, {'7', {0b11111,0b00001,0b00010,0b00100,0b01000,0b01000,0b01000}},
{'8', {0b01110,0b10001,0b10001,0b01110,0b10001,0b10001,0b01110}}, {'8', {0b01110,0b10001,0b10001,0b01110,0b10001,0b10001,0b01110}},
{'9', {0b01110,0b10001,0b10001,0b01111,0b00001,0b00010,0b01100}}, {'9', {0b01110,0b10001,0b10001,0b01111,0b00001,0b00010,0b01100}},
{'/', {0b00001,0b00010,0b00100,0b00100,0b01000,0b01000,0b10000}},
{'#', {0b01010,0b01010,0b11111,0b01010,0b11111,0b01010,0b01010}},
{'*', {0b00100,0b01010,0b11111,0b01010,0b00100,0b00000,0b00000}},
{'+', {0b00000,0b00100,0b00100,0b11111,0b00100,0b00100,0b00000}},
{'=', {0b00000,0b00000,0b11111,0b00000,0b11111,0b00000,0b00000}},
}; };
static const int NGLYPH = int(sizeof(GLYPHS) / sizeof(GLYPHS[0])); static const int NGLYPH = int(sizeof(GLYPHS) / sizeof(GLYPHS[0]));
static const unsigned char* glyph(char c) { static const unsigned char* glyph(char c) {
@@ -245,16 +250,15 @@ static void reset_game() {
static void draw_text(int x, int y, int scale, unsigned long col, const char* s) { static void draw_text(int x, int y, int scale, unsigned long col, const char* s) {
int cx = x; int cx = x;
XSetForeground(dpy, gc, col);
for (const char* p = s; *p; p++) { for (const char* p = s; *p; p++) {
const unsigned char* g = glyph(*p); const unsigned char* g = glyph(*p);
for (int r = 0; r < 7; r++) { for (int r = 0; r < 7; r++) {
unsigned char row = g[r]; unsigned char row = g[r];
for (int b = 0; b < 5; b++) for (int b = 0; b < 5; b++)
if (row & (1 << (4 - b))) { if (row & (1 << (4 - b)))
XSetForeground(dpy, gc, col);
XFillRectangle(dpy, back, gc, cx + b * scale, y + r * scale, scale, scale); XFillRectangle(dpy, back, gc, cx + b * scale, y + r * scale, scale, scale);
} }
}
cx += 6 * scale; cx += 6 * scale;
} }
} }