ADD: Main Menu
All checks were successful
Tests / test (push) Successful in 2m28s

This commit is contained in:
Sebastian Böckelmann 2026-04-24 21:11:18 +02:00
parent c33f571567
commit 363b6ca39b
14 changed files with 153 additions and 8 deletions

View File

@ -321,6 +321,10 @@ if(BUILD_GAME)
src/engine/core/scenes/SplashScreenLayer.h src/engine/core/scenes/SplashScreenLayer.h
src/engine/core/gui/uiComponent/UiProgressbar.cpp src/engine/core/gui/uiComponent/UiProgressbar.cpp
src/engine/core/gui/uiComponent/UiProgressbar.h src/engine/core/gui/uiComponent/UiProgressbar.h
src/game/scenes/main/MainMenu.cpp
src/game/scenes/main/MainMenu.h
src/game/scenes/main/MainUiLayer.cpp
src/game/scenes/main/MainUiLayer.h
) )
target_compile_options(Dicewars_Siedler PRIVATE target_compile_options(Dicewars_Siedler PRIVATE
-Wall -Wall

BIN
assets/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

@ -8,6 +8,10 @@ UiContainer::UiContainer(){
uiPositioner.screenSpace.set(0.f, 0.f, 1.f, 1.f); uiPositioner.screenSpace.set(0.f, 0.f, 1.f, 1.f);
} }
void UiContainer::setBackgroundTexture(GLuint textureID) {
backgroundTextureID = textureID;
}
bool UiContainer::isMouseOver(float mouseX, float mouseY) { bool UiContainer::isMouseOver(float mouseX, float mouseY) {
for (const auto &child : children) { for (const auto &child : children) {
if (child->isMouseOver(mouseX, mouseY)) return true; if (child->isMouseOver(mouseX, mouseY)) return true;
@ -19,7 +23,13 @@ void UiContainer::onUpdate(float x) {
} }
void UiContainer::onCollectRenderData(UiRenderBundle& render_bundle) { void UiContainer::onCollectRenderData(UiRenderBundle& renderBundle) {
if (backgroundTextureID.has_value()) {
GUITextureBuilder builder = GUITextureBuilder();
builder.Foreground(backgroundTextureID.value());
builder.Scale(glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height));
builder.Position(glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y));
renderBundle.addGUITexture(std::make_shared<GUITexture>(builder.Build()));
}
} }

View File

@ -4,15 +4,21 @@
#ifndef DICEWARS_SIEDLER_UICONTAINER_H #ifndef DICEWARS_SIEDLER_UICONTAINER_H
#define DICEWARS_SIEDLER_UICONTAINER_H #define DICEWARS_SIEDLER_UICONTAINER_H
#include <optional>
#include "../uiComponent/UiComponent.h" #include "../uiComponent/UiComponent.h"
class UiContainer : public UiComponent { class UiContainer : public UiComponent {
public: public:
UiContainer(); UiContainer();
void setBackgroundTexture(GLuint textureID);
bool isMouseOver(float mouseX, float mouseY) override; bool isMouseOver(float mouseX, float mouseY) override;
void onUpdate(float) override; void onUpdate(float) override;
void onCollectRenderData(UiRenderBundle& renderBundle) override; void onCollectRenderData(UiRenderBundle& renderBundle) override;
private:
std::optional<GLuint> backgroundTextureID;
}; };

View File

@ -7,7 +7,8 @@
#include "Scene.h" #include "Scene.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
void SceneManager::switchTo(std::unique_ptr<Scene> next) { void SceneManager::switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded) {
onSceneLoaded = std::move(onLoaded);
nextScene = std::move(next); nextScene = std::move(next);
std::vector<AssetRequest> requestedAssets = nextScene->getRequiredAssets(); std::vector<AssetRequest> requestedAssets = nextScene->getRequiredAssets();
spdlog::debug("Required assets: {}", requestedAssets.size()); spdlog::debug("Required assets: {}", requestedAssets.size());
@ -30,6 +31,11 @@ void SceneManager::update() {
nextScene = nullptr; nextScene = nullptr;
currentScene->onEnter(); currentScene->onEnter();
assetLoader.stop(); assetLoader.stop();
if (onSceneLoaded) {
onSceneLoaded();
onSceneLoaded = nullptr;
}
} }
} }
@ -45,3 +51,11 @@ void SceneManager::render() {
} }
SceneManager::~SceneManager() = default; SceneManager::~SceneManager() = default;
float SceneManager::getTransitionProgress() const {
if (assetLoader.getProgress().isDone()) {
return 1.0f;
} else {
return assetLoader.getProgress().fraction();
}
}

View File

@ -11,10 +11,12 @@ class Scene;
class SceneManager { class SceneManager {
public: public:
void switchTo(std::unique_ptr<Scene> next); void switchTo(std::unique_ptr<Scene> next, std::function<void()> onLoaded = nullptr);
void update(); void update();
void render(); void render();
~SceneManager(); ~SceneManager();
float getTransitionProgress() const;
private: private:
std::unique_ptr<Scene> currentScene; std::unique_ptr<Scene> currentScene;
std::unique_ptr<Scene> nextScene; std::unique_ptr<Scene> nextScene;
@ -22,6 +24,8 @@ private:
AssetLoader assetLoader; AssetLoader assetLoader;
bool isTransitioning = false; bool isTransitioning = false;
std::function<void()> onSceneLoaded;
}; };

