diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a570aa..7a19489 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,25 +22,26 @@ FetchContent_Declare( FetchContent_MakeAvailable(SDL3_ttf) FetchContent_Declare( - flecs - URL https://github.com/SanderMertens/flecs/archive/refs/tags/v4.0.5.tar.gz + entt + URL https://github.com/skypjack/entt/archive/refs/tags/v3.15.0.tar.gz OVERRIDE_FIND_PACKAGE ) -FetchContent_MakeAvailable(flecs) +FetchContent_MakeAvailable(entt) +find_package(entt CONFIG REQUIRED) find_package(SDL3 CONFIG REQUIRED) find_package(SDL3_ttf CONFIG REQUIRED) -find_package(flecs CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) add_executable(HansTheGatherer src/main.cpp src/audio.cpp src/assets.cpp + src/level.cpp src/physics.cpp src/render.cpp ) -target_link_libraries(HansTheGatherer SDL3::SDL3 SDL3_ttf::SDL3_ttf flecs::flecs spdlog::spdlog) +target_link_libraries(HansTheGatherer SDL3::SDL3 SDL3_ttf::SDL3_ttf EnTT spdlog::spdlog) set_property(TARGET HansTheGatherer PROPERTY CXX_STANDARD 20) diff --git a/src/assets.cpp b/src/assets.cpp index 8acc93e..6550881 100644 --- a/src/assets.cpp +++ b/src/assets.cpp @@ -81,9 +81,9 @@ FontAsset load_font(uint8_t const* data, size_t size) return font_asset; } -AssetModule::AssetModule(flecs::world& world) +AssetModule::AssetModule(entt::registry& registry) { - auto* renderer = world.get()->renderer; + auto renderer = registry.ctx().get().renderer; auto* background = load_texture(BACKGROUND_DATA, sizeof(BACKGROUND_DATA), renderer); TextureAtlasLayout background_layout = {.width = 866, .height = 510, .rows = 1, .columns = 1}; @@ -97,7 +97,7 @@ AssetModule::AssetModule(flecs::world& world) auto* basket = load_texture(BASKET_DATA, sizeof(BASKET_DATA), renderer); TextureAtlasLayout basket_layout = {.width = 16, .height = 16, .rows = 1, .columns = 1}; - world.set(TextureAssets{ + registry.ctx().emplace(TextureAssets{ .background = Texture{.sdl_texture = background, .texture_atlas_layout = background_layout}, .fruits = Texture{.sdl_texture = fruits, .texture_atlas_layout = fruits_layout}, .spiders = Texture{.sdl_texture = spiders, .texture_atlas_layout = spiders_layout}, @@ -106,10 +106,10 @@ AssetModule::AssetModule(flecs::world& world) auto background_music = load_audio(BACKGROUND_MUSIC_DATA, sizeof(BACKGROUND_MUSIC_DATA)); auto pickup_sound = load_audio(PICKUP_SOUND_DATA, sizeof(PICKUP_SOUND_DATA)); auto hit_sound = load_audio(HIT_SOUND_DATA, sizeof(HIT_SOUND_DATA)); - world.set(AudioAssets{.background_music = background_music, - .pickup_sound = pickup_sound, - .hit_sound = hit_sound}); + registry.ctx().emplace(AudioAssets{.background_music = background_music, + .pickup_sound = pickup_sound, + .hit_sound = hit_sound}); auto font = load_font(DEFAULT_FONT_DATA, sizeof(DEFAULT_FONT_DATA)); - world.set(FontAssets{.default_font = font}); + registry.ctx().emplace(FontAssets{.default_font = font}); } diff --git a/src/assets.hpp b/src/assets.hpp index de61b00..3eddaba 100644 --- a/src/assets.hpp +++ b/src/assets.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include struct TextureAtlasLayout { @@ -47,5 +47,5 @@ struct FontAssets struct AssetModule { - AssetModule(flecs::world& world); + AssetModule(entt::registry& registry); }; diff --git a/src/audio.cpp b/src/audio.cpp index cf6b22e..854c6f4 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -1,34 +1,31 @@ #include "audio.hpp" #include "assets.hpp" -AudioModule::AudioModule(flecs::world& world) +AudioModule::AudioModule(entt::registry& registry) { - auto* audio_assets = world.get(); + auto const& audio_assets = registry.ctx().get(); auto* music_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); auto* sound_stream = SDL_OpenAudioDeviceStream( - SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_assets->pickup_sound.spec, NULL, NULL); + SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_assets.pickup_sound.spec, NULL, NULL); SDL_ResumeAudioStreamDevice(music_stream); SDL_ResumeAudioStreamDevice(sound_stream); - world.set( + registry.ctx().emplace( AudioStreams{.music_stream = music_stream, .sound_stream = sound_stream}); - - world.system("FeedAudioStreams") - .term_at(0) - .singleton() - .term_at(1) - .singleton() - .each( - [](AudioStreams& audio_streams, AudioAssets& audio_assets) - { - if (SDL_GetAudioStreamQueued(audio_streams.music_stream) < - static_cast(audio_assets.background_music.buffer_length)) - { - SDL_PutAudioStreamData(audio_streams.music_stream, - audio_assets.background_music.buffer, - audio_assets.background_music.buffer_length); - } - }); +} + +void AudioModule::FeedAudioStreams(entt::registry& registry) +{ + auto audio_streams = registry.ctx().get(); + auto audio_assets = registry.ctx().get(); + + if (SDL_GetAudioStreamQueued(audio_streams.music_stream) < + static_cast(audio_assets.background_music.buffer_length)) + { + SDL_PutAudioStreamData(audio_streams.music_stream, + audio_assets.background_music.buffer, + audio_assets.background_music.buffer_length); + } } diff --git a/src/audio.hpp b/src/audio.hpp index 9f37ead..a95ad30 100644 --- a/src/audio.hpp +++ b/src/audio.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include struct AudioAsset { @@ -19,5 +19,6 @@ struct AudioStreams struct AudioModule { - AudioModule(flecs::world& world); + AudioModule(entt::registry& registry); + static void FeedAudioStreams(entt::registry& registry); }; diff --git a/src/level.cpp b/src/level.cpp new file mode 100644 index 0000000..edaa096 --- /dev/null +++ b/src/level.cpp @@ -0,0 +1,125 @@ +#include "level.hpp" +#include "input.hpp" + +#include + +void LevelModule::MoveBasket(entt::registry& registry) +{ + auto const& input = registry.ctx().get(); + auto basket_view = registry.view(); + + for (auto [entity, pos, size, sprite] : basket_view.each()) + { + if (input.pressed.contains(SDLK_LEFT)) + { + pos.x -= 5; + } + if (input.pressed.contains(SDLK_RIGHT)) + { + pos.x += 5; + } + + pos.x = pos.x < 0 ? 0 : pos.x; + pos.x = pos.x > WINDOW_WIDTH - size.w ? WINDOW_WIDTH - size.w : pos.x; + } +} + +void LevelModule::SpawnFruits(entt::registry& registry) +{ + auto& game = registry.ctx().get(); + auto const& texture_assets = registry.ctx().get(); + + std::bernoulli_distribution spider_dist(0.25); + bool spider = spider_dist(game.random_engine); + + std::binomial_distribution<> velocity_dist(3, 0.5); + int vel = velocity_dist(game.random_engine) + 1; + + if ((game.ticks % 50) == 0) + { + auto item = registry.create(); + std::uniform_int_distribution<> xpos_dist(32, WINDOW_WIDTH - 32); + int xpos = xpos_dist(game.random_engine); + if (!spider) + { + std::uniform_int_distribution<> index_dist(0, 228 - 1); + uint16_t index = index_dist(game.random_engine); + + registry.emplace(item); + registry.emplace(item); + registry.emplace(item, Position{.x = xpos, .y = -16}); + registry.emplace(item, Velocity{.x = 0, .y = vel}); + registry.emplace( + item, Sprite{.texture = &texture_assets.fruits, .texture_atlas_index = index}); + registry.emplace(item, Size{.w = 32, .h = 32}); + } + else + { + std::uniform_int_distribution<> index_dist(0, 8 - 1); + uint16_t index = index_dist(game.random_engine); + + registry.emplace(item); + registry.emplace(item); + registry.emplace(item, Position{.x = xpos, .y = -16}); + registry.emplace(item, Velocity{.x = 0, .y = vel}); + registry.emplace( + item, Sprite{.texture = &texture_assets.spiders, .texture_atlas_index = index}); + registry.emplace(item, Size{.w = 32, .h = 32}); + } + + auto collision_box = registry.create(); + registry.emplace(collision_box, item); + registry.emplace(collision_box); + registry.emplace(collision_box, Position{.x = 0, .y = 0}); + registry.emplace(collision_box, Size{.w = 32, .h = 32}); + registry.emplace(collision_box, item); + } +} + +void LevelModule::CollectFruit(entt::registry& registry) +{ + auto& game = registry.ctx().get(); + auto const& audio_streams = registry.ctx().get(); + auto const& audio_assets = registry.ctx().get(); + + auto view = registry.view(); + for (auto [entity, pos] : view.each()) + { + game.score += 10; + pos.x += 1000; + // registry.destroy(entity); + + SDL_PutAudioStreamData(audio_streams.sound_stream, + audio_assets.pickup_sound.buffer, + audio_assets.pickup_sound.buffer_length); + } +} + +void LevelModule::CollectSpider(entt::registry& registry) +{ + auto& game = registry.ctx().get(); + auto const& audio_streams = registry.ctx().get(); + auto const& audio_assets = registry.ctx().get(); + + auto view = registry.view(); + for (auto [entity, pos] : view.each()) + { + game.score -= 50; + pos.x += 1000; + // registry.destroy(entity); + + SDL_PutAudioStreamData(audio_streams.sound_stream, + audio_assets.hit_sound.buffer, + audio_assets.hit_sound.buffer_length); + }; +} + +void LevelModule::DespawnItems(entt::registry& registry) +{ + auto view = registry.view(); + for (auto [entity, pos] : view.each()) + { + if (pos.y >= WINDOW_HEIGHT) + registry.destroy(entity); + } +} diff --git a/src/level.hpp b/src/level.hpp index 9926117..a481e70 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -1,13 +1,16 @@ #pragma once #include "definitions.hpp" -#include "input.hpp" #include "physics.hpp" #include "sprite.hpp" -#include +#include #include +struct Background +{ +}; + struct Fruit { }; @@ -24,175 +27,44 @@ struct Basket { }; +struct BasketCollisionBox +{ +}; + struct LevelModule { - LevelModule(flecs::world& world) + LevelModule(entt::registry& registry) { - auto const* texture_assets = world.get(); + auto const* texture_assets = ®istry.ctx().get(); - world.component(); - world.component().is_a(); - world.component().is_a(); + auto background = registry.create(); + registry.emplace(background, Position{.x = 0, .y = 0}); + registry.emplace( + background, Sprite{.texture = &texture_assets->background, .texture_atlas_index = 0}); + registry.emplace(background, Size{.w = WINDOW_WIDTH, .h = WINDOW_HEIGHT}); + registry.emplace(background); - world.entity("Background") - .set(Position{.x = 0, .y = 0}) - .set(Sprite{.texture = &texture_assets->background, .texture_atlas_index = 0}) - .set(Size{.w = WINDOW_WIDTH, .h = WINDOW_HEIGHT}); + auto basket = registry.create(); + registry.emplace(basket); + registry.emplace(basket, + Position{.x = WINDOW_WIDTH / 2 - 32, .y = WINDOW_HEIGHT - 32}); + registry.emplace( + basket, Sprite{.texture = &texture_assets->basket, .texture_atlas_index = 0}); + registry.emplace(basket, Size{.w = 64, .h = 32}); + registry.emplace(basket); - auto basket = - world.entity("Basket") - .add() - .set(Position{.x = WINDOW_WIDTH / 2 - 32, .y = WINDOW_HEIGHT - 32}) - .set(Sprite{.texture = &texture_assets->basket, .texture_atlas_index = 0}) - .set(Size{.w = 64, .h = 32}) - .add(); - - world.entity() - .child_of(basket) - .add() - .set(Position{.x = 0, .y = 16}) - .set(Size{.w = 64, .h = 16}) - .add(); - - world.system("SpawnFruits") - .term_at(0) - .singleton() - .term_at(1) - .singleton() - .each( - [](flecs::iter& it, size_t index, Game& game, TextureAssets const& texture_assets) - { - std::bernoulli_distribution spider_dist(0.25); - bool spider = spider_dist(game.random_engine); - - std::binomial_distribution<> velocity_dist(3, 0.5); - int vel = velocity_dist(game.random_engine) + 1; - - if ((game.ticks % 50) == 0) - { - flecs::entity e; - std::uniform_int_distribution<> xpos_dist(32, WINDOW_WIDTH - 32); - int xpos = xpos_dist(game.random_engine); - if (!spider) - { - std::uniform_int_distribution<> index_dist(0, 228 - 1); - uint16_t index = index_dist(game.random_engine); - - e = it.world() - .entity() - .add() - .add() - .set(Position{.x = xpos, .y = -16}) - .set(Velocity{.x = 0, .y = vel}) - .set(Sprite{.texture = &texture_assets.fruits, - .texture_atlas_index = index}) - .set(Size{.w = 32, .h = 32}); - } - else - { - std::uniform_int_distribution<> index_dist(0, 8 - 1); - uint16_t index = index_dist(game.random_engine); - - e = it.world() - .entity() - .add() - .add() - .set(Position{.x = xpos, .y = -16}) - .set(Velocity{.x = 0, .y = vel}) - .set(Sprite{.texture = &texture_assets.spiders, - .texture_atlas_index = index}) - .set(Size{.w = 32, .h = 32}); - } - it.world() - .entity("CollisionBox") - .child_of(e) - .add() - .set(Position{.x = 0, .y = 0}) - .set(Size{.w = 32, .h = 32}) - .add(); - } - }); - - // world.system("DespawnItems") - // .kind(flecs::OnValidate) - // .each( - // [](flecs::entity e, WorldPosition const& pos, Item) - // { - // if (pos.y >= WINDOW_HEIGHT) - // e.destruct(); - // }); - - world.system("CollectFruit") - .term_at(0) - .singleton() - .term_at(1) - .singleton() - .term_at(2) - .singleton() - .each( - [](flecs::entity e, - Game& game, - AudioStreams& audio_streams, - AudioAssets& audio_assets, - Position& pos, - Fruit, - Collided) - { - game.score += 10; - pos.x += 1000; - // e.destruct(); - - SDL_PutAudioStreamData(audio_streams.sound_stream, - audio_assets.pickup_sound.buffer, - audio_assets.pickup_sound.buffer_length); - }); - - world.system("CollectSpider") - .term_at(0) - .singleton() - .term_at(1) - .singleton() - .term_at(2) - .singleton() - .each( - [](flecs::entity e, - Game& game, - AudioStreams& audio_streams, - AudioAssets& audio_assets, - Position& pos, - Spider, - Collided) - { - game.score -= 50; - pos.x += 1000; - // e.destruct(); - - SDL_PutAudioStreamData(audio_streams.sound_stream, - audio_assets.hit_sound.buffer, - audio_assets.hit_sound.buffer_length); - }); - - world.system("MoveBasket") - .term_at(0) - .singleton() - .each( - [](ButtonInput const& input, - Position& pos, - Size const& size, - Sprite const& sprite, - Basket) - { - if (input.pressed.contains(SDLK_LEFT)) - { - pos.x -= 5; - } - if (input.pressed.contains(SDLK_RIGHT)) - { - pos.x += 5; - } - - pos.x = pos.x < 0 ? 0 : pos.x; - pos.x = pos.x > WINDOW_WIDTH - size.w ? WINDOW_WIDTH - size.w : pos.x; - }); + auto basket_cb = registry.create(); + registry.emplace(basket_cb); + registry.emplace(basket_cb, Position{.x = 0, .y = 16}); + registry.emplace(basket_cb, Size{.w = 64, .h = 16}); + registry.emplace(basket_cb); + registry.emplace(basket_cb, basket); + registry.emplace(basket_cb); } + + static void MoveBasket(entt::registry& registry); + static void SpawnFruits(entt::registry& registry); + static void CollectFruit(entt::registry ®istry); + static void CollectSpider(entt::registry ®istry); + static void DespawnItems(entt::registry ®istry); }; diff --git a/src/main.cpp b/src/main.cpp index 284415c..e1ff835 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,9 +7,25 @@ #include #include -#include +#include #include +void increment_ticks(entt::registry& registry) +{ + auto& game = registry.ctx().get(); + // auto& translate_system = registry.ctx().get(); + + game.ticks += 1; + + if (game.ticks % 60 == 0) + { + game.time = std::max(0, game.time - 1); + } + + // if (game.time == 0) + // translate_system.translate_system.disable(); +} + int main() { spdlog::info("Initialize SDL..."); @@ -38,42 +54,23 @@ int main() auto* text_engine = TTF_CreateRendererTextEngine(renderer); - flecs::world world; + entt::registry registry; - world.set(Game{.ticks = 0, .time = 60, .score = 0, .random_engine = {}}); - world.set(ButtonInput{}); - world.set( + registry.ctx().emplace(Game{.ticks = 0, .time = 60, .score = 0, .random_engine = {}}); + registry.ctx().emplace(ButtonInput{}); + auto sdl_handles = registry.ctx().emplace( SdlHandles{.window = window, .renderer = renderer, .text_engine = text_engine}); - world.import (); - world.import (); - world.import (); - world.import (); - world.import (); - - world.system("IncrementTicks") - .term_at(0) - .singleton() - .term_at(1) - .singleton() - .each( - [](Game& game, TranslateSystem& translate_system) - { - game.ticks += 1; - - if (game.ticks % 60 == 0) - { - game.time = std::max(0, game.time - 1); - } - - if (game.time == 0) - translate_system.translate_system.disable(); - }); + AssetModule asset_module(registry); + AudioModule audio_module(registry); + RenderModule render_module(registry); + PhysicsModule physics_module(registry); + LevelModule level_module(registry); bool exit_gameloop = false; while (!exit_gameloop) { - auto* input = world.get_mut(); + auto* input = ®istry.ctx().get(); // Clear just pressed/released input->just_pressed.clear(); @@ -107,7 +104,24 @@ int main() } } - world.progress(); + AudioModule::FeedAudioStreams(registry); + + increment_ticks(registry); + LevelModule::MoveBasket(registry); + LevelModule::SpawnFruits(registry); + LevelModule::CollectFruit(registry); + LevelModule::CollectSpider(registry); + // LevelModule::DespawnItems(registry); + + PhysicsModule::TranslatePhysicsObject(registry); + PhysicsModule::PropagatePosition(registry); + PhysicsModule::RemoveCollisionMarker(registry); + PhysicsModule::CollisionCheck(registry); + + SDL_RenderClear(sdl_handles.renderer); + RenderModule::RenderSprites(registry); + RenderModule::RenderScore(registry); + SDL_RenderPresent(sdl_handles.renderer); } SDL_DestroyRenderer(renderer); diff --git a/src/physics.cpp b/src/physics.cpp index 19f62c0..b63b313 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -3,84 +3,68 @@ #include -PhysicsModule::PhysicsModule(flecs::world& world) +void PhysicsModule::TranslatePhysicsObject(entt::registry& registry) { - auto translate_system = world.system("TranslatePhysicsObject") - .each( - [](Position& pos, Velocity const& vel) - { - pos.x += vel.x; - pos.y += vel.y; - }); + auto view = registry.view(); - world.set(TranslateSystem{translate_system}); + for (auto [entity, pos, vel] : view.each()) + { + pos.x += vel.x; + pos.y += vel.y; + } +} - // Introduce phase that runs after OnUpdate but before OnValidate - flecs::entity propagate_phase = world.entity().add(flecs::Phase).depends_on(flecs::OnUpdate); +void PhysicsModule::PropagatePosition(entt::registry& registry) +{ + auto root_transform_view = registry.view(entt::exclude); + auto transform_view = registry.view(); - world.system("PropagatePosition") - .kind(propagate_phase) - .each( - [](flecs::entity e, WorldPosition& world_pos, Position const& local_pos) + for (auto [entity, pos, world_pos] : root_transform_view.each()) + { + world_pos.x = pos.x; + world_pos.y = pos.y; + } + + for (auto [entity, pos, world_pos, parent] : transform_view.each()) + { + auto parent_pos = registry.get(parent.parent); + + world_pos.x = parent_pos.x + pos.x; + world_pos.y = parent_pos.y + pos.y; + } +} + +void PhysicsModule::RemoveCollisionMarker(entt::registry& registry) +{ + auto view = registry.view(); + for (auto [entity] : view.each()) + { + registry.remove(entity); + } +} +void PhysicsModule::CollisionCheck(entt::registry& registry) +{ + auto view = registry.view( + entt::exclude); + auto basket_cb_view = registry.view(); + + for (auto [e, world_pos, size, parent] : view.each()) + { + auto fruit = parent.parent; + + for (auto [basket, basket_world_pos, basket_size] : basket_cb_view.each()) + { + if (basket_world_pos.x + basket_size.w >= world_pos.x && + basket_world_pos.x <= world_pos.x + size.w && + basket_world_pos.y + basket_size.h >= world_pos.y && + basket_world_pos.y <= world_pos.y + size.h) { - if (e.parent() != flecs::entity::null() && e.parent().has()) - return; + registry.emplace(fruit); + } + } + } +} - world_pos.x = local_pos.x; - world_pos.y = local_pos.y; - - std::function propagate_to_children; - propagate_to_children = [&](flecs::entity parent, WorldPosition const& parent_pos) - { - parent.children( - [=](flecs::entity child) - { - auto local_pos = child.get(); - auto world_pos = child.get_mut(); - - world_pos->x = parent_pos.x + local_pos->x; - world_pos->y = parent_pos.y + local_pos->y; - - propagate_to_children(child, *world_pos); - }); - }; - - propagate_to_children(e, world_pos); - }); - - 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( - [basket_query]( - flecs::entity e, WorldPosition const& world_pos, Size const& size, CollisionBox) - { - if (e.parent().has()) - return; - - auto fruit = e.parent(); - auto basket = basket_query.first(); - basket.children( - [fruit, world_pos, size](flecs::entity basket_child) - { - if (!basket_child.has()) - return; - - auto basket_child_pos = basket_child.get(); - auto basket_child_size = basket_child.get(); - - if (basket_child_pos->x + basket_child_size->w >= world_pos.x && - basket_child_pos->x <= world_pos.x + size.w && - basket_child_pos->y + basket_child_size->h >= world_pos.y && - basket_child_pos->y <= world_pos.y + size.h) - { - fruit.add(); - } - }); - }); +PhysicsModule::PhysicsModule(entt::registry& registry) +{ } \ No newline at end of file diff --git a/src/physics.hpp b/src/physics.hpp index 36ff898..e77a009 100644 --- a/src/physics.hpp +++ b/src/physics.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include struct WorldPosition { @@ -26,6 +26,16 @@ struct Size int h; }; +struct Parent +{ + entt::entity parent; +}; + +struct Children +{ + std::vector children; +}; + struct CollisionBox { }; @@ -34,12 +44,12 @@ struct Collided { }; -struct TranslateSystem -{ - flecs::system translate_system; -}; - struct PhysicsModule { - PhysicsModule(flecs::world& world); + PhysicsModule(entt::registry& registry); + + static void TranslatePhysicsObject(entt::registry& registry); + static void PropagatePosition(entt::registry& registry); + static void RemoveCollisionMarker(entt::registry& registry); + static void CollisionCheck(entt::registry& registry); }; diff --git a/src/render.cpp b/src/render.cpp index caec6ee..6f0bf06 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -1,73 +1,72 @@ #include "render.hpp" #include "definitions.hpp" +#include "level.hpp" #include "physics.hpp" #include "sprite.hpp" #include -RenderModule::RenderModule(flecs::world& world) +RenderModule::RenderModule(entt::registry& registry) { - world.system("RenderClear") - .term_at(0) - .singleton() - .kind(flecs::PreStore) - .each([](SdlHandles& sdl_handles) { SDL_RenderClear(sdl_handles.renderer); }); - - flecs::entity render_present_phase = - world.entity().add(flecs::Phase).depends_on(flecs::OnStore); - - world.system("RenderPresent") - .term_at(0) - .singleton() - .kind(render_present_phase) - .each([](SdlHandles& sdl_handles) { SDL_RenderPresent(sdl_handles.renderer); }); - - world.system("RenderSprites") - .kind(flecs::OnStore) - .term_at(0) - .singleton() - .each( - [](SdlHandles const& sdl_handles, - Position const& pos, - Size const& size, - Sprite const& sprite) - { - TextureAtlasLayout layout = sprite.texture->texture_atlas_layout; - uint8_t row = sprite.texture_atlas_index / layout.columns; - uint8_t column = sprite.texture_atlas_index % layout.columns; - SDL_FRect srcrect{static_cast(column * layout.width), - static_cast(row * layout.height), - static_cast(layout.width), - static_cast(layout.height)}; - - SDL_FRect dstrect{static_cast(pos.x), - static_cast(pos.y), - static_cast(size.w), - static_cast(size.h)}; - - SDL_RenderTexture( - 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); - }); } + +void RenderModule::RenderSprites(entt::registry& registry) +{ + auto const& sdl_handles = registry.ctx().get(); + auto const& game = registry.ctx().get(); + auto sprites_view = + registry.view(entt::exclude); + auto background_view = registry.view(); + + for (auto [entity, pos, size, sprite] : background_view.each()) + { + TextureAtlasLayout layout = sprite.texture->texture_atlas_layout; + uint8_t row = sprite.texture_atlas_index / layout.columns; + uint8_t column = sprite.texture_atlas_index % layout.columns; + SDL_FRect srcrect{static_cast(column * layout.width), + static_cast(row * layout.height), + static_cast(layout.width), + static_cast(layout.height)}; + + SDL_FRect dstrect{static_cast(pos.x), + static_cast(pos.y), + static_cast(size.w), + static_cast(size.h)}; + + SDL_RenderTexture(sdl_handles.renderer, sprite.texture->sdl_texture, &srcrect, &dstrect); + } + + for (auto [entity, pos, size, sprite] : sprites_view.each()) + { + TextureAtlasLayout layout = sprite.texture->texture_atlas_layout; + uint8_t row = sprite.texture_atlas_index / layout.columns; + uint8_t column = sprite.texture_atlas_index % layout.columns; + SDL_FRect srcrect{static_cast(column * layout.width), + static_cast(row * layout.height), + static_cast(layout.width), + static_cast(layout.height)}; + + SDL_FRect dstrect{static_cast(pos.x), + static_cast(pos.y), + static_cast(size.w), + static_cast(size.h)}; + + SDL_RenderTexture(sdl_handles.renderer, sprite.texture->sdl_texture, &srcrect, &dstrect); + } +} + +void RenderModule::RenderScore(entt::registry& registry) +{ + auto const& sdl_handles = registry.ctx().get(); + auto const& game = registry.ctx().get(); + auto const& font_assets = registry.ctx().get(); + + 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); +} \ No newline at end of file diff --git a/src/render.hpp b/src/render.hpp index 48b944b..3722ab3 100644 --- a/src/render.hpp +++ b/src/render.hpp @@ -1,8 +1,11 @@ #pragma once -#include +#include struct RenderModule { - RenderModule(flecs::world& world); + RenderModule(entt::registry& registry); + + static void RenderSprites(entt::registry& registry); + static void RenderScore(entt::registry& registry); };