Add score text
This commit is contained in:
BIN
assets/fonts/OpenTTD-Sans.ttf
Normal file
BIN
assets/fonts/OpenTTD-Sans.ttf
Normal file
Binary file not shown.
@@ -21,6 +21,10 @@ static constexpr uint8_t BACKGROUND_MUSIC_DATA[] = {
|
|||||||
#embed "../assets/sounds/JamaicanSunrise.wav"
|
#embed "../assets/sounds/JamaicanSunrise.wav"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr uint8_t DEFAULT_FONT_DATA[] = {
|
||||||
|
#embed "../assets/fonts/OpenTTD-Sans.ttf"
|
||||||
|
};
|
||||||
|
|
||||||
SDL_Texture* load_texture(uint8_t const* data, size_t size, SDL_Renderer* renderer)
|
SDL_Texture* load_texture(uint8_t const* data, size_t size, SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
auto* iostream = SDL_IOFromConstMem(data, size);
|
auto* iostream = SDL_IOFromConstMem(data, size);
|
||||||
@@ -53,6 +57,18 @@ AudioAsset load_audio(uint8_t const* data, size_t size)
|
|||||||
return audio_asset;
|
return audio_asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FontAsset load_font(uint8_t const* data, size_t size)
|
||||||
|
{
|
||||||
|
FontAsset font_asset;
|
||||||
|
|
||||||
|
auto* iostream = SDL_IOFromConstMem(data, size);
|
||||||
|
auto* ttf = TTF_OpenFontIO(iostream, false, 20);
|
||||||
|
|
||||||
|
font_asset.font = ttf;
|
||||||
|
|
||||||
|
return font_asset;
|
||||||
|
}
|
||||||
|
|
||||||
AssetModule::AssetModule(flecs::world& world)
|
AssetModule::AssetModule(flecs::world& world)
|
||||||
{
|
{
|
||||||
auto* renderer = world.get<SdlHandles>()->renderer;
|
auto* renderer = world.get<SdlHandles>()->renderer;
|
||||||
@@ -73,4 +89,7 @@ AssetModule::AssetModule(flecs::world& world)
|
|||||||
|
|
||||||
auto background_music = load_audio(BACKGROUND_MUSIC_DATA, sizeof(BACKGROUND_MUSIC_DATA));
|
auto background_music = load_audio(BACKGROUND_MUSIC_DATA, sizeof(BACKGROUND_MUSIC_DATA));
|
||||||
world.set<AudioAssets>(AudioAssets{.background_music = background_music});
|
world.set<AudioAssets>(AudioAssets{.background_music = background_music});
|
||||||
|
|
||||||
|
auto font = load_font(DEFAULT_FONT_DATA, sizeof(DEFAULT_FONT_DATA));
|
||||||
|
world.set<FontAssets>(FontAssets{.default_font = font});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "audio.hpp"
|
#include "audio.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3_ttf/SDL_ttf.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
|
|
||||||
struct TextureAtlasLayout
|
struct TextureAtlasLayout
|
||||||
@@ -31,6 +32,16 @@ struct AudioAssets
|
|||||||
AudioAsset background_music;
|
AudioAsset background_music;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FontAsset
|
||||||
|
{
|
||||||
|
TTF_Font* font;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FontAssets
|
||||||
|
{
|
||||||
|
FontAsset default_font;
|
||||||
|
};
|
||||||
|
|
||||||
struct AssetModule
|
struct AssetModule
|
||||||
{
|
{
|
||||||
AssetModule(flecs::world& world);
|
AssetModule(flecs::world& world);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3_ttf/SDL_ttf.h>
|
||||||
|
|
||||||
static constexpr int WINDOW_WIDTH = 400;
|
static constexpr int WINDOW_WIDTH = 400;
|
||||||
static constexpr int WINDOW_HEIGHT = 240;
|
static constexpr int WINDOW_HEIGHT = 240;
|
||||||
@@ -9,10 +10,12 @@ struct SdlHandles
|
|||||||
{
|
{
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
|
TTF_TextEngine* text_engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Game
|
struct Game
|
||||||
{
|
{
|
||||||
uint32_t ticks;
|
uint32_t ticks;
|
||||||
|
uint32_t time;
|
||||||
uint32_t score;
|
uint32_t score;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ struct LevelModule
|
|||||||
world.entity()
|
world.entity()
|
||||||
.child_of(basket)
|
.child_of(basket)
|
||||||
.add<WorldPosition>()
|
.add<WorldPosition>()
|
||||||
.set<Position>(Position{.x = 0, .y = 0})
|
.set<Position>(Position{.x = 0, .y = 16})
|
||||||
.set<Size>(Size{.w = 64, .h = 32})
|
.set<Size>(Size{.w = 64, .h = 16})
|
||||||
.add<CollisionBox>();
|
.add<CollisionBox>();
|
||||||
|
|
||||||
world.system<Game const, TextureAssets const>("SpawnFruits")
|
world.system<Game const, TextureAssets const>("SpawnFruits")
|
||||||
@@ -87,10 +87,15 @@ struct LevelModule
|
|||||||
// e.destruct();
|
// e.destruct();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
world.system<Game, Fruit, Collided>("CollectItem")
|
world.system<Game, Position, Fruit, Collided>("CollectItem")
|
||||||
.term_at(0)
|
.term_at(0)
|
||||||
.singleton()
|
.singleton()
|
||||||
.each([](flecs::entity e, Game& game, Fruit, Collided) { game.score += 10; });
|
.each(
|
||||||
|
[](flecs::entity e, Game& game, Position& pos, Fruit, Collided)
|
||||||
|
{
|
||||||
|
game.score += 10;
|
||||||
|
pos.x = 1000;
|
||||||
|
});
|
||||||
|
|
||||||
world.system<ButtonInput const, Position, Size const, Sprite const, Basket>("MoveBasket")
|
world.system<ButtonInput const, Position, Size const, Sprite const, Basket>("MoveBasket")
|
||||||
.term_at(0)
|
.term_at(0)
|
||||||
|
|||||||
44
src/main.cpp
44
src/main.cpp
@@ -11,6 +11,7 @@
|
|||||||
#include <SDL3/SDL_iostream.h>
|
#include <SDL3/SDL_iostream.h>
|
||||||
#include <SDL3/SDL_render.h>
|
#include <SDL3/SDL_render.h>
|
||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
|
#include <SDL3_ttf/SDL_ttf.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ int main()
|
|||||||
std::terminate();
|
std::terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTF_Init();
|
||||||
|
|
||||||
auto* window = SDL_CreateWindow("HansTheGatherer", WINDOW_WIDTH, WINDOW_HEIGHT, 0);
|
auto* window = SDL_CreateWindow("HansTheGatherer", WINDOW_WIDTH, WINDOW_HEIGHT, 0);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
@@ -38,11 +41,14 @@ int main()
|
|||||||
spdlog::critical("Failed to create SDL renderer!\nCause: {}", SDL_GetError());
|
spdlog::critical("Failed to create SDL renderer!\nCause: {}", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* text_engine = TTF_CreateRendererTextEngine(renderer);
|
||||||
|
|
||||||
flecs::world world;
|
flecs::world world;
|
||||||
|
|
||||||
world.set<Game>(Game{.ticks = 0});
|
world.set<Game>(Game{.ticks = 0, .time = 60, .score = 0});
|
||||||
world.set<ButtonInput>(ButtonInput{});
|
world.set<ButtonInput>(ButtonInput{});
|
||||||
world.set<SdlHandles>(SdlHandles{.window = window, .renderer = renderer});
|
world.set<SdlHandles>(
|
||||||
|
SdlHandles{.window = window, .renderer = renderer, .text_engine = text_engine});
|
||||||
|
|
||||||
world.import <AssetModule>();
|
world.import <AssetModule>();
|
||||||
world.import <PhysicsModule>();
|
world.import <PhysicsModule>();
|
||||||
@@ -51,10 +57,19 @@ int main()
|
|||||||
world.system<Game>("IncrementTicks")
|
world.system<Game>("IncrementTicks")
|
||||||
.term_at(0)
|
.term_at(0)
|
||||||
.singleton()
|
.singleton()
|
||||||
.each([](Game& game_ticks) { game_ticks.ticks += 1; });
|
.each(
|
||||||
|
[](Game& game)
|
||||||
|
{
|
||||||
|
game.ticks += 1;
|
||||||
|
|
||||||
|
if (game.ticks % 60 == 0)
|
||||||
|
{
|
||||||
|
game.time--;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
world.system<SdlHandles const, Position const, Size const, Sprite const>("RenderSprites")
|
world.system<SdlHandles const, Position const, Size const, Sprite const>("RenderSprites")
|
||||||
.kind(flecs::PreUpdate)
|
.kind(flecs::OnStore)
|
||||||
.term_at(0)
|
.term_at(0)
|
||||||
.singleton()
|
.singleton()
|
||||||
.each(
|
.each(
|
||||||
@@ -80,6 +95,27 @@ int main()
|
|||||||
sdl_handles.renderer, sprite.texture->sdl_texture, &srcrect, &dstrect);
|
sdl_handles.renderer, sprite.texture->sdl_texture, &srcrect, &dstrect);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
world.system<SdlHandles const, Game const, FontAssets const>("RenderScore")
|
||||||
|
.kind(flecs::OnStore)
|
||||||
|
.term_at(0)
|
||||||
|
.singleton()
|
||||||
|
.term_at(1)
|
||||||
|
.singleton()
|
||||||
|
.term_at(2)
|
||||||
|
.singleton()
|
||||||
|
.each(
|
||||||
|
[](SdlHandles const& sdl_handles, Game const& game, FontAssets const& font_assets)
|
||||||
|
{
|
||||||
|
auto score_string = std::format("Score: {}\nTime: {}", game.score, game.time);
|
||||||
|
auto text = TTF_CreateText(sdl_handles.text_engine,
|
||||||
|
font_assets.default_font.font,
|
||||||
|
score_string.c_str(),
|
||||||
|
score_string.length());
|
||||||
|
TTF_DrawRendererText(text, 0.0, 0.0);
|
||||||
|
|
||||||
|
TTF_DestroyText(text);
|
||||||
|
});
|
||||||
|
|
||||||
auto* audio_assets = world.get<AudioAssets>();
|
auto* audio_assets = world.get<AudioAssets>();
|
||||||
auto* stream = SDL_OpenAudioDeviceStream(
|
auto* stream = SDL_OpenAudioDeviceStream(
|
||||||
SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_assets->background_music.spec, NULL, NULL);
|
SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_assets->background_music.spec, NULL, NULL);
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ PhysicsModule::PhysicsModule(flecs::world& world)
|
|||||||
|
|
||||||
auto basket_query = world.query<Basket>();
|
auto basket_query = world.query<Basket>();
|
||||||
|
|
||||||
|
world.system<Collided>("RemoveCollisionMarker")
|
||||||
|
.kind(flecs::PreUpdate)
|
||||||
|
.each([](flecs::entity e, Collided) { e.remove<Collided>(); });
|
||||||
|
|
||||||
world.system<WorldPosition const, Size const, CollisionBox>("CollisionCheck")
|
world.system<WorldPosition const, Size const, CollisionBox>("CollisionCheck")
|
||||||
.kind(flecs::OnValidate)
|
.kind(flecs::OnValidate)
|
||||||
.each(
|
.each(
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": [
|
|
||||||
"spdlog",
|
|
||||||
"sdl3",
|
|
||||||
"spdlog",
|
|
||||||
"flecs"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user