#include #include #include #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 #define GRAVITY 0.5 #define JUMP_FORCE -12 #define MOVE_SPEED 5 typedef struct { float x, y; float dx, dy; bool on_ground; } Player; typedef struct { SDL_EventType type; SDL_Keycode key; } EventSignal; typedef struct { Player player; bool running; } GameState; typedef void (*StateTransformer)(GameState*, Uint32); typedef void (*EventHander)(GameState*, EventSignal); // FRP-style event stream processing void process_events(EventHander handler, GameState* state) { SDL_Event e; while (SDL_PollEvent(&e)) { EventSignal signal = {e.type, e.key.keysym.sym}; handler(state, signal); } } // FRP-style state transformation void update_state(GameState* state, Uint32 delta_time) { Player* p = &state->player; // Apply gravity p->dy += GRAVITY; p->y += p->dy; // Ground collision if (p->y > SCREEN_HEIGHT - 40) { p->y = SCREEN_HEIGHT - 40; p->dy = 0; p->on_ground = true; } } // Event handler with FRP-style signal processing void handle_input(GameState* state, EventSignal signal) { Player* p = &state->player; switch (signal.type) { case SDL_QUIT: state->running = false; break; case SDL_KEYDOWN: switch (signal.key) { case SDLK_SPACE: if (p->on_ground) { p->dy = JUMP_FORCE; p->on_ground = false; } break; case SDLK_LEFT: p->dx = -MOVE_SPEED; break; case SDLK_RIGHT: p->dx = MOVE_SPEED; break; } break; case SDL_KEYUP: if (signal.key == SDLK_LEFT || signal.key == SDLK_RIGHT) { p->dx = 0; } break; } } void render(SDL_Renderer* renderer, const GameState* state) { SDL_SetRenderDrawColor(renderer, 30, 30, 30, 255); SDL_RenderClear(renderer); // Draw ground SDL_SetRenderDrawColor(renderer, 100, 200, 100, 255); SDL_Rect ground = {0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, 40}; SDL_RenderFillRect(renderer, &ground); // Draw player SDL_SetRenderDrawColor(renderer, 200, 100, 100, 255); SDL_Rect player_rect = {state->player.x, state->player.y, 40, 40}; SDL_RenderFillRect(renderer, &player_rect); SDL_RenderPresent(renderer); } int main() { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("Platformer FRP", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); GameState state = { .player = {.x = 100, .y = 100, .dx = 0, .dy = 0, .on_ground = true}, .running = true }; Uint32 last_time = SDL_GetTicks(); while (state.running) { Uint32 current_time = SDL_GetTicks(); Uint32 delta_time = current_time - last_time; process_events(handle_input, &state); update_state(&state, delta_time); render(renderer, &state); // Simple frame rate limiting if (delta_time < 16) SDL_Delay(16 - delta_time); last_time = current_time; } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }