Implement font rendering, add gold

This commit is contained in:
Reimar 2025-11-04 15:31:11 +01:00
parent 61390e37c0
commit 83ed7e5190
7 changed files with 91 additions and 10 deletions

View File

@ -21,8 +21,8 @@ else
LINKER_FLAGS += -fsanitize=address,undefined -g -Og -rdynamic
endif
CXX_FLAGS += $(shell pkg-config sdl2 SDL2_image --cflags)
LINKER_FLAGS += $(shell pkg-config sdl2 SDL2_image --libs)
CXX_FLAGS += $(shell pkg-config sdl2 SDL2_image SDL2_ttf --cflags)
LINKER_FLAGS += $(shell pkg-config sdl2 SDL2_image SDL2_ttf --libs)
build/%.o: %.cpp $(wildcard *.hpp)
@mkdir -p `dirname $@`

28
src/Color.hpp Normal file
View File

@ -0,0 +1,28 @@
#ifndef COLOR_HPP
#define COLOR_HPP
#include <cstdint>
typedef SDL_Color Color;
inline Color rgb(uint8_t red, uint8_t green, uint8_t blue)
{
SDL_Color color;
color.r = red;
color.g = green;
color.b = blue;
color.a = 255;
return color;
}
inline Color rgba(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
SDL_Color color;
color.r = red;
color.g = green;
color.b = blue;
color.a = alpha;
return color;
}
#endif

View File

@ -1,8 +1,10 @@
#include <thread>
#include <functional>
#include <string>
#include "GameRenderer.hpp"
#include "Player.hpp"
#include "Game.hpp"
#include "Color.hpp"
using namespace std::literals::chrono_literals;
@ -10,6 +12,9 @@ Game::Game() : renderer("Zombo Shooter", 800, 450), player(&renderer), map(&rend
{
arrow_sprite = renderer.load_sprite("./assets/arrow.png", 22, 8);
zombo_sprite = renderer.load_sprite("./assets/zombo.png", 40, 40);
gold_sprite = renderer.load_sprite("./assets/gold.png", 30, 20);
font = renderer.load_font("./assets/Jersey20-Regular.ttf", 26);
}
void Game::update(std::stop_token stop_token)
@ -53,7 +58,10 @@ void Game::update(std::stop_token stop_token)
std::erase(arrows, arrow);
zombo.hp--;
if (zombo.hp == 0) std::erase(zombos, zombo);
if (zombo.hp == 0) {
std::erase(zombos, zombo);
player.gold += 10;
}
}
}
}
@ -76,7 +84,7 @@ void Game::draw()
{
const std::lock_guard lock(game_mutex);
renderer.clear_screen(0x80, 0x40, 0xFF, 0xFF);
renderer.clear_screen(rgb(0x80, 0x40, 0xFF));
map.draw(player.x, player.y);
@ -90,6 +98,12 @@ void Game::draw()
player.draw();
renderer.draw_sprite(*gold_sprite, renderer.screen_width - 50, 10);
int text_width = renderer.get_text_width(font, std::to_string(player.gold));
renderer.draw_text(font, std::to_string(player.gold), renderer.screen_width - gold_sprite->width - text_width - 28, 10, rgb(0, 0, 0));
renderer.draw_text(font, std::to_string(player.gold), renderer.screen_width - gold_sprite->width - text_width - 30, 8, rgb(255, 255, 255));
renderer.flush();
}

View File

@ -17,7 +17,8 @@ private:
Map map;
std::vector<Arrow> arrows;
std::vector<Zombo> zombos;
std::unique_ptr<Sprite> arrow_sprite, zombo_sprite;
std::unique_ptr<Sprite> arrow_sprite, zombo_sprite, gold_sprite;
Font *font;
std::mutex game_mutex;
unsigned int ticks = 0;

View File

@ -1,4 +1,5 @@
#include <SDL2/SDL_image.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <memory>
#include <iostream>
#include "Sprite.hpp"
@ -12,6 +13,11 @@ GameRenderer::GameRenderer(const std::string &title, const int screen_width, con
exit(EXIT_FAILURE);
}
if (TTF_Init() < 0) {
std::cerr << "Unable to initialize SDL_ttf" << std::endl;
exit(EXIT_FAILURE);
}
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
window = SDL_CreateWindow(
@ -40,6 +46,26 @@ GameRenderer::~GameRenderer()
SDL_DestroyWindow(window);
}
Font *GameRenderer::load_font(const std::string &file, int font_size)
{
return TTF_OpenFont(file.c_str(), font_size);
}
int GameRenderer::get_text_width(Font *font, const std::string &text) const
{
SDL_Surface *surface = TTF_RenderText_Solid(font, text.c_str(), rgb(0, 0, 0));
return surface->w;
}
void GameRenderer::draw_text(Font *font, const std::string &text, int x, int y, Color color) const
{
SDL_Surface *surface = TTF_RenderText_Solid(font, text.c_str(), color);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect textRect = { .x = x, .y = y, .w = surface->w, .h = surface->h };
SDL_RenderCopy(renderer, texture, nullptr, &textRect);
}
std::unique_ptr<Sprite> GameRenderer::load_sprite(const std::string &file, const int width, const int height) const
{
return std::make_unique<Sprite>(renderer, file, width, height);
@ -63,9 +89,9 @@ void GameRenderer::draw_sprite_rotated(const Sprite &sprite, const int x, const
SDL_RenderCopyEx(renderer, sprite.texture, nullptr, &rect, angle, nullptr, SDL_FLIP_NONE);
}
void GameRenderer::clear_screen(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) const
void GameRenderer::clear_screen(Color color) const
{
SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderClear(renderer);
}

View File

@ -4,7 +4,11 @@
#include <memory>
#include <string>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "Sprite.hpp"
#include "Color.hpp"
typedef TTF_Font Font;
class GameRenderer
{
@ -22,7 +26,13 @@ public:
~GameRenderer();
std::unique_ptr<Sprite> load_sprite(const std::string &file, int width, int height) const;
[[nodiscard]] Font *load_font(const std::string &file, int font_size);
int get_text_width(Font *font, const std::string &text) const;
void draw_text(Font *font, const std::string &text, int x, int y, Color color) const;
[[nodiscard]] std::unique_ptr<Sprite> load_sprite(const std::string &file, int width, int height) const;
void draw_sprite(const Sprite &sprite, int x, int y) const;
@ -30,7 +40,7 @@ public:
void draw_sprite_rotated(const Sprite &sprite, int x, int y, double angle) const;
void clear_screen(uint8_t r, uint8_t g, uint8_t b, uint8_t a) const;
void clear_screen(Color color) const;
void flush() const;

View File

@ -21,6 +21,8 @@ public:
int shooting_cooldown = 0;
int gold = 0;
static constexpr double speed = 1.5;
Player(GameRenderer *renderer);