commit 70b5024d4ab531a17bab3837403b112aabb989de
parent b4109700c5bfa6297a872f15b7d62624ddcbec80
Author: bsandro <brian.drosan@gmail.com>
Date: Sun, 20 Mar 2022 01:03:16 +0200
basic menu support
Diffstat:
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");