From 8602e25c6301eb91ec9d4ba636214950daa8ce56 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Fri, 14 Jun 2024 12:54:25 +0530 Subject: [PATCH 1/7] bgf v0.1.1 --- CMakeLists.txt | 2 +- src/spaced/spaced/game/enemy.cpp | 2 -- src/spaced/spaced/scenes/load_assets.cpp | 8 +---- src/spaced/spaced/spaced.cpp | 45 ++++++++++++------------ src/spaced/spaced/spaced.hpp | 2 +- 5 files changed, 25 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88c1028..7ca5342 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(FetchContent) FetchContent_Declare( bgf GIT_REPOSITORY https://github.com/karnkaul/bgf - GIT_TAG v0.1.0 + GIT_TAG v0.1.1 SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bgf" ) diff --git a/src/spaced/spaced/game/enemy.cpp b/src/spaced/spaced/game/enemy.cpp index 77cd6d3..048a9d4 100644 --- a/src/spaced/spaced/game/enemy.cpp +++ b/src/spaced/spaced/game/enemy.cpp @@ -13,8 +13,6 @@ using bave::Services; using bave::Shader; using bave::Styles; -namespace ui = bave::ui; - Enemy::Enemy(Services const& services, std::string_view const type) : m_layout(&services.get()), m_health_bar(services), m_type(type) { static constexpr auto init_size_v = glm::vec2{100.0f}; auto const play_area = m_layout->play_area; diff --git a/src/spaced/spaced/scenes/load_assets.cpp b/src/spaced/spaced/scenes/load_assets.cpp index 5482362..ff71292 100644 --- a/src/spaced/spaced/scenes/load_assets.cpp +++ b/src/spaced/spaced/scenes/load_assets.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -10,18 +9,13 @@ namespace spaced { using bave::App; using bave::AsyncExec; using bave::Loader; -using bave::Resources; using bave::Services; namespace { auto make_load_stages(Loader loader, Services const& services) -> std::vector { auto asset_list = AssetList{std::move(loader), services}; asset_list.add_manifest(GameScene::get_manifest()); - auto ret = asset_list.build_task_stages(); - auto& stage = ret.emplace_back(); - auto& resources = services.get(); - stage.push_back(util::create_font_atlas_task(resources.main_font, MenuScene::get_text_heights())); - return ret; + return asset_list.build_task_stages(); } } // namespace diff --git a/src/spaced/spaced/spaced.cpp b/src/spaced/spaced/spaced.cpp index 7db77e3..b6a84ea 100644 --- a/src/spaced/spaced/spaced.cpp +++ b/src/spaced/spaced/spaced.cpp @@ -12,25 +12,21 @@ #include #include #include +#include namespace spaced { namespace { using bave::App; -using bave::AudioClip; -using bave::AudioDevice; -using bave::AudioStreamer; +using bave::GameDriver; using bave::Gamepad; using bave::IAudio; using bave::IDisplay; -using bave::Loader; using bave::NotNull; using bave::Persistor; using bave::Rect; -using bave::RenderDevice; -using bave::RenderView; -using bave::Resources; using bave::Seconds; using bave::Styles; +using bave::TextHeight; struct GamepadProvider : IGamepadProvider { bave::App& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) @@ -64,39 +60,42 @@ struct PersistentStats : Stats { persistor.write_json(uri_v, json); } }; + +constexpr auto preload_text_heights_v = std::array{TextHeight{100}, TextHeight{60}}; + +constexpr auto gdci_v = bave::GameDriver::CreateInfo{ + .assets = + { + .main_font = + { + .uri = "fonts/CuteDino.otf", + .preload_heights = preload_text_heights_v, + }, + .spinner = "images/spinner.png", + .styles = "styles.json", + }, +}; } // namespace void Spaced::set_bindings([[maybe_unused]] Serializer& serializer) {} -Spaced::Spaced(App& app) : GameDriver(app) { +Spaced::Spaced(App& app) : GameDriver(app, gdci_v) { m_log.info("using MSAA: {}x", static_cast(app.get_render_device().get_sample_count())); - load_resources(); + save_styles(); set_layout(); create_services(); set_prefs(); set_scene(); } -void Spaced::load_resources() { - auto const loader = Loader{&get_app().get_data_store(), &get_app().get_render_device()}; - m_resources = &m_services.get(); - m_resources->main_font = loader.load_font("fonts/CuteDino.otf"); - m_resources->spinner = loader.load_texture("images/spinner.png", true); - - auto styles = std::make_unique(); - if (auto const json = loader.load_json("styles.json")) { - *styles = Styles::load(json); - m_log.info("loaded Styles from 'styles.json'"); - } - +void Spaced::save_styles() { if constexpr (bave::debug_v) { static bool s_save_styles{}; if (s_save_styles) { - auto const json = styles->save(); + auto const json = m_services.get().save(); json.to_file("styles.json"); } } - m_services.bind(std::move(styles)); } void Spaced::create_services() { diff --git a/src/spaced/spaced/spaced.hpp b/src/spaced/spaced/spaced.hpp index e534ef8..9389a9d 100644 --- a/src/spaced/spaced/spaced.hpp +++ b/src/spaced/spaced/spaced.hpp @@ -17,7 +17,7 @@ class Spaced : public bave::GameDriver { private: static void set_bindings(Serializer& serializer); - void load_resources(); + void save_styles(); void create_services(); void set_layout(); void set_prefs(); From a5bbe28942f2966f50075be19eab26b2f50ef516 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Fri, 14 Jun 2024 19:25:22 +0530 Subject: [PATCH 2/7] Prepare to migrate assets/ code to bgf. --- src/spaced/spaced/assets/asset_list.cpp | 60 +++++++++++---------- src/spaced/spaced/assets/asset_list.hpp | 33 +++++------- src/spaced/spaced/assets/asset_loader.cpp | 42 ++++++--------- src/spaced/spaced/assets/asset_loader.hpp | 8 +-- src/spaced/spaced/assets/asset_manifest.cpp | 18 +++++++ src/spaced/spaced/assets/asset_manifest.hpp | 12 ++++- src/spaced/spaced/scenes/game.cpp | 34 ++++++++---- src/spaced/spaced/scenes/game.hpp | 7 +-- src/spaced/spaced/scenes/load_assets.cpp | 27 ---------- src/spaced/spaced/scenes/load_assets.hpp | 13 ----- src/spaced/spaced/scenes/menu.cpp | 17 +++++- src/spaced/spaced/scenes/menu.hpp | 7 ++- src/spaced/spaced/spaced.cpp | 4 +- 13 files changed, 146 insertions(+), 136 deletions(-) create mode 100644 src/spaced/spaced/assets/asset_manifest.cpp delete mode 100644 src/spaced/spaced/scenes/load_assets.cpp delete mode 100644 src/spaced/spaced/scenes/load_assets.hpp diff --git a/src/spaced/spaced/assets/asset_list.cpp b/src/spaced/spaced/assets/asset_list.cpp index c7edeb9..22994b1 100644 --- a/src/spaced/spaced/assets/asset_list.cpp +++ b/src/spaced/spaced/assets/asset_list.cpp @@ -12,25 +12,25 @@ AssetList::AssetList(Loader loader, Services const& services) : m_loader(std::mo auto AssetList::add_texture(std::string uri, bool const mip_map) -> AssetList& { if (uri.empty()) { return *this; } - m_textures.insert(Tex{.uri = std::move(uri), .mip_map = mip_map}); + m_textures.insert_or_assign(std::move(uri), mip_map); return *this; } -auto AssetList::add_font(std::string uri) -> AssetList& { +auto AssetList::add_nine_slice(std::string uri) -> AssetList& { if (uri.empty()) { return *this; } - m_fonts.insert(std::move(uri)); + m_nine_slices.insert(std::move(uri)); return *this; } -auto AssetList::add_particle_emitter(std::string uri) -> AssetList& { +auto AssetList::add_atlas(std::string uri, bool const mip_map) -> AssetList& { if (uri.empty()) { return *this; } + m_atlases.insert_or_assign(std::move(uri), mip_map); + return *this; +} - auto const json = m_loader.load_json(uri); - if (!json) { return *this; } - - // emitters require textures (stage 0) to be loaded, and must be loaded in stage 1 - if (auto const& texture = json["texture"]) { add_texture(texture.as()); } - m_emitters.insert(std::move(uri)); +auto AssetList::add_font(std::string uri) -> AssetList& { + if (uri.empty()) { return *this; } + m_fonts.insert(std::move(uri)); return *this; } @@ -40,33 +40,39 @@ auto AssetList::add_audio_clip(std::string uri) -> AssetList& { return *this; } +auto AssetList::add_anim_timeline(std::string uri) -> AssetList& { + if (uri.empty()) { return *this; } + m_anim_timelines.insert(std::move(uri)); + return *this; +} + +auto AssetList::add_particle_emitter(std::string uri) -> AssetList& { + if (uri.empty()) { return *this; } + m_emitters.insert(std::move(uri)); + return *this; +} + void AssetList::add_manifest(AssetManifest manifest) { - for (auto& uri : manifest.textures) { add_texture(std::move(uri), false); } - for (auto& uri : manifest.mip_mapped_textures) { add_texture(std::move(uri), true); } + for (auto& uri : manifest.flat_textures) { add_texture(std::move(uri), false); } + for (auto& uri : manifest.textures) { add_texture(std::move(uri), true); } + for (auto& uri : manifest.nine_slices) { add_nine_slice(std::move(uri)); } + for (auto& uri : manifest.flat_atlases) { add_atlas(std::move(uri), false); } + for (auto& uri : manifest.atlases) { add_atlas(std::move(uri), true); } for (auto& uri : manifest.fonts) { add_font(std::move(uri)); } for (auto& uri : manifest.audio_clips) { add_audio_clip(std::move(uri)); } + for (auto& uri : manifest.anim_timelines) { add_anim_timeline(std::move(uri)); } for (auto& uri : manifest.particle_emitters) { add_particle_emitter(std::move(uri)); } } -auto AssetList::build_task_stages() const -> std::vector { - auto ret = std::vector{}; - ret.reserve(2); +auto AssetList::build_load_stage() const -> AsyncExec::Stage { auto asset_loader = AssetLoader{m_loader, m_resources}; - ret.push_back(build_stage_0(asset_loader)); - ret.push_back(build_stage_1(asset_loader)); - return ret; -} - -auto AssetList::build_stage_0(AssetLoader& asset_loader) const -> AsyncExec::Stage { auto ret = AsyncExec::Stage{}; - for (auto const& texture : m_textures) { ret.push_back(asset_loader.make_load_texture(texture.uri, texture.mip_map)); } + for (auto const& [uri, mip_map] : m_textures) { ret.push_back(asset_loader.make_load_texture(uri, mip_map)); } + for (auto const& uri : m_nine_slices) { ret.push_back(asset_loader.make_load_nine_slice(uri)); } + for (auto const& [uri, mip_map] : m_atlases) { ret.push_back(asset_loader.make_load_atlas(uri, mip_map)); } for (auto const& font : m_fonts) { ret.push_back(asset_loader.make_load_font(font)); } for (auto const& audio_clip : m_audio_clips) { ret.push_back(asset_loader.make_load_audio_clip(audio_clip)); } - return ret; -} - -auto AssetList::build_stage_1(AssetLoader& asset_loader) const -> AsyncExec::Stage { - auto ret = AsyncExec::Stage{}; + for (auto const& anim_timeline : m_anim_timelines) { ret.push_back(asset_loader.make_load_anim_timeline(anim_timeline)); } for (auto const& emitter : m_emitters) { ret.push_back(asset_loader.make_load_particle_emitter(emitter)); } return ret; } diff --git a/src/spaced/spaced/assets/asset_list.hpp b/src/spaced/spaced/assets/asset_list.hpp index a2debc1..036d8b9 100644 --- a/src/spaced/spaced/assets/asset_list.hpp +++ b/src/spaced/spaced/assets/asset_list.hpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include namespace bave { struct Resources; @@ -18,33 +19,27 @@ class AssetList { explicit AssetList(bave::Loader loader, bave::Services const& services); auto add_texture(std::string uri, bool mip_map = false) -> AssetList&; + auto add_nine_slice(std::string uri) -> AssetList&; + auto add_atlas(std::string uri, bool mip_map = false) -> AssetList&; auto add_font(std::string uri) -> AssetList&; - auto add_particle_emitter(std::string uri) -> AssetList&; auto add_audio_clip(std::string uri) -> AssetList&; + auto add_anim_timeline(std::string uri) -> AssetList&; + auto add_particle_emitter(std::string uri) -> AssetList&; void add_manifest(AssetManifest manifest); - [[nodiscard]] auto build_task_stages() const -> std::vector; + [[nodiscard]] auto build_load_stage() const -> bave::AsyncExec::Stage; private: - struct Tex { - std::string uri{}; - bool mip_map{}; - - // MacOS doesn't provide operator<=> for strings :/ - auto operator==(Tex const& rhs) const -> bool { return uri == rhs.uri; } - auto operator<(Tex const& rhs) const -> bool { return uri < rhs.uri; } - }; - - auto build_stage_0(AssetLoader& asset_loader) const -> bave::AsyncExec::Stage; - auto build_stage_1(AssetLoader& asset_loader) const -> bave::AsyncExec::Stage; - bave::Loader m_loader; bave::NotNull m_resources; - std::set m_textures{}; - std::set m_fonts{}; - std::set m_emitters{}; - std::set m_audio_clips{}; + std::unordered_map m_textures{}; + std::unordered_set m_nine_slices{}; + std::unordered_map m_atlases{}; + std::unordered_set m_fonts{}; + std::unordered_set m_audio_clips{}; + std::unordered_set m_anim_timelines{}; + std::unordered_set m_emitters{}; }; } // namespace spaced diff --git a/src/spaced/spaced/assets/asset_loader.cpp b/src/spaced/spaced/assets/asset_loader.cpp index c995b61..8f192ce 100644 --- a/src/spaced/spaced/assets/asset_loader.cpp +++ b/src/spaced/spaced/assets/asset_loader.cpp @@ -1,19 +1,14 @@ #include #include -#include #include #include namespace spaced { using bave::Loader; -using bave::Logger; using bave::NotNull; -using bave::ParticleEmitter; using bave::Resources; -using bave::Texture; struct AssetLoader::Impl { - Logger log{"AssetLoader"}; Loader loader; NotNull resources; std::mutex mutex{}; @@ -21,36 +16,23 @@ struct AssetLoader::Impl { AssetLoader::AssetLoader(Loader loader, NotNull resources) : m_impl(new Impl{.loader = std::move(loader), .resources = resources}) {} -auto AssetLoader::make_load_font(std::string uri, bool reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_font(uri); }; +auto AssetLoader::make_load_texture(std::string uri, bool mip_map, bool reload) -> LoadTask { + auto const load = [mip_map](Loader const& loader, std::string_view const uri) { return loader.load_texture(uri, mip_map); }; return make_load_task(std::move(uri), reload, load); } -auto AssetLoader::make_load_texture(std::string uri, bool mip_map, bool reload) -> LoadTask { - auto const load = [mip_map](Loader const& loader, std::string_view const uri) { return loader.load_texture(uri, mip_map); }; +auto AssetLoader::make_load_nine_slice(std::string uri, bool reload) -> LoadTask { + auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_texture_9slice(uri); }; return make_load_task(std::move(uri), reload, load); } -auto AssetLoader::make_load_texture_atlas(std::string uri, bool mip_map, bool reload) -> LoadTask { +auto AssetLoader::make_load_atlas(std::string uri, bool mip_map, bool reload) -> LoadTask { auto const load = [mip_map](Loader const& loader, std::string_view const uri) { return loader.load_texture_atlas(uri, mip_map); }; return make_load_task(std::move(uri), reload, load); } -auto AssetLoader::make_load_particle_emitter(std::string uri, bool const reload) -> LoadTask { - auto const load = [impl = m_impl.get()](Loader const& loader, std::string_view const uri) -> std::shared_ptr { - auto const json = loader.load_json(uri); - if (!json) { return {}; } - - auto ret = std::make_shared(); - bave::from_json(json["config"], ret->config); - if (auto const& texture = json["texture"]) { - auto lock = std::scoped_lock{impl->mutex}; - ret->set_texture(impl->resources->get(texture.as_string())); - } - - impl->log.info("loaded ParticleEmitter: '{}'", uri); - return ret; - }; +auto AssetLoader::make_load_font(std::string uri, bool reload) -> LoadTask { + auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_font(uri); }; return make_load_task(std::move(uri), reload, load); } @@ -59,6 +41,16 @@ auto AssetLoader::make_load_audio_clip(std::string uri, bool const reload) -> Lo return make_load_task(std::move(uri), reload, load); } +auto AssetLoader::make_load_anim_timeline(std::string uri, bool const reload) -> LoadTask { + auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_anim_timeline(uri); }; + return make_load_task(std::move(uri), reload, load); +} + +auto AssetLoader::make_load_particle_emitter(std::string uri, bool const reload) -> LoadTask { + auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_particle_emitter(uri); }; + return make_load_task(std::move(uri), reload, load); +} + template auto AssetLoader::make_load_task(std::string uri, bool reload, FuncT load) const -> LoadTask { return [impl = m_impl, uri = std::move(uri), reload, load] { diff --git a/src/spaced/spaced/assets/asset_loader.hpp b/src/spaced/spaced/assets/asset_loader.hpp index 22c9bf4..41b54f8 100644 --- a/src/spaced/spaced/assets/asset_loader.hpp +++ b/src/spaced/spaced/assets/asset_loader.hpp @@ -12,11 +12,13 @@ class AssetLoader { explicit AssetLoader(bave::Loader loader, bave::NotNull resources); - [[nodiscard]] auto make_load_font(std::string uri, bool reload = false) -> LoadTask; [[nodiscard]] auto make_load_texture(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_texture_atlas(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_particle_emitter(std::string uri, bool reload = false) -> LoadTask; + [[nodiscard]] auto make_load_nine_slice(std::string uri, bool reload = false) -> LoadTask; + [[nodiscard]] auto make_load_atlas(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask; + [[nodiscard]] auto make_load_font(std::string uri, bool reload = false) -> LoadTask; [[nodiscard]] auto make_load_audio_clip(std::string uri, bool reload = false) -> LoadTask; + [[nodiscard]] auto make_load_anim_timeline(std::string uri, bool reload = false) -> LoadTask; + [[nodiscard]] auto make_load_particle_emitter(std::string uri, bool reload = false) -> LoadTask; private: template diff --git a/src/spaced/spaced/assets/asset_manifest.cpp b/src/spaced/spaced/assets/asset_manifest.cpp new file mode 100644 index 0000000..e112d9d --- /dev/null +++ b/src/spaced/spaced/assets/asset_manifest.cpp @@ -0,0 +1,18 @@ +#include +#include + +namespace spaced { +auto AssetManifest::load_from(dj::Json const& json) -> AssetManifest { + auto ret = AssetManifest{}; + for (auto const& texture : json["textures"].array_view()) { ret.textures.push_back(texture.as()); } + for (auto const& texture : json["flat_textures"].array_view()) { ret.flat_textures.push_back(texture.as()); } + for (auto const& atlas : json["atlases"].array_view()) { ret.atlases.push_back(atlas.as()); } + for (auto const& atlas : json["flat_atlases"].array_view()) { ret.flat_atlases.push_back(atlas.as()); } + for (auto const& slice : json["nine_slices"].array_view()) { ret.nine_slices.push_back(slice.as()); } + for (auto const& font : json["fonts"].array_view()) { ret.fonts.push_back(font.as()); } + for (auto const& timeline : json["anim_timelines"].array_view()) { ret.anim_timelines.push_back(timeline.as()); } + for (auto const& clip : json["audio_clips"].array_view()) { ret.audio_clips.push_back(clip.as()); } + for (auto const& emitter : json["particle_emitters"].array_view()) { ret.particle_emitters.push_back(emitter.as()); } + return ret; +} +} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_manifest.hpp b/src/spaced/spaced/assets/asset_manifest.hpp index 471c73f..ca0803b 100644 --- a/src/spaced/spaced/assets/asset_manifest.hpp +++ b/src/spaced/spaced/assets/asset_manifest.hpp @@ -2,12 +2,22 @@ #include #include +namespace dj { +class Json; +} + namespace spaced { struct AssetManifest { + std::vector flat_textures{}; std::vector textures{}; - std::vector mip_mapped_textures{}; + std::vector nine_slices{}; + std::vector flat_atlases{}; + std::vector atlases{}; std::vector fonts{}; std::vector audio_clips{}; + std::vector anim_timelines{}; std::vector particle_emitters{}; + + static auto load_from(dj::Json const& json) -> AssetManifest; }; } // namespace spaced diff --git a/src/spaced/spaced/scenes/game.cpp b/src/spaced/spaced/scenes/game.cpp index 5ab679d..c11d976 100644 --- a/src/spaced/spaced/scenes/game.cpp +++ b/src/spaced/spaced/scenes/game.cpp @@ -12,6 +12,7 @@ namespace spaced { using bave::Action; using bave::App; +using bave::AsyncExec; using bave::FocusChange; using bave::im_text; using bave::Key; @@ -44,8 +45,19 @@ auto GameScene::get_manifest() -> AssetManifest { }; } -GameScene::GameScene(App& app, Services const& services) : Scene(app, services, "Game"), m_save(&app), m_world(&services, this) { - clear_colour = services.get().rgbas["mocha"]; +GameScene::GameScene(App& app, Services const& services) : Scene(app, services, "Game"), m_save(&app) { clear_colour = services.get().rgbas["mocha"]; } + +auto GameScene::build_load_stages() -> std::vector { + auto ret = std::vector{}; + auto asset_list = AssetList{make_loader(), get_services()}; + asset_list.add_manifest(get_manifest()); + ret.push_back(asset_list.build_load_stage()); + return ret; +} + +void GameScene::on_loaded() { + auto const& services = get_services(); + m_world.emplace(&services, this); auto hud = std::make_unique(services); m_hud = hud.get(); @@ -53,28 +65,30 @@ GameScene::GameScene(App& app, Services const& services) : Scene(app, services, push_view(std::move(hud)); ++services.get().game.play_count; + + switch_track("music/game.mp3"); } -void GameScene::on_focus(FocusChange const& focus_change) { m_world.player.on_focus(focus_change); } +void GameScene::on_focus(FocusChange const& focus_change) { m_world->player.on_focus(focus_change); } void GameScene::on_key(KeyInput const& key_input) { if (key_input.key == Key::eEscape && key_input.action == Action::eRelease && key_input.mods == KeyMods{}) { get_switcher().switch_to(); } } -void GameScene::on_move(PointerMove const& pointer_move) { m_world.player.on_move(pointer_move); } +void GameScene::on_move(PointerMove const& pointer_move) { m_world->player.on_move(pointer_move); } -void GameScene::on_tap(PointerTap const& pointer_tap) { m_world.player.on_tap(pointer_tap); } +void GameScene::on_tap(PointerTap const& pointer_tap) { m_world->player.on_tap(pointer_tap); } void GameScene::tick(Seconds const dt) { auto ft = bave::DeltaTime{}; - m_world.tick(dt); - if (m_world.player.health.is_dead() && !m_game_over_dialog_pushed) { on_game_over(); } + m_world->tick(dt); + if (m_world->player.health.is_dead() && !m_game_over_dialog_pushed) { on_game_over(); } if constexpr (bave::debug_v) { inspect(dt, ft.update()); } } -void GameScene::render(Shader& shader) const { m_world.draw(shader); } +void GameScene::render(Shader& shader) const { m_world->draw(shader); } void GameScene::add_score(std::int64_t const score) { m_score += score; @@ -107,7 +121,7 @@ void GameScene::inspect(Seconds const dt, Seconds const frame_time) { if (ImGui::Begin("Debug")) { if (ImGui::BeginTabBar("World")) { - m_world.inspect(); + m_world->inspect(); ImGui::EndTabBar(); } @@ -115,7 +129,7 @@ void GameScene::inspect(Seconds const dt, Seconds const frame_time) { im_text("score: {}", get_score()); ImGui::Separator(); - if (ImGui::Button("end game")) { m_world.player.on_death({}); } + if (ImGui::Button("end game")) { m_world->player.on_death({}); } ImGui::Separator(); im_text("dt: {:05.2f}", std::chrono::duration(dt).count()); diff --git a/src/spaced/spaced/scenes/game.hpp b/src/spaced/spaced/scenes/game.hpp index 4566bb2..3e7e2b6 100644 --- a/src/spaced/spaced/scenes/game.hpp +++ b/src/spaced/spaced/scenes/game.hpp @@ -15,6 +15,9 @@ class GameScene : public bave::Scene, public IScorer { GameScene(bave::App& app, bave::Services const& services); private: + auto build_load_stages() -> std::vector final; + void on_loaded() final; + void on_focus(bave::FocusChange const& focus_change) final; void on_key(bave::KeyInput const& key_input) final; void on_move(bave::PointerMove const& pointer_move) final; @@ -23,8 +26,6 @@ class GameScene : public bave::Scene, public IScorer { void tick(bave::Seconds dt) final; void render(bave::Shader& shader) const final; - [[nodiscard]] auto get_music_uri() const -> std::string_view final { return "music/game.mp3"; } - [[nodiscard]] auto get_score() const -> std::int64_t final { return m_score; } void add_score(std::int64_t score) final; void on_game_over(); @@ -34,7 +35,7 @@ class GameScene : public bave::Scene, public IScorer { void inspect(bave::Seconds dt, bave::Seconds frame_time); GameSave m_save; - World m_world; + std::optional m_world{}; std::int64_t m_score{}; bave::Ptr m_hud{}; bool m_game_over_dialog_pushed{}; diff --git a/src/spaced/spaced/scenes/load_assets.cpp b/src/spaced/spaced/scenes/load_assets.cpp deleted file mode 100644 index ff71292..0000000 --- a/src/spaced/spaced/scenes/load_assets.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace spaced { -using bave::App; -using bave::AsyncExec; -using bave::Loader; -using bave::Services; - -namespace { -auto make_load_stages(Loader loader, Services const& services) -> std::vector { - auto asset_list = AssetList{std::move(loader), services}; - asset_list.add_manifest(GameScene::get_manifest()); - return asset_list.build_task_stages(); -} -} // namespace - -LoadAssets::LoadAssets(App& app, Services const& services) : Scene(app, services, "LoadAssets") {} - -auto LoadAssets::build_load_stages() -> std::vector { return make_load_stages(make_loader(), get_services()); } - -void LoadAssets::on_loaded() { get_switcher().switch_to(); } -} // namespace spaced diff --git a/src/spaced/spaced/scenes/load_assets.hpp b/src/spaced/spaced/scenes/load_assets.hpp deleted file mode 100644 index 4a0f265..0000000 --- a/src/spaced/spaced/scenes/load_assets.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -namespace spaced { -class LoadAssets : public bave::Scene { - public: - explicit LoadAssets(bave::App& app, bave::Services const& services); - - private: - auto build_load_stages() -> std::vector final; - void on_loaded() final; -}; -} // namespace spaced diff --git a/src/spaced/spaced/scenes/menu.cpp b/src/spaced/spaced/scenes/menu.cpp index d1d5d83..4aa04dd 100644 --- a/src/spaced/spaced/scenes/menu.cpp +++ b/src/spaced/spaced/scenes/menu.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -11,15 +12,27 @@ namespace spaced { using bave::App; +using bave::AsyncExec; using bave::Seconds; using bave::Services; using bave::TextHeight; namespace ui = bave::ui; -auto MenuScene::get_text_heights() -> std::vector { return {TextHeight{100}, TextHeight{60}, ui::Dialog::text_height_v}; } +MenuScene::MenuScene(App& app, Services const& services) : Scene(app, services, "Home") {} -MenuScene::MenuScene(App& app, Services const& services) : Scene(app, services, "Home") { create_ui(); } +auto MenuScene::build_load_stages() -> std::vector { + auto ret = std::vector{}; + auto asset_list = AssetList{make_loader(), get_services()}; + asset_list.add_audio_clip("music/menu.mp3"); + ret.push_back(asset_list.build_load_stage()); + return ret; +} + +void MenuScene::on_loaded() { + switch_track("music/menu.mp3"); + create_ui(); +} void MenuScene::create_ui() { auto m_header = std::make_unique(get_services()); diff --git a/src/spaced/spaced/scenes/menu.hpp b/src/spaced/spaced/scenes/menu.hpp index ec5e437..5d5ea94 100644 --- a/src/spaced/spaced/scenes/menu.hpp +++ b/src/spaced/spaced/scenes/menu.hpp @@ -4,13 +4,12 @@ namespace spaced { class MenuScene : public bave::Scene { public: - static auto get_text_heights() -> std::vector; - explicit MenuScene(bave::App& app, bave::Services const& services); private: - void create_ui(); + auto build_load_stages() -> std::vector final; + void on_loaded() final; - [[nodiscard]] auto get_music_uri() const -> std::string_view final { return "music/menu.mp3"; } + void create_ui(); }; } // namespace spaced diff --git a/src/spaced/spaced/spaced.cpp b/src/spaced/spaced/spaced.cpp index b6a84ea..0b87f63 100644 --- a/src/spaced/spaced/spaced.cpp +++ b/src/spaced/spaced/spaced.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -131,5 +131,5 @@ void Spaced::set_prefs() { audio.set_sfx_gain(prefs.sfx_gain); } -void Spaced::set_scene() { get_switcher().switch_to(); } +void Spaced::set_scene() { get_switcher().switch_to(); } } // namespace spaced From 541a13e5c915f0c1c2a602edbd5a2dc5f8093af4 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Fri, 14 Jun 2024 19:51:59 +0530 Subject: [PATCH 3/7] bgf v0.1.2 --- CMakeLists.txt | 2 +- src/spaced/spaced/assets/asset_list.cpp | 79 --------------------- src/spaced/spaced/assets/asset_list.hpp | 45 ------------ src/spaced/spaced/assets/asset_loader.cpp | 68 ------------------ src/spaced/spaced/assets/asset_loader.hpp | 30 -------- src/spaced/spaced/assets/asset_manifest.cpp | 18 ----- src/spaced/spaced/assets/asset_manifest.hpp | 23 ------ src/spaced/spaced/scenes/game.cpp | 10 ++- src/spaced/spaced/scenes/game.hpp | 3 - src/spaced/spaced/scenes/menu.cpp | 3 +- 10 files changed, 10 insertions(+), 271 deletions(-) delete mode 100644 src/spaced/spaced/assets/asset_list.cpp delete mode 100644 src/spaced/spaced/assets/asset_list.hpp delete mode 100644 src/spaced/spaced/assets/asset_loader.cpp delete mode 100644 src/spaced/spaced/assets/asset_loader.hpp delete mode 100644 src/spaced/spaced/assets/asset_manifest.cpp delete mode 100644 src/spaced/spaced/assets/asset_manifest.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ca5342..10c87df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(FetchContent) FetchContent_Declare( bgf GIT_REPOSITORY https://github.com/karnkaul/bgf - GIT_TAG v0.1.1 + GIT_TAG v0.1.2 SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bgf" ) diff --git a/src/spaced/spaced/assets/asset_list.cpp b/src/spaced/spaced/assets/asset_list.cpp deleted file mode 100644 index 22994b1..0000000 --- a/src/spaced/spaced/assets/asset_list.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include - -namespace spaced { -using bave::AsyncExec; -using bave::Loader; -using bave::Resources; -using bave::Services; - -AssetList::AssetList(Loader loader, Services const& services) : m_loader(std::move(loader)), m_resources(&services.get()) {} - -auto AssetList::add_texture(std::string uri, bool const mip_map) -> AssetList& { - if (uri.empty()) { return *this; } - m_textures.insert_or_assign(std::move(uri), mip_map); - return *this; -} - -auto AssetList::add_nine_slice(std::string uri) -> AssetList& { - if (uri.empty()) { return *this; } - m_nine_slices.insert(std::move(uri)); - return *this; -} - -auto AssetList::add_atlas(std::string uri, bool const mip_map) -> AssetList& { - if (uri.empty()) { return *this; } - m_atlases.insert_or_assign(std::move(uri), mip_map); - return *this; -} - -auto AssetList::add_font(std::string uri) -> AssetList& { - if (uri.empty()) { return *this; } - m_fonts.insert(std::move(uri)); - return *this; -} - -auto AssetList::add_audio_clip(std::string uri) -> AssetList& { - if (uri.empty()) { return *this; } - m_audio_clips.insert(std::move(uri)); - return *this; -} - -auto AssetList::add_anim_timeline(std::string uri) -> AssetList& { - if (uri.empty()) { return *this; } - m_anim_timelines.insert(std::move(uri)); - return *this; -} - -auto AssetList::add_particle_emitter(std::string uri) -> AssetList& { - if (uri.empty()) { return *this; } - m_emitters.insert(std::move(uri)); - return *this; -} - -void AssetList::add_manifest(AssetManifest manifest) { - for (auto& uri : manifest.flat_textures) { add_texture(std::move(uri), false); } - for (auto& uri : manifest.textures) { add_texture(std::move(uri), true); } - for (auto& uri : manifest.nine_slices) { add_nine_slice(std::move(uri)); } - for (auto& uri : manifest.flat_atlases) { add_atlas(std::move(uri), false); } - for (auto& uri : manifest.atlases) { add_atlas(std::move(uri), true); } - for (auto& uri : manifest.fonts) { add_font(std::move(uri)); } - for (auto& uri : manifest.audio_clips) { add_audio_clip(std::move(uri)); } - for (auto& uri : manifest.anim_timelines) { add_anim_timeline(std::move(uri)); } - for (auto& uri : manifest.particle_emitters) { add_particle_emitter(std::move(uri)); } -} - -auto AssetList::build_load_stage() const -> AsyncExec::Stage { - auto asset_loader = AssetLoader{m_loader, m_resources}; - auto ret = AsyncExec::Stage{}; - for (auto const& [uri, mip_map] : m_textures) { ret.push_back(asset_loader.make_load_texture(uri, mip_map)); } - for (auto const& uri : m_nine_slices) { ret.push_back(asset_loader.make_load_nine_slice(uri)); } - for (auto const& [uri, mip_map] : m_atlases) { ret.push_back(asset_loader.make_load_atlas(uri, mip_map)); } - for (auto const& font : m_fonts) { ret.push_back(asset_loader.make_load_font(font)); } - for (auto const& audio_clip : m_audio_clips) { ret.push_back(asset_loader.make_load_audio_clip(audio_clip)); } - for (auto const& anim_timeline : m_anim_timelines) { ret.push_back(asset_loader.make_load_anim_timeline(anim_timeline)); } - for (auto const& emitter : m_emitters) { ret.push_back(asset_loader.make_load_particle_emitter(emitter)); } - return ret; -} -} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_list.hpp b/src/spaced/spaced/assets/asset_list.hpp deleted file mode 100644 index 036d8b9..0000000 --- a/src/spaced/spaced/assets/asset_list.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -namespace bave { -struct Resources; -} - -namespace spaced { -class AssetLoader; - -class AssetList { - public: - explicit AssetList(bave::Loader loader, bave::Services const& services); - - auto add_texture(std::string uri, bool mip_map = false) -> AssetList&; - auto add_nine_slice(std::string uri) -> AssetList&; - auto add_atlas(std::string uri, bool mip_map = false) -> AssetList&; - auto add_font(std::string uri) -> AssetList&; - auto add_audio_clip(std::string uri) -> AssetList&; - auto add_anim_timeline(std::string uri) -> AssetList&; - auto add_particle_emitter(std::string uri) -> AssetList&; - - void add_manifest(AssetManifest manifest); - - [[nodiscard]] auto build_load_stage() const -> bave::AsyncExec::Stage; - - private: - bave::Loader m_loader; - bave::NotNull m_resources; - - std::unordered_map m_textures{}; - std::unordered_set m_nine_slices{}; - std::unordered_map m_atlases{}; - std::unordered_set m_fonts{}; - std::unordered_set m_audio_clips{}; - std::unordered_set m_anim_timelines{}; - std::unordered_set m_emitters{}; -}; -} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_loader.cpp b/src/spaced/spaced/assets/asset_loader.cpp deleted file mode 100644 index 8f192ce..0000000 --- a/src/spaced/spaced/assets/asset_loader.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -namespace spaced { -using bave::Loader; -using bave::NotNull; -using bave::Resources; - -struct AssetLoader::Impl { - Loader loader; - NotNull resources; - std::mutex mutex{}; -}; - -AssetLoader::AssetLoader(Loader loader, NotNull resources) : m_impl(new Impl{.loader = std::move(loader), .resources = resources}) {} - -auto AssetLoader::make_load_texture(std::string uri, bool mip_map, bool reload) -> LoadTask { - auto const load = [mip_map](Loader const& loader, std::string_view const uri) { return loader.load_texture(uri, mip_map); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_nine_slice(std::string uri, bool reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_texture_9slice(uri); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_atlas(std::string uri, bool mip_map, bool reload) -> LoadTask { - auto const load = [mip_map](Loader const& loader, std::string_view const uri) { return loader.load_texture_atlas(uri, mip_map); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_font(std::string uri, bool reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_font(uri); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_audio_clip(std::string uri, bool const reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_audio_clip(uri); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_anim_timeline(std::string uri, bool const reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_anim_timeline(uri); }; - return make_load_task(std::move(uri), reload, load); -} - -auto AssetLoader::make_load_particle_emitter(std::string uri, bool const reload) -> LoadTask { - auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_particle_emitter(uri); }; - return make_load_task(std::move(uri), reload, load); -} - -template -auto AssetLoader::make_load_task(std::string uri, bool reload, FuncT load) const -> LoadTask { - return [impl = m_impl, uri = std::move(uri), reload, load] { - auto lock = std::unique_lock{impl->mutex}; - if (!reload && impl->resources->contains(uri)) { return; } - - lock.unlock(); - auto asset = load(impl->loader, uri); - if (!asset) { return; } - - lock.lock(); - impl->resources->add(uri, std::move(asset)); - }; -} -} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_loader.hpp b/src/spaced/spaced/assets/asset_loader.hpp deleted file mode 100644 index 41b54f8..0000000 --- a/src/spaced/spaced/assets/asset_loader.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace spaced { -class AssetLoader { - public: - using LoadTask = std::function; - - explicit AssetLoader(bave::Loader loader, bave::NotNull resources); - - [[nodiscard]] auto make_load_texture(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_nine_slice(std::string uri, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_atlas(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_font(std::string uri, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_audio_clip(std::string uri, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_anim_timeline(std::string uri, bool reload = false) -> LoadTask; - [[nodiscard]] auto make_load_particle_emitter(std::string uri, bool reload = false) -> LoadTask; - - private: - template - auto make_load_task(std::string uri, bool reload, FuncT load) const -> LoadTask; - - struct Impl; - std::shared_ptr m_impl{}; -}; -} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_manifest.cpp b/src/spaced/spaced/assets/asset_manifest.cpp deleted file mode 100644 index e112d9d..0000000 --- a/src/spaced/spaced/assets/asset_manifest.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -namespace spaced { -auto AssetManifest::load_from(dj::Json const& json) -> AssetManifest { - auto ret = AssetManifest{}; - for (auto const& texture : json["textures"].array_view()) { ret.textures.push_back(texture.as()); } - for (auto const& texture : json["flat_textures"].array_view()) { ret.flat_textures.push_back(texture.as()); } - for (auto const& atlas : json["atlases"].array_view()) { ret.atlases.push_back(atlas.as()); } - for (auto const& atlas : json["flat_atlases"].array_view()) { ret.flat_atlases.push_back(atlas.as()); } - for (auto const& slice : json["nine_slices"].array_view()) { ret.nine_slices.push_back(slice.as()); } - for (auto const& font : json["fonts"].array_view()) { ret.fonts.push_back(font.as()); } - for (auto const& timeline : json["anim_timelines"].array_view()) { ret.anim_timelines.push_back(timeline.as()); } - for (auto const& clip : json["audio_clips"].array_view()) { ret.audio_clips.push_back(clip.as()); } - for (auto const& emitter : json["particle_emitters"].array_view()) { ret.particle_emitters.push_back(emitter.as()); } - return ret; -} -} // namespace spaced diff --git a/src/spaced/spaced/assets/asset_manifest.hpp b/src/spaced/spaced/assets/asset_manifest.hpp deleted file mode 100644 index ca0803b..0000000 --- a/src/spaced/spaced/assets/asset_manifest.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include -#include - -namespace dj { -class Json; -} - -namespace spaced { -struct AssetManifest { - std::vector flat_textures{}; - std::vector textures{}; - std::vector nine_slices{}; - std::vector flat_atlases{}; - std::vector atlases{}; - std::vector fonts{}; - std::vector audio_clips{}; - std::vector anim_timelines{}; - std::vector particle_emitters{}; - - static auto load_from(dj::Json const& json) -> AssetManifest; -}; -} // namespace spaced diff --git a/src/spaced/spaced/scenes/game.cpp b/src/spaced/spaced/scenes/game.cpp index c11d976..0d729ff 100644 --- a/src/spaced/spaced/scenes/game.cpp +++ b/src/spaced/spaced/scenes/game.cpp @@ -1,10 +1,11 @@ +#include +#include #include #include #include #include #include #include -#include #include #include #include @@ -12,6 +13,8 @@ namespace spaced { using bave::Action; using bave::App; +using bave::AssetList; +using bave::AssetManifest; using bave::AsyncExec; using bave::FocusChange; using bave::im_text; @@ -28,12 +31,12 @@ using bave::Styles; namespace ui = bave::ui; -auto GameScene::get_manifest() -> AssetManifest { +namespace { +auto get_manifest() -> AssetManifest { return AssetManifest{ .audio_clips = { "sfx/bubble.wav", - "music/menu.mp3", "music/game.mp3", }, .particle_emitters = @@ -44,6 +47,7 @@ auto GameScene::get_manifest() -> AssetManifest { }, }; } +} // namespace GameScene::GameScene(App& app, Services const& services) : Scene(app, services, "Game"), m_save(&app) { clear_colour = services.get().rgbas["mocha"]; } diff --git a/src/spaced/spaced/scenes/game.hpp b/src/spaced/spaced/scenes/game.hpp index 3e7e2b6..8a58843 100644 --- a/src/spaced/spaced/scenes/game.hpp +++ b/src/spaced/spaced/scenes/game.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include #include #include @@ -10,8 +9,6 @@ namespace spaced { class GameScene : public bave::Scene, public IScorer { public: - static auto get_manifest() -> AssetManifest; - GameScene(bave::App& app, bave::Services const& services); private: diff --git a/src/spaced/spaced/scenes/menu.cpp b/src/spaced/spaced/scenes/menu.cpp index 4aa04dd..41a4b36 100644 --- a/src/spaced/spaced/scenes/menu.cpp +++ b/src/spaced/spaced/scenes/menu.cpp @@ -1,9 +1,9 @@ +#include #include #include #include #include #include -#include #include #include #include @@ -12,6 +12,7 @@ namespace spaced { using bave::App; +using bave::AssetList; using bave::AsyncExec; using bave::Seconds; using bave::Services; From 27e3204d523a2cf44ebfde571c67d17381597c53 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Fri, 14 Jun 2024 20:24:16 +0530 Subject: [PATCH 4/7] Add player_ship sprite. --- .gitignore | 1 + assets/images/player_ship.png | Bin 0 -> 7100 bytes assets/particles/exhaust.json | 14 +++++++------- attribution.txt | 1 + src/spaced/spaced/game/player.cpp | 18 ++++++++---------- src/spaced/spaced/game/player.hpp | 4 +++- src/spaced/spaced/scenes/game.cpp | 4 ++++ 7 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 assets/images/player_ship.png create mode 100644 attribution.txt diff --git a/.gitignore b/.gitignore index ca09e17..0bb7d4e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ imgui.ini bave*.log /spaced /notes.txt +/local_store diff --git a/assets/images/player_ship.png b/assets/images/player_ship.png new file mode 100644 index 0000000000000000000000000000000000000000..a465e7e404b5a48531ab434da2e017b98e9f79a8 GIT binary patch literal 7100 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 controller) : m_services(&services), m_stats(&services.get()), m_controller(std::move(controller)) { auto const& layout = services.get(); ship.transform.position.x = layout.player_x; - auto rounded_quad = RoundedQuad{}; - rounded_quad.size = layout.player_size; - rounded_quad.corner_radius = 20.0f; - ship.set_shape(rounded_quad); - - auto const& rgbas = services.get().rgbas; - ship.tint = rgbas["black"]; auto const& resources = services.get(); + + if (auto const texture = services.get().get("images/player_ship.png")) { ship.set_texture(texture); } + ship.set_auto_size(ship_size); + if (auto const exhaust = resources.get("particles/exhaust.json")) { m_exhaust = *exhaust; } m_exhaust.set_position(get_exhaust_position()); m_exhaust.pre_warm(); @@ -59,8 +56,9 @@ void Player::tick(State const& state, Seconds const dt) { auto const y_position = m_controller->tick(dt); set_y(y_position); + auto const hitbox = Rect<>::from_size(hitbox_size, ship.transform.position); for (auto const& target : state.targets) { - if (is_intersecting(target->get_bounds(), ship.get_bounds())) { + if (is_intersecting(target->get_bounds(), hitbox)) { on_death(dt); target->force_death(); return; diff --git a/src/spaced/spaced/game/player.hpp b/src/spaced/spaced/game/player.hpp index 015ca75..1bc6724 100644 --- a/src/spaced/spaced/game/player.hpp +++ b/src/spaced/spaced/game/player.hpp @@ -43,7 +43,9 @@ class Player : public bave::IDrawable { if constexpr (bave::debug_v) { do_inspect(); } } - bave::RoundedQuadShape ship{}; + bave::Sprite ship{}; + glm::vec2 ship_size{100.0f}; + glm::vec2 hitbox_size{75.0f}; Health health{}; private: diff --git a/src/spaced/spaced/scenes/game.cpp b/src/spaced/spaced/scenes/game.cpp index 0d729ff..6967188 100644 --- a/src/spaced/spaced/scenes/game.cpp +++ b/src/spaced/spaced/scenes/game.cpp @@ -34,6 +34,10 @@ namespace ui = bave::ui; namespace { auto get_manifest() -> AssetManifest { return AssetManifest{ + .textures = + { + "images/player_ship.png", + }, .audio_clips = { "sfx/bubble.wav", From 1cfa5525f735424e3096583eae0798742a64debd Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Sat, 15 Jun 2024 09:06:15 +0530 Subject: [PATCH 5/7] bgf v0.1.3, fixup world vs UI space in layout. --- CMakeLists.txt | 2 +- src/spaced/spaced/spaced.cpp | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10c87df..a5c5a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include(FetchContent) FetchContent_Declare( bgf GIT_REPOSITORY https://github.com/karnkaul/bgf - GIT_TAG v0.1.2 + GIT_TAG v0.1.3 SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bgf" ) diff --git a/src/spaced/spaced/spaced.cpp b/src/spaced/spaced/spaced.cpp index 0b87f63..4e0ddcc 100644 --- a/src/spaced/spaced/spaced.cpp +++ b/src/spaced/spaced/spaced.cpp @@ -111,17 +111,21 @@ void Spaced::create_services() { } void Spaced::set_layout() { - auto game_layout = std::make_unique(); - auto const& display = m_services.get(); - game_layout->world_space = display.get_world_space(); - auto const viewport = display.get_main_view().viewport; - auto const hud_size = glm::vec2{viewport.x, 100.0f}; - auto const hud_origin = glm::vec2{0.0f, 0.5f * (viewport.y - hud_size.y)}; - game_layout->hud_area = Rect<>::from_size(hud_size, hud_origin); - auto const play_size = glm::vec2{hud_size.x, viewport.y - hud_size.y}; - auto const play_origin = glm::vec2{0.0f, -0.5f * (viewport.y - play_size.y)}; - game_layout->play_area = Rect<>::from_size(play_size, play_origin); - m_services.bind(std::move(game_layout)); + static constexpr auto world_space_v = glm::vec2{1920.0f, 1080.0f}; + + auto layout = std::make_unique(); + auto& display = m_services.get(); + display.set_world_space(display.get_viewport_scaler().match_width(world_space_v)); + + layout->world_space = display.get_world_space(); + layout->player_x = -0.5f * layout->world_space.x + 0.1f * layout->world_space.x; + auto const hud_size = glm::vec2{display.get_ui_space().x, 100.0f}; + auto const hud_origin = glm::vec2{0.0f, 0.5f * (display.get_ui_space().y - hud_size.y)}; + layout->hud_area = Rect<>::from_size(hud_size, hud_origin); + auto const play_size = glm::vec2{hud_size.x, display.get_world_space().y - hud_size.y}; + auto const play_origin = glm::vec2{0.0f, -0.5f * (display.get_world_space().y - play_size.y)}; + layout->play_area = Rect<>::from_size(play_size, play_origin); + m_services.bind(std::move(layout)); } void Spaced::set_prefs() { From df29e0e902cc26af519fc2cf1cfcac76ab18d817 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Sat, 15 Jun 2024 09:06:29 +0530 Subject: [PATCH 6/7] Add `TiledBg`. --- assets/images/background.png | Bin 0 -> 2880 bytes src/spaced/spaced/game/tiled_bg.cpp | 55 ++++++++++++++++++++++++++++ src/spaced/spaced/game/tiled_bg.hpp | 27 ++++++++++++++ src/spaced/spaced/game/world.cpp | 9 ++++- src/spaced/spaced/game/world.hpp | 3 ++ src/spaced/spaced/scenes/game.cpp | 1 + 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 assets/images/background.png create mode 100644 src/spaced/spaced/game/tiled_bg.cpp create mode 100644 src/spaced/spaced/game/tiled_bg.hpp diff --git a/assets/images/background.png b/assets/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c3fd42dc38bbc1e9fa407a0790598114f1e5d6 GIT binary patch literal 2880 zcmaJ@dt4J&7QP8SkbxznzJN$Zh?qx{kt7tG5d>e0 zv`Psgg8f-Qw*@TajhYAwtw^C8D@q6;il73DVR=J#f?&7(Ej$0*d+wa`opaCqzB_Yb zTY#^H*=jQYfQ8>??;rp$=oAA?vFM<&Vv^9o8r~EN2MhPZQjQn`o?PKR2-j)l@=-F6F5d6f{ZUhqXD2ZWg<>w3sWv$G@W;V6*{ zV2;dDAo*|(!5fl9ig_ZKClug}h@5@GLofr6R{CZOe9>E2fn>H#Xv2syj)+JiI2pGz z=jiYM|6Td~x84#s2>PSm{|PJ!k&7T=5F`;E5=Wv3xBo+9DiMt>hB&ZL93m7Roa^GY zXdx_=L<>bYHXHZx4xWH3luFjmxcmFl`~(u1BZ!3jycu{DfWYH%X%uI)F`KCFRI0ZV ziL{AK^>p@Ov&oyh+$dysCs&ubSZ`tEAwDF4=VG~k#CpyfYh(gngl6`J#JpID>mwHO zaWgxn@#e3^ZCYGY$jwJ?rNiQ4wYWu4!Jxb- z^~k9SFe95&$9IV-Kh`i6(=AKm-d}@V0I&dq02aU@ji&v~UNW+(>#Ie9lnaZjyr_Ma z*$1b!bxo%lDiy2hU2KPowiM(((ZHXS%DSFKE{a}f7`9I?TTn%Z9a+9)*2ZqTEx+35 zQzyr!FZ7(ZEy5fqsMjnGr05#KO8z2K`D?D`nR)YF`7l=_1UO&?OaYo6O+7cAtz;gv zGl?cFz=3hPZ!-0kCm34I+EaFJIkNsnhczy@Wntgy@_ArKvdMcr>?ovqtA3o)~kgJ&3PmTMu~NV zVsquWp6*cp(y~ES(oe}?^z|N5Y}V_(6_1T!#Q4ghPSHq2^^7sueIuc$ zthxwSh$(z9d?O*_?Xd9bGb2ok!x0Ml8e6eKjb^*$s(xRKCLya^TspBx&oZygJlRvw z`7q%5THCrr(EGAY^-jZ@(d5sW1IJwQibg}yoA^Jj;rG2fcGzaBXr!ZbRi2y{VAr|> z)0`yFZcWv|2QC>#%2hkDzg^n(VoI8~1i9hRkv#rf$}vM48$tE>tE%uB%FYNU;xmCL zW^=}=?D_Q0BjH9*FomBe9b>C_&r>N$SGwNzbtL|lP$GceQ#-a! z*%yr>G^#zVSgQCHVe<+XS!bbM>M>-aF1~bLM}I~^BHRKgd|7Xs;$fr2kfEb%Ypx8$ zx2GyMnjB57mghZ+pEzyk--Yv0wp@E+eK9TGL0T=J9-G#+7*05*QO1>PM8Q9lR=mIv zosm<%eNP{5_h?vgeEow3r&rpkFG=-qt!3D#tJ*hp@kb||}nC2ImUqI!FBR*~d_`YRMlY#Wzx7pzz?`+=_oTImYmki3U zVLc3{j~=thV9n)Ile{G%pPsY(x9&4CAcomYeLrsdwKZbXvwa4S?Ehzd&R%qLa-B6pwJM5f_Gy#Q-w&TyrY`VRgie{`{*IyZ!1uOc{3Oap z<)2hvNwFIcx%Dae^43=;*P8R_9jRYdGP|D-1Y7S0k6i-ma;-a;?5cQjRa+3dBKkyL z+7AhLLC4nX3gR98Q+jaN%Q4qFms{T+ZcJ@GZ%tMwlClcMgw&-IX~|c~CZ-n~K&vZa z|CN37S;Db9Rof>UknsET!AVKSeuR2$Y`QT^a-}k@&GxRGP+C&I=zB07&i|mG_n-8m z4eM0}6PkUYamPu0mi_pPDU)*Rp&KSNq}mtZ zhS6@99CQB`pyO@15Ze{5U9o&W5O6c|V=cC&D9Egw^ludBqB<5>vFf*6y!O+A<*a=4 z@`IGBLQK_O>^IlWA6|Lay!ns`!T8bmOE3Rqs%vY+Eu-iM!ln16F2OCi!Y+IXlAS#& z8@ZRCk<6k01C`Rf4tghhkU@~8H;U8y#a<`byC+L-8V(rtPF&z+r)nk&%PuctNe>iM zKHYvZOL< + +namespace spaced { +using bave::RenderInstance; +using bave::Seconds; +using bave::Services; +using bave::Shader; + +TiledBg::TiledBg(Services const& services) : m_layout(&services.get()) {} + +void TiledBg::set_tile_size(glm::vec2 const size) { + auto shape = m_quad.get_shape(); + shape.size = size; + m_quad.set_shape(shape); + + auto const cols = static_cast(m_layout->world_space.x / size.x) + 1; + auto const rows = static_cast(m_layout->world_space.y / size.y) + 1; + auto const lt = 0.5f * glm::vec2{-m_layout->world_space.x + size.x, m_layout->world_space.y - size.y}; + + m_exit_x = lt.x - size.x; + + m_quad.instances.clear(); + auto instance = RenderInstance{}; + instance.transform.position = lt; + for (int row = 0; row < rows; ++row) { + for (int col = 0; col < cols + 1; ++col) { + m_quad.instances.push_back(instance); + instance.transform.position.x += size.x; + } + instance.transform.position.x = lt.x; + instance.transform.position.y -= size.y; + } +} + +void TiledBg::tick(Seconds const dt) { + if (x_speed <= 0.0f) { return; } + + auto const dx = x_speed * dt.count(); + auto max_x = 0.0f; + for (auto& instance : m_quad.instances) { + instance.transform.position.x -= dx; + max_x = std::max(max_x, instance.transform.position.x); + } + for (auto& instance : m_quad.instances) { + if (instance.transform.position.x <= m_exit_x) { instance.transform.position.x = max_x + m_quad.get_shape().size.x; } + } +} + +void TiledBg::draw(Shader& shader) const { + static bool s_wf{false}; + if (s_wf) { shader.polygon_mode = vk::PolygonMode::eLine; } + m_quad.draw(shader); + if (s_wf) { shader.polygon_mode = vk::PolygonMode::eFill; } +} +} // namespace spaced diff --git a/src/spaced/spaced/game/tiled_bg.hpp b/src/spaced/spaced/game/tiled_bg.hpp new file mode 100644 index 0000000..1cc9f56 --- /dev/null +++ b/src/spaced/spaced/game/tiled_bg.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace spaced { +class TiledBg { + public: + explicit TiledBg(bave::Services const& services); + + void set_tile_size(glm::vec2 size); + void set_texture(std::shared_ptr texture) { m_quad.set_texture(std::move(texture)); } + + void tick(bave::Seconds dt); + void draw(bave::Shader& shader) const; + + float x_speed{10.0f}; + + private: + bave::NotNull m_layout; + bave::Instanced m_quad{}; + + float m_exit_x{}; +}; +} // namespace spaced diff --git a/src/spaced/spaced/game/world.cpp b/src/spaced/spaced/game/world.cpp index 4607c08..2cd6d08 100644 --- a/src/spaced/spaced/game/world.cpp +++ b/src/spaced/spaced/game/world.cpp @@ -19,6 +19,7 @@ using bave::Resources; using bave::Seconds; using bave::Services; using bave::Shader; +using bave::Texture; namespace { [[nodiscard]] auto make_player_controller(Services const& services) { @@ -39,14 +40,19 @@ namespace { World::World(bave::NotNull services, bave::NotNull scorer) : player(*services, make_player_controller(*services)), m_services(services), m_resources(&services->get()), m_audio(&services->get()), - m_stats(&services->get()), m_scorer(scorer) { + m_stats(&services->get()), m_scorer(scorer), m_background(*services) { m_enemy_factories["CreepFactory"] = std::make_unique(services); + + m_background.set_texture(services->get().get("images/background.png")); + m_background.set_tile_size(glm::vec2{300.0f}); + m_background.x_speed = 50.0f; } void World::tick(Seconds const dt) { bool const in_play = !player.health.is_dead(); if (in_play) { + m_background.tick(dt); for (auto& [_, factory] : m_enemy_factories) { if (auto enemy = factory->tick(dt)) { m_active_enemies.push_back(std::move(enemy)); } } @@ -74,6 +80,7 @@ void World::tick(Seconds const dt) { } void World::draw(Shader& shader) const { + m_background.draw(shader); for (auto const& enemy : m_active_enemies) { enemy->draw(shader); } for (auto const& emitter : m_enemy_death_emitters) { emitter.draw(shader); } for (auto const& powerup : m_active_powerups) { powerup->draw(shader); } diff --git a/src/spaced/spaced/game/world.hpp b/src/spaced/spaced/game/world.hpp index 24720c9..3b581bf 100644 --- a/src/spaced/spaced/game/world.hpp +++ b/src/spaced/spaced/game/world.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace bave { struct Resources; @@ -41,6 +42,8 @@ class World : public ITargetProvider { bave::NotNull m_stats; bave::NotNull m_scorer; + TiledBg m_background; + std::unordered_map> m_enemy_factories{}; std::vector> m_active_enemies{}; diff --git a/src/spaced/spaced/scenes/game.cpp b/src/spaced/spaced/scenes/game.cpp index 6967188..8feaa80 100644 --- a/src/spaced/spaced/scenes/game.cpp +++ b/src/spaced/spaced/scenes/game.cpp @@ -37,6 +37,7 @@ auto get_manifest() -> AssetManifest { .textures = { "images/player_ship.png", + "images/background.png", }, .audio_clips = { From 36296fabfb46fbb1033bcfb92e764aed94cb7eb5 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Sat, 15 Jun 2024 09:48:10 +0530 Subject: [PATCH 7/7] Fixup hud positioning. --- assets/styles.json | 2 +- .../game/controllers/player_controller.cpp | 5 +++-- .../game/controllers/player_controller.hpp | 2 +- src/spaced/spaced/game/hud.cpp | 21 ++++++++++++------- src/spaced/spaced/game/hud.hpp | 6 +++++- src/spaced/spaced/prefs.cpp | 12 +++++------ src/spaced/spaced/spaced.cpp | 11 +++++----- src/spaced/spaced/spaced.hpp | 2 ++ 8 files changed, 37 insertions(+), 24 deletions(-) diff --git a/assets/styles.json b/assets/styles.json index 06607c0..fd3ff52 100644 --- a/assets/styles.json +++ b/assets/styles.json @@ -58,7 +58,7 @@ "sliders": { "default": { "progress_bar": "default", - "knob_diameter": 30, + "knob_diameter": 50, "knob_tint": "#9f2b68ff" } }, diff --git a/src/spaced/spaced/game/controllers/player_controller.cpp b/src/spaced/spaced/game/controllers/player_controller.cpp index 8fcae45..18d1e1a 100644 --- a/src/spaced/spaced/game/controllers/player_controller.cpp +++ b/src/spaced/spaced/game/controllers/player_controller.cpp @@ -68,8 +68,9 @@ void PlayerController::stop_firing() { } auto PlayerController::is_in_move_area(glm::vec2 const position) const -> bool { - auto const n_pos = position.x / m_display->get_world_space().x; - return n_pos <= -n_move_area; + auto const width = m_display->get_world_space().x; + auto const n_pos = (position.x + 0.5f * width) / width; + return n_pos <= n_move_area; } void PlayerController::tick_gamepad(Seconds const dt) { diff --git a/src/spaced/spaced/game/controllers/player_controller.hpp b/src/spaced/spaced/game/controllers/player_controller.hpp index 72f0c2c..ec4726a 100644 --- a/src/spaced/spaced/game/controllers/player_controller.hpp +++ b/src/spaced/spaced/game/controllers/player_controller.hpp @@ -33,7 +33,7 @@ class PlayerController : public FollowController { float max_y{}; float min_y{}; - float n_move_area{0.25f}; // from left + float n_move_area{0.3f}; // from left float gamepad_sensitivity{2000.0f}; diff --git a/src/spaced/spaced/game/hud.cpp b/src/spaced/spaced/game/hud.cpp index 2a6d3c5..848ca1f 100644 --- a/src/spaced/spaced/game/hud.cpp +++ b/src/spaced/spaced/game/hud.cpp @@ -1,20 +1,25 @@ #include #include +#include #include #include namespace spaced { +using bave::IDisplay; +using bave::Seconds; using bave::Services; using bave::Styles; using bave::TextHeight; namespace ui = bave::ui; -Hud::Hud(Services const& services) : ui::View(services), m_styles(&services.get()), m_area(services.get().hud_area) { +Hud::Hud(Services const& services) + : ui::View(services), m_display(&services.get()), m_layout(&services.get()), m_styles(&services.get()) { create_background(); create_score(services); block_input_events = false; + render_view = m_display->get_world_view(); } void Hud::set_score(std::int64_t const score) { m_score->text.set_string(fmt::format("{}", score)); } @@ -25,8 +30,8 @@ void Hud::create_background() { auto background = std::make_unique(); m_background = background.get(); background->set_outline_width(0.0f); - background->set_size(m_area.size()); - background->set_position(m_area.centre()); + background->set_size(m_layout->hud_area.size()); + background->set_position(m_layout->hud_area.centre()); background->set_tint(m_styles->rgbas["milk"]); push(std::move(background)); } @@ -37,7 +42,7 @@ void Hud::create_score(Services const& services) { auto make_text = [&] { auto text = std::make_unique(services); text->text.set_height(TextHeight{60}); - text->text.transform.position = m_area.centre(); + text->text.transform.position = m_layout->hud_area.centre(); text->text.tint = rgbas["grey"]; return text; }; @@ -45,16 +50,16 @@ void Hud::create_score(Services const& services) { auto text = make_text(); m_score = text.get(); text->text.set_string("9999999999"); - auto const text_bounds_size = text->text.get_bounds().size(); - text->text.transform.position.y -= 0.5f * text_bounds_size.y; + m_text_bounds_size = text->text.get_bounds().size(); + text->text.transform.position.y -= 0.5f * m_text_bounds_size.y; set_score(0); push(std::move(text)); text = make_text(); m_hi_score = text.get(); - text->text.transform.position.x = m_area.rb.x - 50.0f; - text->text.transform.position.y -= 0.5f * text_bounds_size.y; + text->text.transform.position.x = m_layout->hud_area.rb.x - 50.0f; + text->text.transform.position.y -= 0.5f * m_text_bounds_size.y; text->text.set_align(bave::Text::Align::eLeft); set_hi_score(0); diff --git a/src/spaced/spaced/game/hud.hpp b/src/spaced/spaced/game/hud.hpp index bc26dc3..25dadab 100644 --- a/src/spaced/spaced/game/hud.hpp +++ b/src/spaced/spaced/game/hud.hpp @@ -5,6 +5,8 @@ #include namespace spaced { +struct Layout; + class Hud : public bave::ui::View { public: explicit Hud(bave::Services const& services); @@ -16,8 +18,10 @@ class Hud : public bave::ui::View { void create_background(); void create_score(bave::Services const& services); + bave::NotNull m_display; + bave::NotNull m_layout; bave::NotNull m_styles; - bave::Rect<> m_area{}; + glm::vec2 m_text_bounds_size{}; bave::Ptr m_background{}; bave::Ptr m_score{}; diff --git a/src/spaced/spaced/prefs.cpp b/src/spaced/spaced/prefs.cpp index 223346f..bd8929b 100644 --- a/src/spaced/spaced/prefs.cpp +++ b/src/spaced/spaced/prefs.cpp @@ -45,7 +45,7 @@ Prefs::View::View(NotNull app, Services const& services) auto const& styles = services.get(); auto bg = std::make_unique(); - bg->set_size({400.0f, 400.0f}); + bg->set_size({600.0f, 600.0f}); bg->set_outline_width(5.0f); bg->set_corner_ratio(0.1f); bg->set_tint(styles.rgbas["milk"]); @@ -53,7 +53,7 @@ Prefs::View::View(NotNull app, Services const& services) auto text = std::make_unique(services); text->text.set_string("music"); - text->set_position({0.0f, 130.0f}); + text->set_position({0.0f, 230.0f}); push(std::move(text)); auto slider = std::make_unique(services); @@ -62,12 +62,12 @@ Prefs::View::View(NotNull app, Services const& services) m_prefs.music_gain = val; m_audio->set_music_gain(val); }; - slider->set_position({0.0f, 100.0f}); + slider->set_position({0.0f, 200.0f}); push(std::move(slider)); text = std::make_unique(services); text->text.set_string("sfx"); - text->set_position({0.0f, 30.0f}); + text->set_position({0.0f, 130.0f}); push(std::move(text)); slider = std::make_unique(services); @@ -76,13 +76,13 @@ Prefs::View::View(NotNull app, Services const& services) m_prefs.sfx_gain = val; m_audio->set_sfx_gain(val); }; - slider->set_position({0.0f, 0.0f}); + slider->set_position({0.0f, 100.0f}); push(std::move(slider)); auto button = std::make_unique(services); button->set_text("close"); button->callback = [this] { set_destroyed(); }; - button->set_position({0.0f, -100.0f}); + button->set_position({0.0f, -200.0f}); push(std::move(button)); } diff --git a/src/spaced/spaced/spaced.cpp b/src/spaced/spaced/spaced.cpp index 4e0ddcc..a0fde84 100644 --- a/src/spaced/spaced/spaced.cpp +++ b/src/spaced/spaced/spaced.cpp @@ -114,16 +114,17 @@ void Spaced::set_layout() { static constexpr auto world_space_v = glm::vec2{1920.0f, 1080.0f}; auto layout = std::make_unique(); + m_layout = layout.get(); auto& display = m_services.get(); display.set_world_space(display.get_viewport_scaler().match_width(world_space_v)); layout->world_space = display.get_world_space(); - layout->player_x = -0.5f * layout->world_space.x + 0.1f * layout->world_space.x; - auto const hud_size = glm::vec2{display.get_ui_space().x, 100.0f}; - auto const hud_origin = glm::vec2{0.0f, 0.5f * (display.get_ui_space().y - hud_size.y)}; + layout->player_x = -0.5f * layout->world_space.x + 0.2f * layout->world_space.x; + auto const hud_size = glm::vec2{layout->world_space.x, 100.0f}; + auto const hud_origin = glm::vec2{0.0f, 0.5f * (layout->world_space.y - hud_size.y)}; layout->hud_area = Rect<>::from_size(hud_size, hud_origin); - auto const play_size = glm::vec2{hud_size.x, display.get_world_space().y - hud_size.y}; - auto const play_origin = glm::vec2{0.0f, -0.5f * (display.get_world_space().y - play_size.y)}; + auto const play_size = glm::vec2{hud_size.x, layout->world_space.y - hud_size.y}; + auto const play_origin = glm::vec2{0.0f, -0.5f * (layout->world_space.y - play_size.y)}; layout->play_area = Rect<>::from_size(play_size, play_origin); m_services.bind(std::move(layout)); } diff --git a/src/spaced/spaced/spaced.hpp b/src/spaced/spaced/spaced.hpp index 9389a9d..827cff8 100644 --- a/src/spaced/spaced/spaced.hpp +++ b/src/spaced/spaced/spaced.hpp @@ -9,6 +9,7 @@ struct Resources; namespace spaced { class Serializer; struct SceneSwitcher; +struct Layout; class Spaced : public bave::GameDriver { public: @@ -25,5 +26,6 @@ class Spaced : public bave::GameDriver { bave::Logger m_log{"Spaced"}; bave::Ptr m_resources{}; + bave::Ptr m_layout{}; }; } // namespace spaced