From 30697862fbd0c356922a859e9676fb9623a0b700 Mon Sep 17 00:00:00 2001 From: fallahn Date: Mon, 17 Jul 2023 11:58:15 +0100 Subject: [PATCH] create initial layout of stats browser --- samples/golf/src/golf/StatsState.cpp | 167 ++++++++++++++++++++++++++- samples/golf/src/golf/StatsState.hpp | 24 ++++ 2 files changed, 187 insertions(+), 4 deletions(-) diff --git a/samples/golf/src/golf/StatsState.cpp b/samples/golf/src/golf/StatsState.cpp index e7cb04b59..ea100a808 100644 --- a/samples/golf/src/golf/StatsState.cpp +++ b/samples/golf/src/golf/StatsState.cpp @@ -83,7 +83,8 @@ StatsState::StatsState(cro::StateStack& ss, cro::State::Context ctx, SharedState : cro::State (ss, ctx), m_scene (ctx.appInstance.getMessageBus()), m_sharedData (sd), - m_viewScale (2.f) + m_viewScale (2.f), + m_currentTab (0) { ctx.mainWindow.setMouseCaptured(false); @@ -126,11 +127,20 @@ bool StatsState::handleEvent(const cro::Event& evt) else if (evt.type == SDL_CONTROLLERBUTTONUP) { cro::App::getWindow().setMouseCaptured(true); - if (evt.cbutton.button == cro::GameController::ButtonB - || evt.cbutton.button == cro::GameController::ButtonStart) + + switch (evt.cbutton.button) { + default: break; + case cro::GameController::ButtonB: + case cro::GameController::ButtonStart: quitState(); return false; + case cro::GameController::ButtonRightShoulder: + activateTab((m_currentTab + 1) % TabID::Max); + break; + case cro::GameController::ButtonLeftShoulder: + activateTab((m_currentTab + (TabID::Max - 1)) % TabID::Max); + break; } } else if (evt.type == SDL_MOUSEBUTTONUP) @@ -290,7 +300,76 @@ void StatsState::buildScene() entity.getComponent().setOrigin({ std::floor(bounds.width / 2.f), std::floor(bounds.height / 2.f) }); rootNode.getComponent().addChild(entity.getComponent()); - + auto bgNode = entity; + + //tab buttons + entity = m_scene.createEntity(); + entity.addComponent().setPosition({ 0.f, 0.f, 0.1f }); + entity.addComponent(); + entity.addComponent() = spriteSheet.getSprite("club_stats_button"); + bgNode.getComponent().addChild(entity.getComponent()); + + m_tabEntity = entity; + + auto selectedID = m_scene.getSystem()->addCallback( + [&](cro::Entity e) + { + e.getComponent().active = true; + e.getComponent().setColour(cro::Colour::White); + m_audioEnts[AudioID::Back].getComponent().play(); + }); + auto unselectedID = m_scene.getSystem()->addCallback( + [](cro::Entity e) + { + e.getComponent().setColour(cro::Colour::Transparent); + }); + + + + //const float bgWidth = bounds.width; + const float stride = 102.f; + auto sprite = spriteSheet.getSprite("button_highlight"); + bounds = sprite.getTextureBounds(); + const float offset = 52.f; + + for (auto i = 0; i < TabID::Max; ++i) + { + entity = m_scene.createEntity(); + entity.addComponent().setPosition({ (stride * i) + offset, 13.f, 0.5f }); + entity.getComponent().setOrigin({ std::floor(bounds.width / 2.f), std::floor(bounds.height / 2.f) }); + entity.getComponent().move(entity.getComponent().getOrigin()); + entity.addComponent(); + entity.addComponent() = sprite; + entity.getComponent().setColour(cro::Colour::Transparent); + + entity.addComponent().area = bounds; + entity.getComponent().enabled = i != m_currentTab; + entity.getComponent().callbacks[cro::UIInput::Selected] = selectedID; + entity.getComponent().callbacks[cro::UIInput::Unselected] = unselectedID; + entity.getComponent().callbacks[cro::UIInput::ButtonDown] = + m_scene.getSystem()->addCallback( + [&, i](cro::Entity e, const cro::ButtonEvent& evt) + { + if (activated(evt)) + { + activateTab(i); + e.getComponent().setColour(cro::Colour::Transparent); + } + }); + + entity.addComponent().function = MenuTextCallback(); + + bgNode.getComponent().addChild(entity.getComponent()); + + m_tabButtons[i] = entity; + } + + + createClubStatsTab(bgNode, spriteSheet); + createPerformanceTab(bgNode, spriteSheet); + createHistoryTab(bgNode); + createAwardsTab(bgNode); + auto updateView = [&, rootNode](cro::Camera& cam) mutable { glm::vec2 size(GolfGame::getActiveTarget()->getSize()); @@ -327,6 +406,86 @@ void StatsState::buildScene() m_scene.simulate(0.f); } +void StatsState::createClubStatsTab(cro::Entity parent, const cro::SpriteSheet& spriteSheet) +{ + m_tabNodes[TabID::ClubStats] = m_scene.createEntity(); + m_tabNodes[TabID::ClubStats].addComponent().setPosition({ 0.f, 0.f, 0.2f }); + parent.getComponent().addChild(m_tabNodes[TabID::ClubStats].getComponent()); + + const auto centre = parent.getComponent().getTextureBounds().width / 2.f; + + auto entity = m_scene.createEntity(); + entity.addComponent().setPosition({ centre, 36.f, 0.1f }); + entity.addComponent(); + entity.addComponent() = spriteSheet.getSprite("club_stats"); + entity.getComponent().move(glm::vec2(-entity.getComponent().getTextureBounds().width / 2.f, 0.f)); + m_tabNodes[TabID::ClubStats].getComponent().addChild(entity.getComponent()); +} + +void StatsState::createPerformanceTab(cro::Entity parent, const cro::SpriteSheet& spriteSheet) +{ + m_tabNodes[TabID::Performance] = m_scene.createEntity(); + m_tabNodes[TabID::Performance].addComponent().setPosition({ 0.f, 0.f, 0.2f }); + m_tabNodes[TabID::Performance].getComponent().setScale(glm::vec2(0.f)); + parent.getComponent().addChild(m_tabNodes[TabID::Performance].getComponent()); + + const auto centre = parent.getComponent().getTextureBounds().width / 2.f; + + auto entity = m_scene.createEntity(); + entity.addComponent().setPosition({ centre, 38.f, 0.1f }); + entity.addComponent(); + entity.addComponent() = spriteSheet.getSprite("performance"); + entity.getComponent().move(glm::vec2(-entity.getComponent().getTextureBounds().width / 2.f, 0.f)); + m_tabNodes[TabID::Performance].getComponent().addChild(entity.getComponent()); +} + +void StatsState::createHistoryTab(cro::Entity parent) +{ + m_tabNodes[TabID::History] = m_scene.createEntity(); + m_tabNodes[TabID::History].addComponent().setPosition({ 0.f, 0.f, 0.2f }); + m_tabNodes[TabID::History].getComponent().setScale(glm::vec2(0.f)); + parent.getComponent().addChild(m_tabNodes[TabID::History].getComponent()); +} + +void StatsState::createAwardsTab(cro::Entity parent) +{ + m_tabNodes[TabID::Awards] = m_scene.createEntity(); + m_tabNodes[TabID::Awards].addComponent().setPosition({ 0.f, 0.f, 0.2f }); + m_tabNodes[TabID::Awards].getComponent().setScale(glm::vec2(0.f)); + parent.getComponent().addChild(m_tabNodes[TabID::Awards].getComponent()); + + auto& font = m_sharedData.sharedResources->fonts.get(FontID::UI); + auto entity = m_scene.createEntity(); + entity.addComponent().setPosition({ 18.f, 200.f, 0.1f }); + entity.addComponent(); + entity.addComponent(font).setString("No Awards... sad :("); + entity.getComponent().setCharacterSize(UITextSize); + entity.getComponent().setFillColour(TextNormalColour); + + m_tabNodes[TabID::Awards].getComponent().addChild(entity.getComponent()); +} + +void StatsState::activateTab(std::int32_t tabID) +{ + //update old + m_tabButtons[m_currentTab].getComponent().enabled = true; + m_tabNodes[m_currentTab].getComponent().setScale(glm::vec2(0.f)); + + //update index + m_currentTab = tabID; + + //update new + m_tabButtons[m_currentTab].getComponent().enabled = false; + m_tabNodes[m_currentTab].getComponent().setScale(glm::vec2(1.f)); + + //update the button selection graphic + auto bounds = m_tabEntity.getComponent().getTextureRect(); + bounds.bottom = bounds.height * m_currentTab; + m_tabEntity.getComponent().setTextureRect(bounds); + + m_audioEnts[AudioID::Accept].getComponent().play(); +} + void StatsState::quitState() { m_scene.setSystemActive(false); diff --git a/samples/golf/src/golf/StatsState.hpp b/samples/golf/src/golf/StatsState.hpp index c0911ba3b..cb221f2a4 100644 --- a/samples/golf/src/golf/StatsState.hpp +++ b/samples/golf/src/golf/StatsState.hpp @@ -36,6 +36,10 @@ source distribution. #include struct SharedStateData; +namespace cro +{ + class SpriteSheet; +} class StatsState final : public cro::State { @@ -72,6 +76,26 @@ class StatsState final : public cro::State glm::vec2 m_viewScale; cro::Entity m_rootNode; + struct TabID final + { + enum + { + ClubStats, Performance, History, Awards, + + Count + }; + static constexpr std::int32_t Max = 4; + }; + std::int32_t m_currentTab; + cro::Entity m_tabEntity; + std::array m_tabButtons = {}; + std::array m_tabNodes = {}; + void buildScene(); + void createClubStatsTab(cro::Entity, const cro::SpriteSheet&); + void createPerformanceTab(cro::Entity, const cro::SpriteSheet&); + void createHistoryTab(cro::Entity); + void createAwardsTab(cro::Entity); + void activateTab(std::int32_t); void quitState(); }; \ No newline at end of file