examples/game/01-snake: Update game logic in AppIterate, don't use a timer.

Reference Issue #11210.
This commit is contained in:
Ryan C. Gordon 2024-10-14 23:16:02 -04:00
parent edb28e79b5
commit e254c99b38
No known key found for this signature in database
GPG key ID: FA148B892AB48044

View file

@ -57,8 +57,8 @@ typedef struct
{ {
SDL_Window *window; SDL_Window *window;
SDL_Renderer *renderer; SDL_Renderer *renderer;
SDL_TimerID step_timer;
SnakeContext snake_ctx; SnakeContext snake_ctx;
Uint64 last_step;
} AppState; } AppState;
SnakeCell snake_cell_at(const SnakeContext *ctx, char x, char y) SnakeCell snake_cell_at(const SnakeContext *ctx, char x, char y)
@ -208,16 +208,6 @@ void snake_step(SnakeContext *ctx)
} }
} }
static Uint32 sdl_timer_callback_(void *payload, SDL_TimerID timer_id, Uint32 interval)
{
/* NOTE: snake_step is not called here directly for multithreaded concerns. */
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_USER;
SDL_PushEvent(&event);
return interval;
}
static int handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code) static int handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code)
{ {
switch (key_code) { switch (key_code) {
@ -250,14 +240,22 @@ static int handle_key_event_(SnakeContext *ctx, SDL_Scancode key_code)
SDL_AppResult SDL_AppIterate(void *appstate) SDL_AppResult SDL_AppIterate(void *appstate)
{ {
AppState *as; AppState *as = (AppState *)appstate;
SnakeContext *ctx; SnakeContext *ctx = &as->snake_ctx;
const Uint64 now = SDL_GetTicks();
SDL_FRect r; SDL_FRect r;
unsigned i; unsigned i;
unsigned j; unsigned j;
int ct; int ct;
as = (AppState *)appstate;
ctx = &as->snake_ctx; // run game logic if we're at or past the time to run it.
// if we're _really_ behind the time to run it, run it
// several times.
while ((now - as->last_step) >= STEP_RATE_IN_MILLISECONDS) {
snake_step(ctx);
as->last_step += STEP_RATE_IN_MILLISECONDS;
}
r.w = r.h = SNAKE_BLOCK_SIZE_IN_PIXELS; r.w = r.h = SNAKE_BLOCK_SIZE_IN_PIXELS;
SDL_SetRenderDrawColor(as->renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(as->renderer, 0, 0, 0, 255);
SDL_RenderClear(as->renderer); SDL_RenderClear(as->renderer);
@ -321,10 +319,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
snake_initialize(&as->snake_ctx); snake_initialize(&as->snake_ctx);
as->step_timer = SDL_AddTimer(STEP_RATE_IN_MILLISECONDS, sdl_timer_callback_, NULL); as->last_step = SDL_GetTicks();
if (as->step_timer == 0) {
return SDL_APP_FAILURE;
}
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
@ -335,9 +330,6 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
switch (event->type) { switch (event->type) {
case SDL_EVENT_QUIT: case SDL_EVENT_QUIT:
return SDL_APP_SUCCESS; return SDL_APP_SUCCESS;
case SDL_EVENT_USER:
snake_step(ctx);
break;
case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_DOWN:
return handle_key_event_(ctx, event->key.scancode); return handle_key_event_(ctx, event->key.scancode);
} }
@ -348,7 +340,6 @@ void SDL_AppQuit(void *appstate, SDL_AppResult result)
{ {
if (appstate != NULL) { if (appstate != NULL) {
AppState *as = (AppState *)appstate; AppState *as = (AppState *)appstate;
SDL_RemoveTimer(as->step_timer);
SDL_DestroyRenderer(as->renderer); SDL_DestroyRenderer(as->renderer);
SDL_DestroyWindow(as->window); SDL_DestroyWindow(as->window);
SDL_free(as); SDL_free(as);