games: fix timing drift with cumulative nextTick, 30fps render, 90 pps base
Root cause of unstable speed: nextTick was reset to 'now + speed' each step, accumulating timing drift. Now uses 'nextTick += speed' with a floor (if nextTick < now, reset to now) to prevent drift and catch-up spirals. - Both games: 30 fps render cap (FRAME_MS = 33 ms), nextTick updated cumulatively to eliminate drift. - Snake: base speed 90 px/sec (~100 ms per step at cell=9), turn queue unchanged, edge wrap unchanged. - Tetris: gravity step uses cumulative nextTick, controls unchanged.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5
-3
@@ -228,7 +228,8 @@ static void step() {
|
|||||||
update_speed();
|
update_speed();
|
||||||
place_food();
|
place_food();
|
||||||
}
|
}
|
||||||
nextTick = now_ms() + speed;
|
if (nextTick < now_ms()) nextTick = now_ms();
|
||||||
|
nextTick += speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -407,7 +408,7 @@ int main() {
|
|||||||
render();
|
render();
|
||||||
|
|
||||||
int xfd = ConnectionNumber(dpy);
|
int xfd = ConnectionNumber(dpy);
|
||||||
const unsigned long FRAME_MS = 1000 / 60; // 60 fps rendering
|
const unsigned long FRAME_MS = 1000 / 30; // 30 fps rendering
|
||||||
unsigned long frameStart = now_ms();
|
unsigned long frameStart = now_ms();
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
@@ -425,7 +426,8 @@ int main() {
|
|||||||
// Game logic step at its own rate
|
// Game logic step at its own rate
|
||||||
if (now >= nextTick) {
|
if (now >= nextTick) {
|
||||||
if (state == PLAYING) step();
|
if (state == PLAYING) step();
|
||||||
nextTick = now + (state == PLAYING ? speed : 80);
|
if (nextTick < now) nextTick = now;
|
||||||
|
nextTick += (state == PLAYING ? speed : 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render every frame
|
// Render every frame
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ int main() {
|
|||||||
render();
|
render();
|
||||||
|
|
||||||
int xfd = ConnectionNumber(dpy);
|
int xfd = ConnectionNumber(dpy);
|
||||||
const unsigned long FRAME_MS = 1000 / 60; // 60 fps rendering
|
const unsigned long FRAME_MS = 1000 / 30; // 30 fps rendering
|
||||||
unsigned long frameStart = now_ms();
|
unsigned long frameStart = now_ms();
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
@@ -538,7 +538,8 @@ int main() {
|
|||||||
// Game logic step at its own rate
|
// Game logic step at its own rate
|
||||||
if (now >= nextTick) {
|
if (now >= nextTick) {
|
||||||
if (state == PLAYING) step();
|
if (state == PLAYING) step();
|
||||||
nextTick = now + (state == PLAYING ? speed : 80);
|
if (nextTick < now) nextTick = now;
|
||||||
|
nextTick += (state == PLAYING ? speed : 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render every frame
|
// Render every frame
|
||||||
|
|||||||
Reference in New Issue
Block a user