View File

@ -4,6 +4,7 @@
#include "SplashScreenLayer.h" #include "SplashScreenLayer.h"
#include "SceneManager.h"
#include "../../renderer/loader/AssetManager.h" #include "../../renderer/loader/AssetManager.h"
#include "../../renderer/GUIRenderer.h" #include "../../renderer/GUIRenderer.h"
#include "../gui/uiComponent/UiImage.h" #include "../gui/uiComponent/UiImage.h"
@ -29,7 +30,8 @@ void SplashScreenLayer::onUpdate() {
Dimensions rootParent {0.0, 0.0, 1.0, 1.0f}; Dimensions rootParent {0.0, 0.0, 1.0, 1.0f};
rootContainer->uiPositioner.compute(rootParent); rootContainer->uiPositioner.compute(rootParent);
progressbar->setProgress(progressbar->getProgress() + 0.01f); const auto loadingProgress = Application::getInstance().sceneManager->getTransitionProgress();
progressbar->setProgress(loadingProgress);
} }
void SplashScreenLayer::onAttach() { void SplashScreenLayer::onAttach() {

View File

@ -37,9 +37,11 @@ void AssetLoader::scheduleAsset(const AssetRequest &assetRequest) {
} }
void AssetLoader::start() { void AssetLoader::start() {
if (!running) {
running = true; running = true;
loadingThread = std::thread(&AssetLoader::loadingThreadFunc, this); loadingThread = std::thread(&AssetLoader::loadingThreadFunc, this);
} }
}
void AssetLoader::stop() { void AssetLoader::stop() {
running = false; running = false;

View File

@ -6,7 +6,10 @@
#include "../engine/core/scenes/SceneManager.h" #include "../engine/core/scenes/SceneManager.h"
#include "../engine/core/scenes/SplashScreen.h" #include "../engine/core/scenes/SplashScreen.h"
#include "scenes/main/MainMenu.h"
DicewarsApp::DicewarsApp() { DicewarsApp::DicewarsApp() {
sceneManager->switchTo(std::make_unique<SplashScreen>()); sceneManager->switchTo(std::make_unique<SplashScreen>(), [this]() {
sceneManager->switchTo(std::make_unique<MainMenu>());
});
} }

View File

@ -0,0 +1,23 @@
//
// Created by sebastian on 24.04.26.
//
#include "MainMenu.h"
#include "MainUiLayer.h"
void MainMenu::onEnter() {
addLayer(std::make_unique<MainUiLayer>());
}
void MainMenu::onExit() {
for (const auto& layer: layers) {
layer->onDetach();
}
}
std::vector<AssetRequest> MainMenu::getRequiredAssets() {
std::vector<AssetRequest> requests;
requests.emplace_back(TextureRequest("mainCover", "assets/background.png"));
return requests;
}

View File

@ -0,0 +1,20 @@
//
// Created by sebastian on 24.04.26.
//
#ifndef MAINMENU_H
#define MAINMENU_H
#include "../../../engine/core/scenes/Scene.h"
class MainMenu: public Scene {
public:
void onEnter() override;
void onExit() override;
std::vector<AssetRequest> getRequiredAssets() override;
};
#endif //MAINMENU_H

View File

@ -0,0 +1,31 @@
//
// Created by sebastian on 24.04.26.
//
#include "MainUiLayer.h"
#include "../../../engine/renderer/loader/AssetManager.h"
void MainUiLayer::onAttach() {
rootContainer = std::make_unique<UiContainer>();
rootContainer->setBackgroundTexture(AssetManager::getTexture("mainCover")->getTextureID());
}
void MainUiLayer::onDetach() {
}
void MainUiLayer::onRender() {
UiRenderBundle renderBundle;
if (rootContainer) {
rootContainer->collectRenderData(renderBundle);
}
auto guis = renderBundle.getGUITextures();
guiRenderer->render(guis);
}
void MainUiLayer::onUpdate() {
Dimensions rootParent {0.0, 0.0, 1.0, 1.0f};
rootContainer->uiPositioner.compute(rootParent);
}

View File

@ -0,0 +1,26 @@
//
// Created by sebastian on 24.04.26.
//
#ifndef MAINUILAYER_H
#define MAINUILAYER_H
#include "../../../engine/layer/Layer.h"
#include "../../../engine/renderer/GUIRenderer.h"
#include "../../../engine/renderer/loader/Loader.h"
#include "../../../engine/core/gui/uiMain/UiContainer.h"
class MainUiLayer: public Layer {
public:
MainUiLayer(): guiRenderer(std::make_unique<GUIRenderer>(Loader::instance())) {}
void onAttach() override;
void onDetach() override;
void onRender() override;
void onUpdate() override;
private:
std::unique_ptr<GUIRenderer> guiRenderer;
std::unique_ptr<UiContainer> rootContainer;
};
#endif //MAINUILAYER_H