flappychik

Silly SDL2 game
git clone git://bsandro.tech/flappychik
Log | Files | Refs

commit 70b5024d4ab531a17bab3837403b112aabb989de
parent b4109700c5bfa6297a872f15b7d62624ddcbec80
Author: bsandro <brian.drosan@gmail.com>
Date:   Sun, 20 Mar 2022 01:03:16 +0200

basic menu support

Diffstat:
MMakefile | 4++--
Aassets/APL386.ttf | 0
Mmain.c | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
3 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ NAME=$(shell basename ${PWD}) -SDL2FLAGS=$(shell pkg-config --cflags sdl2 SDL2_image) +SDL2FLAGS=$(shell pkg-config --cflags sdl2 SDL2_image SDL2_ttf) CFLAGS?=-std=c99 -Wall -Wextra -pedantic -I. -O0 -g -LDFLAGS?=$(shell pkg-config --libs sdl2 SDL2_image) +LDFLAGS?=$(shell pkg-config --libs sdl2 SDL2_image SDL2_ttf) SRC=$(wildcard *.c) DEPS:=$(wildcard *.h) OBJ:=$(SRC:.c=.o) diff --git a/assets/APL386.ttf b/assets/APL386.ttf Binary files differ. diff --git a/main.c b/main.c @@ -4,6 +4,7 @@ #include <assert.h> #include <SDL.h> #include <SDL_image.h> +#include <SDL_ttf.h> #ifdef __APPLE__ #define WINDOW_FLAGS SDL_WINDOW_METAL | SDL_WINDOW_ALLOW_HIGHDPI @@ -14,6 +15,9 @@ #define GAME_WIN_WIDTH 800 #define GAME_WIN_HEIGHT 600 #define GAME_FPS 60 +#define GAME_FALL_ACCEL 0.85 // pixels per second^2 essentially + +enum game_state_t { GAME_STATE_INIT, GAME_STATE_RUNNING, GAME_STATE_OVER }; struct sprite_t { SDL_Texture *texture; @@ -24,7 +28,7 @@ struct sprite_t { }; struct game_t { - bool over; + enum game_state_t state; SDL_Window *screen; int scrW, scrH; SDL_Renderer *renderer; @@ -33,12 +37,19 @@ struct game_t { struct sprite_t ship; }; -void process_frame(uint64_t ts, uint64_t ftime, struct game_t *game) { +struct menu_t { + struct game_t *game; + TTF_Font *font; + SDL_Surface *surface; + SDL_Texture *texture; +}; + +void draw_game(uint64_t ftime, struct game_t *game) { game->ship.velocity += game->ship.accel * ftime; game->ship.rect.y += (ftime * game->ship.velocity / 1000.0); if (game->ship.rect.y >= game->scrH) { - game->over = true; + game->state = GAME_STATE_INIT; } // top border @@ -63,7 +74,26 @@ void process_frame(uint64_t ts, uint64_t ftime, struct game_t *game) { SDL_RenderPresent(game->renderer); //printf("frame time: %llu\n", ftime); - game->last_frame = ts; +} + +void draw_menu(struct menu_t *menu) { + if (menu->surface == NULL) { + SDL_Color color = { 255, 255, 255, 0 }; + menu->surface = TTF_RenderText_Solid(menu->font, "Press <space> to play", color); + assert(menu->surface != NULL); + } + + if (menu->texture == NULL) { + menu->texture = SDL_CreateTextureFromSurface(menu->game->renderer, menu->surface); + assert(menu->texture != NULL); + } + + SDL_Rect rect; + SDL_QueryTexture(menu->texture, NULL, NULL, &rect.w, &rect.h); + + SDL_RenderClear(menu->game->renderer); + SDL_RenderCopy(menu->game->renderer, menu->texture, NULL, &rect); + SDL_RenderPresent(menu->game->renderer); } int main(int argc, char *argv[]) { @@ -72,9 +102,10 @@ int main(int argc, char *argv[]) { SDL_Event event; struct game_t game = {0}; - game.over = false; + game.state = GAME_STATE_INIT; SDL_Init(SDL_INIT_VIDEO); + TTF_Init(); game.screen = SDL_CreateWindow("flappychik", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, GAME_WIN_WIDTH, GAME_WIN_HEIGHT, WINDOW_FLAGS); assert(game.screen != NULL); @@ -102,30 +133,42 @@ int main(int argc, char *argv[]) { // hidpi scale float hidpi_scale = (float)game.scrW / GAME_WIN_WIDTH; - printf("scale: %.2f\n", hidpi_scale); // initial values game.last_frame = SDL_GetTicks64(); - game.ship.rect.x = 150; + game.ship.rect.x = 150; // initial position game.ship.rect.y = 50; game.ship.rect.w *= hidpi_scale; game.ship.rect.h *= hidpi_scale; game.bg.rect.w *= hidpi_scale; game.bg.rect.h *= hidpi_scale; - game.ship.accel = 0.85; // pixels per second^2 essentially + game.ship.accel = GAME_FALL_ACCEL; + + // menu + struct menu_t menu = {0}; + menu.game = &game; + menu.font = TTF_OpenFont("assets/APL386.ttf", 70); + assert(menu.font != NULL); // main game loop - while (!game.over) { + while (game.state != GAME_STATE_OVER) { while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: - game.over = true; + game.state = GAME_STATE_OVER; break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_q) { // quit if "q" button is pressed - game.over = true; + game.state = GAME_STATE_OVER; } if (event.key.keysym.sym == SDLK_SPACE) { - game.ship.velocity = -600; + if (game.state == GAME_STATE_RUNNING) { + game.ship.velocity = -600; + } else { // reset game + game.state = GAME_STATE_RUNNING; + game.ship.velocity = 0; + game.ship.rect.x = 150; + game.ship.rect.y = 50; + } } break; } @@ -135,15 +178,22 @@ int main(int argc, char *argv[]) { uint64_t ftime = ts - game.last_frame; if (ftime >= 1000/GAME_FPS) { - process_frame(ts, ftime, &game); + if (game.state == GAME_STATE_RUNNING) { + draw_game(ftime, &game); + } else { + draw_menu(&menu); + } + game.last_frame = ts; } } // cleanup + TTF_CloseFont(menu.font); SDL_DestroyTexture(game.bg.texture); SDL_DestroyTexture(game.ship.texture); SDL_DestroyRenderer(game.renderer); SDL_DestroyWindow(game.screen); + TTF_Quit(); SDL_Quit(); printf("bye!\n");