diff --git a/assets/fonts/OpenTTD-Sans.ttf b/assets/fonts/OpenTTD-Sans.ttf new file mode 100644 index 0000000..7c3dbda Binary files /dev/null and b/assets/fonts/OpenTTD-Sans.ttf differ diff --git a/src/assets.cpp b/src/assets.cpp index 7fb8e12..3b71e20 100644 --- a/src/assets.cpp +++ b/src/assets.cpp @@ -21,6 +21,10 @@ static constexpr uint8_t BACKGROUND_MUSIC_DATA[] = { #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) { auto* iostream = SDL_IOFromConstMem(data, size); @@ -53,6 +57,18 @@ AudioAsset load_audio(uint8_t const* data, size_t size) 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) { auto* renderer = world.get()->renderer; @@ -73,4 +89,7 @@ AssetModule::AssetModule(flecs::world& world) auto background_music = load_audio(BACKGROUND_MUSIC_DATA, sizeof(BACKGROUND_MUSIC_DATA)); world.set(AudioAssets{.background_music = background_music}); + + auto font = load_font(DEFAULT_FONT_DATA, sizeof(DEFAULT_FONT_DATA)); + world.set(FontAssets{.default_font = font}); } diff --git a/src/assets.hpp b/src/assets.hpp index d7766d1..9ba327e 100644 --- a/src/assets.hpp +++ b/src/assets.hpp @@ -3,6 +3,7 @@ #include "audio.hpp" #include +#include #include struct TextureAtlasLayout @@ -31,6 +32,16 @@ struct AudioAssets AudioAsset background_music; }; +struct FontAsset +{ + TTF_Font* font; +}; + +struct FontAssets +{ + FontAsset default_font; +}; + struct AssetModule { AssetModule(flecs::world& world); diff --git a/src/definitions.hpp b/src/definitions.hpp index f505a89..939df87 100644 --- a/src/definitions.hpp +++ b/src/definitions.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include static constexpr int WINDOW_WIDTH = 400; static constexpr int WINDOW_HEIGHT = 240; @@ -9,10 +10,12 @@ struct SdlHandles { SDL_Window* window; SDL_Renderer* renderer; + TTF_TextEngine* text_engine; }; struct Game { uint32_t ticks; + uint32_t time; uint32_t score; }; diff --git a/src/level.hpp b/src/level.hpp index b4ad5fe..2e71aaf 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -38,8 +38,8 @@ struct LevelModule world.entity() .child_of(basket) .add() - .set(Position{.x = 0, .y = 0}) - .set(Size{.w = 64, .h = 32}) + .set(Position{.x = 0, .y = 16}) + .set(Size{.w = 64, .h = 16}) .add(); world.system("SpawnFruits") @@ -87,10 +87,15 @@ struct LevelModule // e.destruct(); // }); - world.system("CollectItem") + world.system("CollectItem") .term_at(0) .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("MoveBasket") .term_at(0) diff --git a/src/main.cpp b/src/main.cpp index 4e2a9ab..0e815aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,8 @@ int main() std::terminate(); } + TTF_Init(); + auto* window = SDL_CreateWindow("HansTheGatherer", WINDOW_WIDTH, WINDOW_HEIGHT, 0); if (window == nullptr) { @@ -38,11 +41,16 @@ int main() spdlog::critical("Failed to create SDL renderer!\nCause: {}", SDL_GetError()); } - flecs::world world; + auto* text_engine = TTF_CreateRendererTextEngine(renderer); - world.set(Game{.ticks = 0}); + flecs::world world; + world.import (); + world.set({}); + + world.set(Game{.ticks = 0, .time = 60, .score = 0}); world.set(ButtonInput{}); - world.set(SdlHandles{.window = window, .renderer = renderer}); + world.set( + SdlHandles{.window = window, .renderer = renderer, .text_engine = text_engine}); world.import (); world.import (); @@ -51,10 +59,19 @@ int main() world.system("IncrementTicks") .term_at(0) .singleton() - .each([](Game& game_ticks) { game_ticks.ticks += 1; }); + .each( + [](Game& game) + { + game.ticks += 1; + + if (game.ticks % 60 == 0) + { + game.time--; + } + }); world.system("RenderSprites") - .kind(flecs::PreUpdate) + .kind(flecs::OnStore) .term_at(0) .singleton() .each( @@ -80,6 +97,27 @@ int main() sdl_handles.renderer, sprite.texture->sdl_texture, &srcrect, &dstrect); }); + world.system("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(); auto* stream = SDL_OpenAudioDeviceStream( SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_assets->background_music.spec, NULL, NULL); diff --git a/src/physics.cpp b/src/physics.cpp index c8df384..4e002d2 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -48,6 +48,10 @@ PhysicsModule::PhysicsModule(flecs::world& world) auto basket_query = world.query(); + world.system("RemoveCollisionMarker") + .kind(flecs::PreUpdate) + .each([](flecs::entity e, Collided) { e.remove(); }); + world.system("CollisionCheck") .kind(flecs::OnValidate) .each(