From a09f1d15c6b158740e05b273cba90224a3b2bec2 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 22 Jan 2025 18:41:15 +0100 Subject: [PATCH 01/29] Adding instructions for syntax errors under vscode in README --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 8e5bcd0..e464b3a 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,31 @@ 4. Visual Studio erkennt automatisch das CMake-Projekt 5. Build über "Build All" ausführen +#### Falls Syntax errors + +1. Erstelle .vscode/c_cpp_properties.json Datei +2. Füge die folgende JSON so oder so ähnlich ein: + +```json +{ + "configurations": [ + { + "name": "Fedora", + "includePath": [ + "/usr/include", + "/usr/include/SDL2" + ], + "defines": [], + "intelliSenseMode": "linux-gcc-x64", + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "c++17" + } + ], + "version": 4 +} +``` + ## Build-Optionen CMake kann mit verschiedenen Optionen konfiguriert werden: -- GitLab From 6e36612d6123c68fdd6fc9eea6f53b3922f30123 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 22 Jan 2025 20:16:39 +0100 Subject: [PATCH 02/29] Refactoring CMakeLists.txt Changing SDL to SDL2 Refactoring level, engine, scene, spritesheet, window changing SDL to SDL2 --- CMakeLists.txt | 9 +++++++++ src/engine.cpp | 2 +- src/engine.hpp | 2 +- src/level.cpp | 2 +- src/level.hpp | 2 +- src/scene.hpp | 2 +- src/spritesheet.hpp | 2 +- src/window.hpp | 2 +- 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6ceb5d..17ad577 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,8 @@ project(ADVANCED_WARS file(GLOB ADVANCED_WARS_SOURCES "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/*.hpp" + "${PROJECT_SOURCE_DIR}/src/ui/*.cpp" + "${PROJECT_SOURCE_DIR}/src/ui/*.hpp" ) # C++ Standard festlegen @@ -30,10 +32,14 @@ set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH}) # SDL2 find_package(SDL2 REQUIRED) find_package(SDL2_IMAGE REQUIRED) +find_package(SDL2_ttf REQUIRED) find_package(HDF5 REQUIRED COMPONENTS CXX) +include_directories(/usr/include/SDL2) + include_directories(${SDL2_INCLUDE_DIR}) include_directories(${SDL2_IMG_INCLUDE_DIR}) +include_directories(${SDL2_TTF_INCLUDE_DIR}) include_directories(${HDF5_INCLUDE_DIRS}) # Executable erstellen @@ -41,6 +47,9 @@ add_executable(advanced_wars src/main.cpp ${ADVANCED_WARS_SOURCES}) target_link_libraries(advanced_wars ${SDL2_LIBRARY} ${SDL2_IMG_LIBRARY} + ${SDL2_TTF_LIBRARIY} ${HDF5_LIBRARIES} + -lSDL2 + -lSDL2_ttf m ) \ No newline at end of file diff --git a/src/engine.cpp b/src/engine.cpp index 69da6ac..ce0ed91 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -3,7 +3,7 @@ #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" -#include <SDL.h> +#include <SDL2/SDL.h> #include <SDL_image.h> #include <stdexcept> #include <vector> diff --git a/src/engine.hpp b/src/engine.hpp index 2eb4341..db2abeb 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -4,7 +4,7 @@ #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" -#include <SDL.h> +#include <SDL2/SDL.h> #include <optional> #include <vector> diff --git a/src/level.cpp b/src/level.cpp index 0504c41..b744f99 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -3,7 +3,7 @@ #include "unit.hpp" #include <string> #include <iostream> -#include <SDL.h> +#include <SDL2/SDL.h> namespace advanced_wars { diff --git a/src/level.hpp b/src/level.hpp index 367615b..fdb8fa5 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -4,7 +4,7 @@ #include "scene.hpp" #include "tile.hpp" #include "unit.hpp" -#include <SDL.h> +#include <SDL2/SDL.h> #include <string> #include <vector> diff --git a/src/scene.hpp b/src/scene.hpp index 9730ff5..bbc0861 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -1,6 +1,6 @@ #pragma once -#include <SDL.h> +#include <SDL2/SDL.h> #include <vector> namespace advanced_wars { diff --git a/src/spritesheet.hpp b/src/spritesheet.hpp index f9d60e1..a96889d 100644 --- a/src/spritesheet.hpp +++ b/src/spritesheet.hpp @@ -1,7 +1,7 @@ #pragma once #include "SDL_render.h" -#include <SDL.h> +#include <SDL2/SDL.h> #include <string> #include <vector> diff --git a/src/window.hpp b/src/window.hpp index 9cd664d..3b6adc3 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -1,6 +1,6 @@ #pragma once -#include <SDL.h> +#include <SDL2/SDL.h> #include <string> namespace advanced_wars { -- GitLab From 61ff93da18769b92a03b7f6ba784fbcf2f5dcbea Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 22 Jan 2025 20:16:52 +0100 Subject: [PATCH 03/29] Adding Menu Class --- src/ui/Menu.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/Menu.hpp | 49 +++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/ui/Menu.cpp create mode 100644 src/ui/Menu.hpp diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp new file mode 100644 index 0000000..97dd9da --- /dev/null +++ b/src/ui/Menu.cpp @@ -0,0 +1,101 @@ +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> +#include <iostream> +#include <vector> +#include <string> +#include "Menu.hpp" + +namespace advanced_wars +{ + + MainMenu::MainMenu(int selectedOption) + : selectedOption(selectedOption), + options({"Start Game", "Options", "Exit"}) + { + + } + + MainMenu::~MainMenu() { + + }; + + void MainMenu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { + + if (events.size() > 0) { + for (auto event: events) { + handleEvent(event); + } + } + + + // Clear the screen with a background color + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + // Initialize SDL_TTF if not already done + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; + return; + } + + // Load a font + TTF_Font* font = TTF_OpenFont("/usr/share/fonts/ARCADECLASSIC.TTF", 24); + if (!font) { + std::cerr << "Failed to load font: " << TTF_GetError() << std::endl; + return; + } + + // Colors for text rendering + SDL_Color white = {255, 255, 255, 255}; + SDL_Color yellow = {255, 255, 0, 255}; + + // Render each menu option + for (size_t i = 0; i < options.size(); ++i) { + SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white); + if (!textSurface) { + std::cerr << "Failed to create text surface: " << TTF_GetError() << std::endl; + continue; + } + + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + if (!textTexture) { + std::cerr << "Failed to create text texture: " << SDL_GetError() << std::endl; + SDL_FreeSurface(textSurface); + continue; + } + + // Define text position and size + SDL_Rect textRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h}; + + // Render the texture + SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + + // Clean up resources + SDL_DestroyTexture(textTexture); + SDL_FreeSurface(textSurface); + } + + // Close the font and quit TTF + TTF_CloseFont(font); + TTF_Quit(); + + // Present the rendered content + SDL_RenderPresent(renderer); + } + + void MainMenu::handleEvent(SDL_Event& event) { + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_DOWN) { + selectedOption = (selectedOption + 1) % options.size(); + } else if (event.key.keysym.sym == SDLK_UP) { + selectedOption = (selectedOption - 1 + options.size()) % options.size(); + } else if (event.key.keysym.sym == SDLK_RETURN) { + if (options[selectedOption] == "Exit") { + std::cout << "Exiting game..." << std::endl; + // Exit logic here + } + } + } + } + +} diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp new file mode 100644 index 0000000..350c25a --- /dev/null +++ b/src/ui/Menu.hpp @@ -0,0 +1,49 @@ +#ifndef MENU_SYSTEM_HPP +#define MENU_SYSTEM_HPP + +#include <SDL2/SDL.h> +#include <iostream> +#include <vector> +#include <string> +#include <array> +#include "../scene.hpp" + +namespace advanced_wars { + +class BaseMenu : public Scene { +public: + virtual void handleEvent(SDL_Event& event); + virtual ~BaseMenu(); +}; + +class MainMenu : public Scene { +private: + size_t selectedOption; + std::array<std::string, 3> options; + +public: + + MainMenu(int selectedOption); + + void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); + + void handleEvent(SDL_Event& event); + + ~MainMenu(); +}; + +class PauseMenu : public BaseMenu { +private: + std::vector<std::string> options; + int selectedOption; + +public: + + void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); + + void handleEvent(SDL_Event& event); +}; + +} + +#endif // MENU_SYSTEM_HPP \ No newline at end of file -- GitLab From 4d64e0e8b94f4c7325856dc2e64665cecde98f3c Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 22 Jan 2025 20:17:09 +0100 Subject: [PATCH 04/29] Adding MainMenu to main --- src/main.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3afc605..c6e4c19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include "spritesheet.hpp" #include "window.hpp" #include <vector> +#include "ui/Menu.hpp" using namespace advanced_wars; @@ -12,14 +13,20 @@ int main() { Engine engine(window); - Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), + // render main menu + + MainMenu menu(0); + + engine.set_scene(menu); + + /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), std::vector<Unit>()); engine.set_scene(level); Spritesheet spritesheet("../test.png", engine); - engine.set_spritesheet(spritesheet); + engine.set_spritesheet(spritesheet); */ while (!engine.exited()) { engine.pump(); -- GitLab From 1adf2e054aec32715dbeecc08bc032c7ae98faf4 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 19:11:36 +0100 Subject: [PATCH 05/29] Adding ARCADECLASSIC.ttf font --- src/assets/ARCADECLASSIC.TTF | Bin 0 -> 17296 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/assets/ARCADECLASSIC.TTF diff --git a/src/assets/ARCADECLASSIC.TTF b/src/assets/ARCADECLASSIC.TTF new file mode 100644 index 0000000000000000000000000000000000000000..394a9f781cedaa283a11b3b8b43c9006f4e5bac7 GIT binary patch literal 17296 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 RaA4qKU|^_ZcnVr^0|2fRI_>}f literal 0 HcmV?d00001 -- GitLab From e27150d533cead2d730c8ed17eee5bbd3da48e23 Mon Sep 17 00:00:00 2001 From: David Hermann <david.hermann@informatik.hs-fulda.de> Date: Fri, 24 Jan 2025 19:30:43 +0100 Subject: [PATCH 06/29] Refactoring CMakeLists.txt --- CMakeLists.txt | 98 ++++++++++++++++++++++++++++------------ cmake/FindSDL2_ttf.cmake | 98 ++++++++++++++++++++++++++++++++++++++++ src/engine.cpp | 2 +- src/engine.hpp | 2 +- src/spritesheet.cpp | 2 +- src/spritesheet.hpp | 4 +- 6 files changed, 171 insertions(+), 35 deletions(-) create mode 100644 cmake/FindSDL2_ttf.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 17ad577..6bdba39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,16 +2,15 @@ cmake_minimum_required(VERSION 3.15) # Projektname und Sprache project(ADVANCED_WARS - VERSION 1.0.0 - DESCRIPTION "HSFD C++ Project" - LANGUAGES CXX + VERSION 1.0.0 + DESCRIPTION "HSFD C++ Project" + LANGUAGES CXX ) -file(GLOB ADVANCED_WARS_SOURCES - "${PROJECT_SOURCE_DIR}/src/*.cpp" - "${PROJECT_SOURCE_DIR}/src/*.hpp" - "${PROJECT_SOURCE_DIR}/src/ui/*.cpp" - "${PROJECT_SOURCE_DIR}/src/ui/*.hpp" +# Quellen sammeln +file(GLOB_RECURSE ADVANCED_WARS_SOURCES + "${PROJECT_SOURCE_DIR}/src/*.cpp" + "${PROJECT_SOURCE_DIR}/src/*.hpp" ) # C++ Standard festlegen @@ -26,30 +25,69 @@ else() add_compile_options(-Wall -Wextra -Wpedantic) endif() -# CMake +# Ressourcen kopieren +set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/assets) +set(OUTPUT_ASSETS_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets) +file(MAKE_DIRECTORY ${OUTPUT_ASSETS_DIR}) +file(GLOB FONT_FILES ${ASSETS_DIR}/*.ttf) + +# Executable erstellen +add_executable(advanced_wars ${ADVANCED_WARS_SOURCES}) + +foreach(FONT ${FONT_FILES}) + add_custom_command( + TARGET advanced_wars PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${FONT} ${OUTPUT_ASSETS_DIR} + COMMENT "Kopiere Font: ${FONT} nach ${OUTPUT_ASSETS_DIR}" + ) +endforeach() + set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH}) -# SDL2 -find_package(SDL2 REQUIRED) -find_package(SDL2_IMAGE REQUIRED) -find_package(SDL2_ttf REQUIRED) -find_package(HDF5 REQUIRED COMPONENTS CXX) +# Plattform-spezifische Konfiguration +if(APPLE) + # SDL2 Frameworks für macOS + set(SDL2_PATH "/Library/Frameworks") + set(CMAKE_OSX_ARCHITECTURES "arm64") + target_include_directories( + advanced_wars PRIVATE + ${SDL2_PATH}/SDL2.framework/Headers + ${SDL2_PATH}/SDL2_image.framework/Headers + ${SDL2_PATH}/SDL2_ttf.framework/Headers + ) -include_directories(/usr/include/SDL2) + target_link_libraries( + advanced_wars PRIVATE + ${SDL2_PATH}/SDL2.framework/SDL2 + ${SDL2_PATH}/SDL2_image.framework/SDL2_image + ${SDL2_PATH}/SDL2_ttf.framework/SDL2_ttf + ) -include_directories(${SDL2_INCLUDE_DIR}) -include_directories(${SDL2_IMG_INCLUDE_DIR}) -include_directories(${SDL2_TTF_INCLUDE_DIR}) -include_directories(${HDF5_INCLUDE_DIRS}) + # Debug-Ausgaben + message(STATUS "Include Dir (SDL2): ${SDL2_PATH}/SDL2.framework/Headers") + message(STATUS "Include Dir (SDL2_image): ${SDL2_PATH}/SDL2_image.framework/Headers") + message(STATUS "Include Dir (SDL2_ttf): ${SDL2_PATH}/SDL2_ttf.framework/Headers") +else() + find_package(SDL2 REQUIRED) + find_package(SDL2_IMAGE REQUIRED) + find_package(SDL2_ttf REQUIRED) + find_package(HDF5 REQUIRED COMPONENTS CXX) + + include_directories(/usr/include/SDL2) + + include_directories(${SDL2_INCLUDE_DIR}) + include_directories(${SDL2_IMG_INCLUDE_DIR}) + include_directories(${SDL2_TTF_INCLUDE_DIR}) + include_directories(${HDF5_INCLUDE_DIRS}) + + target_link_libraries(advanced_wars + ${HDF5_LIBRARIES} + -lSDL2 + -lSDL2_image + -lSDL2_ttf + m + ) + + +endif() -# Executable erstellen -add_executable(advanced_wars src/main.cpp ${ADVANCED_WARS_SOURCES}) -target_link_libraries(advanced_wars - ${SDL2_LIBRARY} - ${SDL2_IMG_LIBRARY} - ${SDL2_TTF_LIBRARIY} - ${HDF5_LIBRARIES} - -lSDL2 - -lSDL2_ttf - m -) \ No newline at end of file diff --git a/cmake/FindSDL2_ttf.cmake b/cmake/FindSDL2_ttf.cmake new file mode 100644 index 0000000..56719ce --- /dev/null +++ b/cmake/FindSDL2_ttf.cmake @@ -0,0 +1,98 @@ +# Locate SDL_ttf library +# +# This module defines: +# +# :: +# +# SDL2_TTF_LIBRARIES, the name of the library to link against +# SDL2_TTF_INCLUDE_DIRS, where to find the headers +# SDL2_TTF_FOUND, if false, do not try to link against +# SDL2_TTF_VERSION_STRING - human-readable string containing the version of SDL_ttf +# +# +# +# For backward compatibility the following variables are also set: +# +# :: +# +# SDLTTF_LIBRARY (same value as SDL2_TTF_LIBRARIES) +# SDLTTF_INCLUDE_DIR (same value as SDL2_TTF_INCLUDE_DIRS) +# SDLTTF_FOUND (same value as SDL2_TTF_FOUND) +# +# +# +# $SDLDIR is an environment variable that would correspond to the +# ./configure --prefix=$SDLDIR used in building SDL. +# +# Created by Eric Wing. This was influenced by the FindSDL.cmake +# module, but with modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). + +#============================================================================= +# Copyright 2005-2009 Kitware, Inc. +# Copyright 2012 Benjamin Eikel +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h + HINTS + ENV SDL2TTFDIR + ENV SDL2DIR + PATH_SUFFIXES SDL2 + # path suffixes to search inside ENV{SDLDIR} + include/SDL2 include + PATHS ${SDL2_TTF_PATH} + ) + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VC_LIB_PATH_SUFFIX lib/x64) +else () + set(VC_LIB_PATH_SUFFIX lib/x86) +endif () + +find_library(SDL2_TTF_LIBRARY + NAMES SDL2_ttf + HINTS + ENV SDL2TTFDIR + ENV SDL2DIR + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} + PATHS ${SDL2_TTF_PATH} + ) + +if (SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h") + file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}") + set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH}) + unset(SDL2_TTF_VERSION_MAJOR_LINE) + unset(SDL2_TTF_VERSION_MINOR_LINE) + unset(SDL2_TTF_VERSION_PATCH_LINE) + unset(SDL2_TTF_VERSION_MAJOR) + unset(SDL2_TTF_VERSION_MINOR) + unset(SDL2_TTF_VERSION_PATCH) +endif () + +set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY}) +set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf + REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS + VERSION_VAR SDL2_TTF_VERSION_STRING) + +# for backward compatibility +set(SDLTTF_LIBRARY ${SDL2_TTF_LIBRARIES}) +set(SDLTTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS}) +set(SDLTTF_FOUND ${SDL2_TTF_FOUND}) \ No newline at end of file diff --git a/src/engine.cpp b/src/engine.cpp index ce0ed91..09b2d27 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,5 +1,5 @@ #include "engine.hpp" -#include "SDL_render.h" +#include <SDL_render.h> #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" diff --git a/src/engine.hpp b/src/engine.hpp index db2abeb..ddfc3d0 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -1,6 +1,6 @@ #pragma once -#include "SDL_render.h" +#include <SDL_render.h> #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" diff --git a/src/spritesheet.cpp b/src/spritesheet.cpp index 75125b2..421e8ad 100644 --- a/src/spritesheet.cpp +++ b/src/spritesheet.cpp @@ -1,5 +1,5 @@ #include "spritesheet.hpp" -#include "SDL_render.h" +#include <SDL_render.h> #include "SDL_surface.h" #include "engine.hpp" diff --git a/src/spritesheet.hpp b/src/spritesheet.hpp index a96889d..7f7a4e1 100644 --- a/src/spritesheet.hpp +++ b/src/spritesheet.hpp @@ -1,7 +1,7 @@ #pragma once -#include "SDL_render.h" -#include <SDL2/SDL.h> +#include <SDL_render.h> +#include <SDL.h> #include <string> #include <vector> -- GitLab From c19a14b22f75973d76533a2958555c391aec8563 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 19:42:51 +0100 Subject: [PATCH 07/29] Revert of commit 6e36612d6123c68fdd6fc9eea6f53b3922f30123 Removing SDL2/ from include paths --- src/engine.cpp | 2 +- src/engine.hpp | 2 +- src/level.cpp | 2 +- src/level.hpp | 2 +- src/scene.hpp | 2 +- src/ui/Menu.cpp | 4 ++-- src/ui/Menu.hpp | 2 +- src/window.hpp | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 09b2d27..984b332 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -3,7 +3,7 @@ #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" -#include <SDL2/SDL.h> +#include <SDL.h> #include <SDL_image.h> #include <stdexcept> #include <vector> diff --git a/src/engine.hpp b/src/engine.hpp index ddfc3d0..967b2de 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -4,7 +4,7 @@ #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" -#include <SDL2/SDL.h> +#include <SDL.h> #include <optional> #include <vector> diff --git a/src/level.cpp b/src/level.cpp index b744f99..0504c41 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -3,7 +3,7 @@ #include "unit.hpp" #include <string> #include <iostream> -#include <SDL2/SDL.h> +#include <SDL.h> namespace advanced_wars { diff --git a/src/level.hpp b/src/level.hpp index fdb8fa5..367615b 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -4,7 +4,7 @@ #include "scene.hpp" #include "tile.hpp" #include "unit.hpp" -#include <SDL2/SDL.h> +#include <SDL.h> #include <string> #include <vector> diff --git a/src/scene.hpp b/src/scene.hpp index bbc0861..9730ff5 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -1,6 +1,6 @@ #pragma once -#include <SDL2/SDL.h> +#include <SDL.h> #include <vector> namespace advanced_wars { diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 97dd9da..2a8908a 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -1,5 +1,5 @@ -#include <SDL2/SDL.h> -#include <SDL2/SDL_ttf.h> +#include <SDL.h> +#include <SDL_ttf.h> #include <iostream> #include <vector> #include <string> diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp index 350c25a..3cc0bd7 100644 --- a/src/ui/Menu.hpp +++ b/src/ui/Menu.hpp @@ -1,7 +1,7 @@ #ifndef MENU_SYSTEM_HPP #define MENU_SYSTEM_HPP -#include <SDL2/SDL.h> +#include <SDL.h> #include <iostream> #include <vector> #include <string> diff --git a/src/window.hpp b/src/window.hpp index 3b6adc3..9cd664d 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -1,6 +1,6 @@ #pragma once -#include <SDL2/SDL.h> +#include <SDL.h> #include <string> namespace advanced_wars { -- GitLab From 4fb1315d80e98299acc727734d4864ed720bfc6a Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 19:44:17 +0100 Subject: [PATCH 08/29] Fix: Removing SDL Event from vector when handling it --- src/ui/Menu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 2a8908a..3317f00 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -22,9 +22,9 @@ namespace advanced_wars void MainMenu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { if (events.size() > 0) { - for (auto event: events) { - handleEvent(event); - } + SDL_Event event = events.back(); + events.pop_back(); + handleEvent(event); } -- GitLab From c6a02d06d1aff2b5f2924d4f50048b4ccea1170f Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 20:14:18 +0100 Subject: [PATCH 09/29] Fix: Changing .ttf to .TTF in cmakefiles Fix: Removing local path from Menu.cpp --- CMakeLists.txt | 2 +- src/ui/Menu.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bdba39..344704d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ endif() set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/assets) set(OUTPUT_ASSETS_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets) file(MAKE_DIRECTORY ${OUTPUT_ASSETS_DIR}) -file(GLOB FONT_FILES ${ASSETS_DIR}/*.ttf) +file(GLOB FONT_FILES ${ASSETS_DIR}/*.TTF) # Executable erstellen add_executable(advanced_wars ${ADVANCED_WARS_SOURCES}) diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 3317f00..9b59495 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -39,9 +39,12 @@ namespace advanced_wars } // Load a font - TTF_Font* font = TTF_OpenFont("/usr/share/fonts/ARCADECLASSIC.TTF", 24); + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/ARCADECLASSIC.TTF"; + std::string fullPath = basePath + relativePath; + TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 24); if (!font) { - std::cerr << "Failed to load font: " << TTF_GetError() << std::endl; + std::cerr << "Failed to load font: " << fullPath << TTF_GetError() << std::endl; return; } -- GitLab From b904569e81d371e56651c0e52ed862911f9345e4 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 20:17:37 +0100 Subject: [PATCH 10/29] Adding possibility to load images from assets into build dir --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 344704d..a950f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/assets) set(OUTPUT_ASSETS_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets) file(MAKE_DIRECTORY ${OUTPUT_ASSETS_DIR}) file(GLOB FONT_FILES ${ASSETS_DIR}/*.TTF) +file(GLOB IMAGE_FILES ${ASSETS_DIR}/*.png) # Executable erstellen add_executable(advanced_wars ${ADVANCED_WARS_SOURCES}) @@ -42,6 +43,14 @@ foreach(FONT ${FONT_FILES}) ) endforeach() +foreach(IMAGE ${IMAGE_FILES}) + add_custom_command( + TARGET advanced_wars PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${IMAGE} ${OUTPUT_ASSETS_DIR} + COMMENT "Kopiere Image: ${IMAGE} nach ${OUTPUT_ASSETS_DIR}" + ) +endforeach() + set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH}) # Plattform-spezifische Konfiguration -- GitLab From f42e8ccf0ed8355f99df77a900ddee3dc72de9de Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 20:17:51 +0100 Subject: [PATCH 11/29] Adding template background image --- src/assets/main_background.png | Bin 0 -> 2633 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/assets/main_background.png diff --git a/src/assets/main_background.png b/src/assets/main_background.png new file mode 100644 index 0000000000000000000000000000000000000000..5958dc0d0a7144697dece04db5dc2a1646088207 GIT binary patch literal 2633 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 literal 0 HcmV?d00001 -- GitLab From eb5b3fd16aaaf171e027684646b8741c0a9c36cd Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 20:18:25 +0100 Subject: [PATCH 12/29] Closing #10 Implementing possibility to render background in main menu --- src/main.cpp | 6 +++++- src/ui/Menu.cpp | 42 ++++++++++++++++++++++++++++++++++++------ src/ui/Menu.hpp | 3 +++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c6e4c19..23e60e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,8 +17,12 @@ int main() { MainMenu menu(0); - engine.set_scene(menu); + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/main_background.png"; + std::string fullPath = basePath + relativePath; + menu.loadBackground(engine.renderer(), fullPath.c_str()); + engine.set_scene(menu); /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), std::vector<Unit>()); diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 9b59495..435ab1e 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -3,6 +3,7 @@ #include <iostream> #include <vector> #include <string> +#include <SDL_image.h> #include "Menu.hpp" namespace advanced_wars @@ -10,13 +11,19 @@ namespace advanced_wars MainMenu::MainMenu(int selectedOption) : selectedOption(selectedOption), - options({"Start Game", "Options", "Exit"}) + options({"Start Game", "Options", "Exit"}), + backgroundTexture(nullptr) { - + if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { + std::cerr << "Failed to initialize SDL_image: " << IMG_GetError() << std::endl; + } } MainMenu::~MainMenu() { - + if (backgroundTexture) { + SDL_DestroyTexture(backgroundTexture); + } + IMG_Quit(); }; void MainMenu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { @@ -28,9 +35,14 @@ namespace advanced_wars } - // Clear the screen with a background color - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); + if (backgroundTexture) { + SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr); + } else { + std::cout << "No background texture loaded" << std::endl; + // Falls kein Hintergrundbild vorhanden ist, cleare mit Schwarz + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + } // Initialize SDL_TTF if not already done if (TTF_Init() == -1) { @@ -101,4 +113,22 @@ namespace advanced_wars } } + void MainMenu::loadBackground(SDL_Renderer *renderer, const std::string& imagePath) { + // Lade das Hintergrundbild + SDL_Surface* backgroundSurface = IMG_Load(imagePath.c_str()); + if (!backgroundSurface) { + std::cerr << "Failed to load background image: " << IMG_GetError() << std::endl; + return; + } + + // Erstelle eine Textur aus der Oberfläche und speichere sie als Klassenmitglied + backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface); + SDL_FreeSurface(backgroundSurface); // Oberfläche freigeben, da sie nicht mehr benötigt wird + + if (!backgroundTexture) { + std::cerr << "Failed to create background texture: " << SDL_GetError() << std::endl; + } +} + + } diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp index 3cc0bd7..7c0050a 100644 --- a/src/ui/Menu.hpp +++ b/src/ui/Menu.hpp @@ -20,6 +20,7 @@ class MainMenu : public Scene { private: size_t selectedOption; std::array<std::string, 3> options; + SDL_Texture* backgroundTexture; public: @@ -29,6 +30,8 @@ public: void handleEvent(SDL_Event& event); + void loadBackground(SDL_Renderer *renderer, const std::string& imagePath); + ~MainMenu(); }; -- GitLab From 88ba577adb62793651cc15278b660cef81bb0e63 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Fri, 24 Jan 2025 20:26:56 +0100 Subject: [PATCH 13/29] Refactoring: Removing comments from menu.cpp Refactoring: Changing the layout of the main menu and adding the game title --- src/ui/Menu.cpp | 114 ++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 435ab1e..c96a2e9 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -28,76 +28,74 @@ namespace advanced_wars void MainMenu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { - if (events.size() > 0) { - SDL_Event event = events.back(); - events.pop_back(); - handleEvent(event); - } - - - if (backgroundTexture) { - SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr); - } else { - std::cout << "No background texture loaded" << std::endl; - // Falls kein Hintergrundbild vorhanden ist, cleare mit Schwarz - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - } - - // Initialize SDL_TTF if not already done - if (TTF_Init() == -1) { - std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; - return; - } + if (events.size() > 0) { + SDL_Event event = events.back(); + events.pop_back(); + handleEvent(event); + } - // Load a font - std::string basePath = SDL_GetBasePath(); - std::string relativePath = "assets/ARCADECLASSIC.TTF"; - std::string fullPath = basePath + relativePath; - TTF_Font* font = TTF_OpenFont(fullPath.c_str(), 24); - if (!font) { - std::cerr << "Failed to load font: " << fullPath << TTF_GetError() << std::endl; - return; - } + if (backgroundTexture) { + SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr); + } else { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + } - // Colors for text rendering - SDL_Color white = {255, 255, 255, 255}; - SDL_Color yellow = {255, 255, 0, 255}; + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; + return; + } - // Render each menu option - for (size_t i = 0; i < options.size(); ++i) { - SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white); - if (!textSurface) { - std::cerr << "Failed to create text surface: " << TTF_GetError() << std::endl; - continue; - } + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/ARCADECLASSIC.TTF"; + std::string fullPath = basePath + relativePath; + TTF_Font* titleFont = TTF_OpenFont(fullPath.c_str(), 48); + if (!titleFont) { + std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << std::endl; + return; + } - SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); - if (!textTexture) { - std::cerr << "Failed to create text texture: " << SDL_GetError() << std::endl; - SDL_FreeSurface(textSurface); - continue; - } + TTF_Font* menuFont = TTF_OpenFont(fullPath.c_str(), 24); + if (!menuFont) { + TTF_CloseFont(titleFont); + std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << std::endl; + return; + } - // Define text position and size - SDL_Rect textRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h}; + SDL_Color white = {255, 255, 255, 255}; + SDL_Color yellow = {255, 255, 0, 255}; - // Render the texture - SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + SDL_Surface* titleSurface = TTF_RenderText_Solid(titleFont, "Advanced Wars", white); + if (titleSurface) { + SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(renderer, titleSurface); + SDL_Rect titleRect = {static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; + SDL_RenderCopy(renderer, titleTexture, nullptr, &titleRect); + SDL_DestroyTexture(titleTexture); + SDL_FreeSurface(titleSurface); + } - // Clean up resources - SDL_DestroyTexture(textTexture); - SDL_FreeSurface(textSurface); + for (size_t i = 0; i < options.size(); ++i) { + SDL_Surface* textSurface = TTF_RenderText_Solid(menuFont, options[i].c_str(), (i == selectedOption) ? yellow : white); + if (!textSurface) { + continue; } - // Close the font and quit TTF - TTF_CloseFont(font); - TTF_Quit(); + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + SDL_Rect textRect = {static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), textSurface->w, textSurface->h}; + SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); - // Present the rendered content - SDL_RenderPresent(renderer); + SDL_DestroyTexture(textTexture); + SDL_FreeSurface(textSurface); } + TTF_CloseFont(titleFont); + TTF_CloseFont(menuFont); + TTF_Quit(); + + SDL_RenderPresent(renderer); +} + + void MainMenu::handleEvent(SDL_Event& event) { if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_DOWN) { -- GitLab From 2636f4614bf8076bf8181a5fccef2fbe4fa924bb Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Sat, 25 Jan 2025 18:05:05 +0100 Subject: [PATCH 14/29] Refactoring: Renaming MainMenu to Menu Removing BaseMenu and PauseMenu --- src/main.cpp | 2 +- src/ui/Menu.cpp | 10 +++++----- src/ui/Menu.hpp | 24 +++--------------------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 23e60e9..3d7a803 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ int main() { // render main menu - MainMenu menu(0); + Menu menu(0); std::string basePath = SDL_GetBasePath(); std::string relativePath = "assets/main_background.png"; diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index c96a2e9..b2c17dd 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -9,7 +9,7 @@ namespace advanced_wars { - MainMenu::MainMenu(int selectedOption) + Menu::Menu(int selectedOption) : selectedOption(selectedOption), options({"Start Game", "Options", "Exit"}), backgroundTexture(nullptr) @@ -19,14 +19,14 @@ namespace advanced_wars } } - MainMenu::~MainMenu() { + Menu::~Menu() { if (backgroundTexture) { SDL_DestroyTexture(backgroundTexture); } IMG_Quit(); }; - void MainMenu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { + void Menu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { if (events.size() > 0) { SDL_Event event = events.back(); @@ -96,7 +96,7 @@ namespace advanced_wars } - void MainMenu::handleEvent(SDL_Event& event) { + void Menu::handleEvent(SDL_Event& event) { if (event.type == SDL_KEYDOWN) { if (event.key.keysym.sym == SDLK_DOWN) { selectedOption = (selectedOption + 1) % options.size(); @@ -111,7 +111,7 @@ namespace advanced_wars } } - void MainMenu::loadBackground(SDL_Renderer *renderer, const std::string& imagePath) { + void Menu::loadBackground(SDL_Renderer *renderer, const std::string& imagePath) { // Lade das Hintergrundbild SDL_Surface* backgroundSurface = IMG_Load(imagePath.c_str()); if (!backgroundSurface) { diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp index 7c0050a..7d41e07 100644 --- a/src/ui/Menu.hpp +++ b/src/ui/Menu.hpp @@ -10,13 +10,7 @@ namespace advanced_wars { -class BaseMenu : public Scene { -public: - virtual void handleEvent(SDL_Event& event); - virtual ~BaseMenu(); -}; - -class MainMenu : public Scene { +class Menu : public Scene { private: size_t selectedOption; std::array<std::string, 3> options; @@ -24,7 +18,7 @@ private: public: - MainMenu(int selectedOption); + Menu(int selectedOption); void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); @@ -32,19 +26,7 @@ public: void loadBackground(SDL_Renderer *renderer, const std::string& imagePath); - ~MainMenu(); -}; - -class PauseMenu : public BaseMenu { -private: - std::vector<std::string> options; - int selectedOption; - -public: - - void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); - - void handleEvent(SDL_Event& event); + ~Menu(); }; } -- GitLab From 2b88b2c078cfd45e2a0fbaaf5c02f0137c97222d Mon Sep 17 00:00:00 2001 From: fdai7375 <david.maul@informatik.hs-fulda.de> Date: Sat, 25 Jan 2025 23:48:55 +0100 Subject: [PATCH 15/29] add scene stack --- src/engine.cpp | 32 +++++-- src/engine.hpp | 21 ++++- src/level.cpp | 37 ++++---- src/level.hpp | 2 +- src/main.cpp | 15 ++- src/scene.hpp | 9 +- src/ui/Menu.cpp | 238 +++++++++++++++++++++++++----------------------- src/ui/Menu.hpp | 27 +++--- 8 files changed, 212 insertions(+), 169 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 984b332..eb7baba 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,12 +1,15 @@ #include "engine.hpp" -#include <SDL_render.h> +#include "SDL_events.h" #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" #include <SDL.h> #include <SDL_image.h> +#include <SDL_render.h> +#include <deque> +#include <memory> +#include <optional> #include <stdexcept> -#include <vector> namespace advanced_wars { @@ -34,7 +37,22 @@ Engine::Engine(Window &window) : window(window), quit(false) { } } -void Engine::set_scene(Scene &scene) { this->scene = &scene; } +std::deque<SDL_Event> &Engine::events() { return this->_events; } + +void Engine::push_scene(std::shared_ptr<Scene> scene) { + this->scenes.push_back(scene); +} + +std::optional<std::shared_ptr<Scene>> Engine::pop_scene() { + if (!this->scenes.empty()) { + return std::nullopt; + } else { + std::shared_ptr<Scene> tmp = scenes.at(scenes.size() - 1); + this->scenes.pop_back(); + + return std::optional<std::shared_ptr<Scene>>(tmp); + } +} void Engine::set_spritesheet(Spritesheet spritesheet) { this->spritesheet = spritesheet; @@ -46,11 +64,13 @@ void Engine::pump() { if (e.type == SDL_QUIT) { this->quit = true; } else { - this->events.push_back(e); + this->_events.push_back(e); } } } +void Engine::exit() { this->quit = true; } + bool Engine::exited() { return this->quit; } void Engine::render() { @@ -59,11 +79,11 @@ void Engine::render() { std::string(SDL_GetError())); } - if (!scene.has_value()) { + if (scenes.empty()) { return; } - this->scene.value()->render(this->sdl_renderer, this->events); + this->scenes.at(scenes.size() - 1)->render(this); SDL_RenderPresent(this->sdl_renderer); } diff --git a/src/engine.hpp b/src/engine.hpp index 967b2de..b7ae83d 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -1,15 +1,20 @@ #pragma once -#include <SDL_render.h> +#include "SDL_events.h" #include "scene.hpp" #include "spritesheet.hpp" #include "window.hpp" #include <SDL.h> +#include <SDL_render.h> +#include <deque> +#include <memory> #include <optional> -#include <vector> namespace advanced_wars { +// Forward declaration +class Scene; + /** * @brief The main window of the game */ @@ -22,9 +27,15 @@ public: bool exited(); + void exit(); + void pump(); - void set_scene(Scene &scene); + void push_scene(std::shared_ptr<Scene> scene); + + std::optional<std::shared_ptr<Scene>> pop_scene(); + + std::deque<SDL_Event> &events(); void set_spritesheet(Spritesheet spritesheet); @@ -37,9 +48,9 @@ public: private: Window &window; SDL_Renderer *sdl_renderer; - std::optional<Scene *> scene; + std::vector<std::shared_ptr<Scene>> scenes; std::optional<Spritesheet> spritesheet; - std::vector<SDL_Event> events; + std::deque<SDL_Event> _events; bool quit; }; diff --git a/src/level.cpp b/src/level.cpp index 0504c41..9385dbe 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -1,26 +1,27 @@ #include "level.hpp" #include "building.hpp" #include "unit.hpp" -#include <string> -#include <iostream> #include <SDL.h> +#include <iostream> +#include <string> -namespace advanced_wars -{ - - Level::Level(std::string name, int width, int height, std::vector<Tile> tiles, std::vector<Building> buildings, std::vector<Unit> units): name(name), width(width), height(height), buildings(buildings), units(units) {}; - - void Level::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { - // Iterate over all events - while (!events.empty()) { - events.erase(events.begin()); - } +namespace advanced_wars { - // Set background color for renderer - if(SDL_SetRenderDrawColor(renderer, 255, 0, 0, 0)) - { - std::cout << "Could not set render draw color: " << SDL_GetError() << std::endl; - } - } +Level::Level(std::string name, int width, int height, std::vector<Tile> tiles, + std::vector<Building> buildings, std::vector<Unit> units) + : name(name), width(width), height(height), buildings(buildings), + units(units) {}; +void Level::render(Engine *engine) { + // Iterate over all events + while (!engine->events().empty()) { + engine->events().pop_front(); + } + // Set background color for renderer + if (SDL_SetRenderDrawColor(engine->renderer(), 255, 0, 0, 0)) { + std::cout << "Could not set render draw color: " << SDL_GetError() + << std::endl; + } } + +} // namespace advanced_wars diff --git a/src/level.hpp b/src/level.hpp index 367615b..2f81c60 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -18,7 +18,7 @@ public: Level(std::string name, int width, int height, std::vector<Tile> tiles, std::vector<Building> buildings, std::vector<Unit> units); - void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); + void render(Engine *events); private: std::string name; diff --git a/src/main.cpp b/src/main.cpp index 3d7a803..c9b04e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,8 @@ #include "engine.hpp" -#include "level.hpp" #include "spritesheet.hpp" -#include "window.hpp" -#include <vector> #include "ui/Menu.hpp" +#include "window.hpp" +#include <memory> using namespace advanced_wars; @@ -15,16 +14,16 @@ int main() { // render main menu - Menu menu(0); + std::shared_ptr<Menu> menu = std::make_shared<Menu>(0); std::string basePath = SDL_GetBasePath(); std::string relativePath = "assets/main_background.png"; std::string fullPath = basePath + relativePath; - menu.loadBackground(engine.renderer(), fullPath.c_str()); + menu->loadBackground(engine.renderer(), fullPath.c_str()); - engine.set_scene(menu); - /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), - std::vector<Unit>()); + engine.push_scene(menu); + /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), + std::vector<Building>(), std::vector<Unit>()); engine.set_scene(level); diff --git a/src/scene.hpp b/src/scene.hpp index 9730ff5..5d5d1c1 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -1,13 +1,16 @@ #pragma once +#include "engine.hpp" #include <SDL.h> -#include <vector> namespace advanced_wars { +// Forward declaration +class Engine; + class Scene { public: - virtual void render(SDL_Renderer *renderer, - std::vector<SDL_Event> &events) = 0; + virtual void render(Engine *engine) = 0; }; + } // namespace advanced_wars diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index b2c17dd..1a95672 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -1,132 +1,142 @@ +#include "Menu.hpp" #include <SDL.h> +#include <SDL_image.h> #include <SDL_ttf.h> #include <iostream> -#include <vector> #include <string> -#include <SDL_image.h> -#include "Menu.hpp" - -namespace advanced_wars -{ - - Menu::Menu(int selectedOption) - : selectedOption(selectedOption), - options({"Start Game", "Options", "Exit"}), - backgroundTexture(nullptr) - { - if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { - std::cerr << "Failed to initialize SDL_image: " << IMG_GetError() << std::endl; - } - } - - Menu::~Menu() { - if (backgroundTexture) { - SDL_DestroyTexture(backgroundTexture); - } - IMG_Quit(); - }; - - void Menu::render(SDL_Renderer *renderer, std::vector<SDL_Event> &events) { - - if (events.size() > 0) { - SDL_Event event = events.back(); - events.pop_back(); - handleEvent(event); - } - - if (backgroundTexture) { - SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr); - } else { - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - } - - if (TTF_Init() == -1) { - std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; - return; - } - - std::string basePath = SDL_GetBasePath(); - std::string relativePath = "assets/ARCADECLASSIC.TTF"; - std::string fullPath = basePath + relativePath; - TTF_Font* titleFont = TTF_OpenFont(fullPath.c_str(), 48); - if (!titleFont) { - std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << std::endl; - return; - } - TTF_Font* menuFont = TTF_OpenFont(fullPath.c_str(), 24); - if (!menuFont) { - TTF_CloseFont(titleFont); - std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << std::endl; - return; - } +namespace advanced_wars { - SDL_Color white = {255, 255, 255, 255}; - SDL_Color yellow = {255, 255, 0, 255}; +Menu::Menu(int selectedOption) + : selectedOption(selectedOption), + options({"Start Game", "Options", "Exit"}), backgroundTexture(nullptr) { + if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { + std::cerr << "Failed to initialize SDL_image: " << IMG_GetError() + << std::endl; + } +} - SDL_Surface* titleSurface = TTF_RenderText_Solid(titleFont, "Advanced Wars", white); - if (titleSurface) { - SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(renderer, titleSurface); - SDL_Rect titleRect = {static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; - SDL_RenderCopy(renderer, titleTexture, nullptr, &titleRect); - SDL_DestroyTexture(titleTexture); - SDL_FreeSurface(titleSurface); +Menu::~Menu() { + if (backgroundTexture) { + SDL_DestroyTexture(backgroundTexture); + } + IMG_Quit(); +}; + +void Menu::render(Engine *engine) { + + // Iterate over all events + while (!engine->events().empty()) { + SDL_Event event = engine->events().at(0); + engine->events().pop_front(); + handleEvent(engine, event); + } + + if (backgroundTexture) { + SDL_RenderCopy(engine->renderer(), backgroundTexture, nullptr, nullptr); + } else { + SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255); + SDL_RenderClear(engine->renderer()); + } + + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; + return; + } + + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/ARCADECLASSIC.TTF"; + std::string fullPath = basePath + relativePath; + TTF_Font *titleFont = TTF_OpenFont(fullPath.c_str(), 48); + if (!titleFont) { + std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() + << std::endl; + return; + } + + TTF_Font *menuFont = TTF_OpenFont(fullPath.c_str(), 24); + if (!menuFont) { + TTF_CloseFont(titleFont); + std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() + << std::endl; + return; + } + + SDL_Color white = {255, 255, 255, 255}; + SDL_Color yellow = {255, 255, 0, 255}; + + SDL_Surface *titleSurface = + TTF_RenderText_Solid(titleFont, "Advanced Wars", white); + if (titleSurface) { + SDL_Texture *titleTexture = + SDL_CreateTextureFromSurface(engine->renderer(), titleSurface); + SDL_Rect titleRect = {static_cast<int>((800 - titleSurface->w) / 2), 50, + titleSurface->w, titleSurface->h}; + SDL_RenderCopy(engine->renderer(), titleTexture, nullptr, &titleRect); + SDL_DestroyTexture(titleTexture); + SDL_FreeSurface(titleSurface); + } + + for (size_t i = 0; i < options.size(); ++i) { + SDL_Surface *textSurface = TTF_RenderText_Solid( + menuFont, options[i].c_str(), (i == selectedOption) ? yellow : white); + if (!textSurface) { + continue; } - for (size_t i = 0; i < options.size(); ++i) { - SDL_Surface* textSurface = TTF_RenderText_Solid(menuFont, options[i].c_str(), (i == selectedOption) ? yellow : white); - if (!textSurface) { - continue; - } + SDL_Texture *textTexture = + SDL_CreateTextureFromSurface(engine->renderer(), textSurface); + SDL_Rect textRect = {static_cast<int>((800 - textSurface->w) / 2), + static_cast<int>(150 + i * 50), textSurface->w, + textSurface->h}; + SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect); - SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); - SDL_Rect textRect = {static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), textSurface->w, textSurface->h}; - SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + SDL_DestroyTexture(textTexture); + SDL_FreeSurface(textSurface); + } - SDL_DestroyTexture(textTexture); - SDL_FreeSurface(textSurface); - } - - TTF_CloseFont(titleFont); - TTF_CloseFont(menuFont); - TTF_Quit(); + TTF_CloseFont(titleFont); + TTF_CloseFont(menuFont); + TTF_Quit(); - SDL_RenderPresent(renderer); + SDL_RenderPresent(engine->renderer()); } - - void Menu::handleEvent(SDL_Event& event) { - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_DOWN) { - selectedOption = (selectedOption + 1) % options.size(); - } else if (event.key.keysym.sym == SDLK_UP) { - selectedOption = (selectedOption - 1 + options.size()) % options.size(); - } else if (event.key.keysym.sym == SDLK_RETURN) { - if (options[selectedOption] == "Exit") { - std::cout << "Exiting game..." << std::endl; - // Exit logic here - } - } - } - } - - void Menu::loadBackground(SDL_Renderer *renderer, const std::string& imagePath) { - // Lade das Hintergrundbild - SDL_Surface* backgroundSurface = IMG_Load(imagePath.c_str()); - if (!backgroundSurface) { - std::cerr << "Failed to load background image: " << IMG_GetError() << std::endl; - return; - } - - // Erstelle eine Textur aus der Oberfläche und speichere sie als Klassenmitglied - backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface); - SDL_FreeSurface(backgroundSurface); // Oberfläche freigeben, da sie nicht mehr benötigt wird - - if (!backgroundTexture) { - std::cerr << "Failed to create background texture: " << SDL_GetError() << std::endl; +void Menu::handleEvent(Engine *engine, SDL_Event &event) { + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_DOWN) { + selectedOption = (selectedOption + 1) % options.size(); + } else if (event.key.keysym.sym == SDLK_UP) { + selectedOption = (selectedOption - 1 + options.size()) % options.size(); + } else if (event.key.keysym.sym == SDLK_RETURN) { + if (options[selectedOption] == "Exit") { + std::cout << "Exiting game..." << std::endl; + engine->exit(); + } } + } } - +void Menu::loadBackground(SDL_Renderer *renderer, + const std::string &imagePath) { + // Lade das Hintergrundbild + SDL_Surface *backgroundSurface = IMG_Load(imagePath.c_str()); + if (!backgroundSurface) { + std::cerr << "Failed to load background image: " << IMG_GetError() + << std::endl; + return; + } + + // Erstelle eine Textur aus der Oberfläche und speichere sie als + // Klassenmitglied + backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface); + SDL_FreeSurface(backgroundSurface); // Oberfläche freigeben, da sie nicht mehr + // benötigt wird + + if (!backgroundTexture) { + std::cerr << "Failed to create background texture: " << SDL_GetError() + << std::endl; + } } + +} // namespace advanced_wars diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp index 7d41e07..5e5cd0e 100644 --- a/src/ui/Menu.hpp +++ b/src/ui/Menu.hpp @@ -1,34 +1,33 @@ #ifndef MENU_SYSTEM_HPP #define MENU_SYSTEM_HPP +#include "../scene.hpp" #include <SDL.h> +#include <array> #include <iostream> -#include <vector> #include <string> -#include <array> -#include "../scene.hpp" +#include <vector> namespace advanced_wars { class Menu : public Scene { private: - size_t selectedOption; - std::array<std::string, 3> options; - SDL_Texture* backgroundTexture; - -public: + size_t selectedOption; + std::array<std::string, 3> options; + SDL_Texture *backgroundTexture; - Menu(int selectedOption); +public: + Menu(int selectedOption); - void render(SDL_Renderer *renderer, std::vector<SDL_Event> &events); + void render(Engine *engine); - void handleEvent(SDL_Event& event); + void handleEvent(Engine *engine, SDL_Event &event); - void loadBackground(SDL_Renderer *renderer, const std::string& imagePath); + void loadBackground(SDL_Renderer *renderer, const std::string &imagePath); - ~Menu(); + ~Menu(); }; -} +} // namespace advanced_wars #endif // MENU_SYSTEM_HPP \ No newline at end of file -- GitLab From 6d6b4447e3a169295b2e4121270f0ff05e98a6a7 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Sun, 26 Jan 2025 13:56:41 +0100 Subject: [PATCH 16/29] Adding keyword override to render method --- src/ui/Menu.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/Menu.hpp b/src/ui/Menu.hpp index 5e5cd0e..df0419d 100644 --- a/src/ui/Menu.hpp +++ b/src/ui/Menu.hpp @@ -19,7 +19,7 @@ private: public: Menu(int selectedOption); - void render(Engine *engine); + void render(Engine *engine) override; void handleEvent(Engine *engine, SDL_Event &event); -- GitLab From 70647e7194ed1c326d0b384e5add05022cd3da17 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Sun, 26 Jan 2025 13:57:03 +0100 Subject: [PATCH 17/29] Adding boilerplate code to test if the scene switch to start a level works --- src/ui/Menu.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 1a95672..4f37177 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -4,6 +4,11 @@ #include <SDL_ttf.h> #include <iostream> #include <string> +#include "../level.hpp" +#include "../building.hpp" +#include "../unit.hpp" +#include "../tile.hpp" +#include "../spritesheet.hpp" namespace advanced_wars { @@ -112,6 +117,27 @@ void Menu::handleEvent(Engine *engine, SDL_Event &event) { if (options[selectedOption] == "Exit") { std::cout << "Exiting game..." << std::endl; engine->exit(); + } else if (options[selectedOption] == "Start Game") { + std::cout << "Starting game..." << std::endl; + + /* TODO REMOVE THIS BOILERPLATE CODE BEFORE MERGE */ + + Level level("Osnabrück", 20, 20, std::vector<Tile>(), + std::vector<Building>(), std::vector<Unit>()); + + engine->push_scene(std::make_shared<advanced_wars::Level>(level)); + + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/test.png"; + std::string fullPath = basePath + relativePath; + Spritesheet spritesheet(fullPath, *engine); + + engine->set_spritesheet(spritesheet); + + /* END OF BOILERPLATE CODE */ + + } else if (options[selectedOption] == "Options") { + std::cout << "Opening options..." << std::endl; } } } -- GitLab From 43edfab63d4173c69553d47e4fe20528bc3eb8f5 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Sun, 26 Jan 2025 13:57:16 +0100 Subject: [PATCH 18/29] Adding a first ContextMenu --- src/ui/ContextMenu.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++ src/ui/ContextMenu.hpp | 31 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/ui/ContextMenu.cpp create mode 100644 src/ui/ContextMenu.hpp diff --git a/src/ui/ContextMenu.cpp b/src/ui/ContextMenu.cpp new file mode 100644 index 0000000..e6717b9 --- /dev/null +++ b/src/ui/ContextMenu.cpp @@ -0,0 +1,70 @@ +#include "ContextMenu.hpp" +#include <iostream> +#include <SDL_ttf.h> + +namespace advanced_wars { + + ContextMenu::ContextMenu() + : selectedOption(0) {} + + ContextMenu::~ContextMenu() {} + + void ContextMenu::setOptions(const std::vector<std::string>& newOptions) { + options = newOptions; + selectedOption = 0; // Reset auf die erste Option + } + + void ContextMenu::render(Engine* engine) { + if (!options.empty()) { + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; + return; + } + + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/ARCADECLASSIC.TTF"; + std::string fullPath = basePath + relativePath; + TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 48); + if (!font) { + std::cerr << "Failed to load font: " << TTF_GetError() << std::endl; + return; + } + + SDL_Color white = {255, 255, 255, 255}; + SDL_Color yellow = {255, 255, 0, 255}; + + int startY = 100; // Startposition für das Menü + int spacing = 40; // Abstand zwischen den Optionen + + for (size_t i = 0; i < options.size(); ++i) { + SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white); + if (!textSurface) { + continue; + } + + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine->renderer(), textSurface); + SDL_Rect textRect = {200, startY + static_cast<int>(i * spacing), textSurface->w, textSurface->h}; + SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect); + + SDL_DestroyTexture(textTexture); + SDL_FreeSurface(textSurface); + } + + TTF_CloseFont(font); + TTF_Quit(); + } + } + + void ContextMenu::handleEvent(SDL_Event& event) { + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_DOWN) { + selectedOption = (selectedOption + 1) % options.size(); + } else if (event.key.keysym.sym == SDLK_UP) { + selectedOption = (selectedOption - 1 + options.size()) % options.size(); + } else if (event.key.keysym.sym == SDLK_RETURN) { + std::cout << "Selected option: " << options[selectedOption] << std::endl; + } + } + } + +} diff --git a/src/ui/ContextMenu.hpp b/src/ui/ContextMenu.hpp new file mode 100644 index 0000000..9b98bcb --- /dev/null +++ b/src/ui/ContextMenu.hpp @@ -0,0 +1,31 @@ +#ifndef CONTEXTMENU_HPP +#define CONTEXTMENU_HPP + +#include <SDL.h> +#include <vector> +#include <string> +#include "../scene.hpp" +#include "../engine.hpp" + +namespace advanced_wars { + +class ContextMenu : public Scene { +private: + size_t selectedOption; + std::vector<std::string> options; + +public: + ContextMenu(); + + void setOptions(const std::vector<std::string>& newOptions); + + void render(Engine* engine) override; + + void handleEvent(SDL_Event& event); + + ~ContextMenu(); +}; + +} + +#endif // CONTEXTMENU_HPP -- GitLab From 7a1ee6d16d5ea1e706ece16a4a51df8aeb5c9ac9 Mon Sep 17 00:00:00 2001 From: fdai7466 <nicolas-paul.will@hs-fulda.de> Date: Sun, 26 Jan 2025 23:22:53 +0100 Subject: [PATCH 19/29] add pausemenu class and escape event to level --- src/level.cpp | 17 +++++++++ src/level.hpp | 1 + src/ui/Menu.cpp | 2 +- src/ui/pausemenu.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ src/ui/pausemenu.hpp | 30 ++++++++++++++++ 5 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/ui/pausemenu.cpp create mode 100644 src/ui/pausemenu.hpp diff --git a/src/level.cpp b/src/level.cpp index 9385dbe..af6b8b4 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -4,6 +4,7 @@ #include <SDL.h> #include <iostream> #include <string> +#include "ui/pausemenu.hpp" namespace advanced_wars { @@ -15,6 +16,7 @@ Level::Level(std::string name, int width, int height, std::vector<Tile> tiles, void Level::render(Engine *engine) { // Iterate over all events while (!engine->events().empty()) { + handleEvent(engine, engine->events().at(0)); engine->events().pop_front(); } // Set background color for renderer @@ -24,4 +26,19 @@ void Level::render(Engine *engine) { } } +void Level::handleEvent(Engine *engine, SDL_Event &event) { + // Handle events for the level + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_ESCAPE) { + // Pause the game + std::cout << "Pausing game..." << std::endl; + SDL_Texture *currentTexture = SDL_CreateTexture(engine->renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 800, 600); + + PauseMenu pauseMenu(0, currentTexture); + engine->push_scene(std::make_shared<PauseMenu>(pauseMenu)); + + } + } +} + } // namespace advanced_wars diff --git a/src/level.hpp b/src/level.hpp index 2f81c60..303257b 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -19,6 +19,7 @@ public: std::vector<Building> buildings, std::vector<Unit> units); void render(Engine *events); + void handleEvent(Engine *engine, SDL_Event &event); private: std::string name; diff --git a/src/ui/Menu.cpp b/src/ui/Menu.cpp index 4f37177..556e282 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/Menu.cpp @@ -128,7 +128,7 @@ void Menu::handleEvent(Engine *engine, SDL_Event &event) { engine->push_scene(std::make_shared<advanced_wars::Level>(level)); std::string basePath = SDL_GetBasePath(); - std::string relativePath = "assets/test.png"; + std::string relativePath = "assets/main_background.png"; std::string fullPath = basePath + relativePath; Spritesheet spritesheet(fullPath, *engine); diff --git a/src/ui/pausemenu.cpp b/src/ui/pausemenu.cpp new file mode 100644 index 0000000..26e1294 --- /dev/null +++ b/src/ui/pausemenu.cpp @@ -0,0 +1,85 @@ +#include "pausemenu.hpp" +#include "../engine.hpp" +#include <SDL_ttf.h> + +namespace advanced_wars { + +PauseMenu::PauseMenu(int selectedOption, SDL_Texture *backgroundTexture) + : selectedOption(selectedOption), + options({"Resume", "Options", "Exit"}), backgroundTexture(backgroundTexture) { + // Initialize SDL_ttf + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl; + } +} + +PauseMenu::~PauseMenu() { + if (backgroundTexture) { + SDL_DestroyTexture(backgroundTexture); + } + TTF_Quit(); +} + +void PauseMenu::render(Engine *engine) { + SDL_Renderer *renderer = engine->renderer(); + + // Render the existing level + //engine->render(); + + // Render the dialog background + if (backgroundTexture) { + SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr); + } + + if (TTF_Init() == -1) { + std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; + return; + } + + // Render the dialog options on top of the background + std::string basePath = SDL_GetBasePath(); + std::string relativePath = "assets/ARCADECLASSIC.TTF"; + std::string fullPath = basePath + relativePath; + + TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 24); + if (!font) { + std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError() + << std::endl; + return; + } + + SDL_Color white = {255, 255, 255, 255}; + SDL_Color yellow = {255, 255, 0, 255}; + + for (size_t i = 0; i < options.size(); ++i) { + SDL_Surface *textSurface = TTF_RenderText_Solid( + font, options[i].c_str(), (i == selectedOption) ? yellow : white); + SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + + SDL_Rect destRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h}; + SDL_RenderCopy(renderer, textTexture, nullptr, &destRect); + + SDL_FreeSurface(textSurface); + SDL_DestroyTexture(textTexture); + } + TTF_CloseFont(font); + SDL_RenderPresent(renderer); +} + +void PauseMenu::handleEvent(Engine *engine, SDL_Event &event) { + // Handle events for the pause menu +} + + + +void PauseMenu::loadBackground(SDL_Renderer *renderer, const std::string &imagePath) { + SDL_Surface *surface = IMG_Load(imagePath.c_str()); + if (!surface) { + std::cerr << "Failed to load image: " << IMG_GetError() << std::endl; + return; + } + backgroundTexture = SDL_CreateTextureFromSurface(renderer, surface); + SDL_FreeSurface(surface); +} + +} // namespace advanced_wars \ No newline at end of file diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp new file mode 100644 index 0000000..655e68a --- /dev/null +++ b/src/ui/pausemenu.hpp @@ -0,0 +1,30 @@ +#include "../scene.hpp" +#include <SDL.h> +#include <array> +#include <iostream> +#include <string> +#include <vector> +#include <SDL_image.h> +#include <SDL_ttf.h> + +namespace advanced_wars { + +class PauseMenu : public Scene { +private: + size_t selectedOption; + std::array<std::string, 3> options; + SDL_Texture *backgroundTexture; + +public: + PauseMenu(int selectedOption, SDL_Texture *backgroundTextureS); + + void render(Engine *engine) override; + + void handleEvent(Engine *engine, SDL_Event &event); + + void loadBackground(SDL_Renderer *renderer, const std::string &imagePath); + + ~PauseMenu(); +}; + +} // namespace advanced_wars \ No newline at end of file -- GitLab From 3f727f13b2ea75d78b76df638032848cc3862d97 Mon Sep 17 00:00:00 2001 From: fdai7466 <nicolas-paul.will@hs-fulda.de> Date: Tue, 28 Jan 2025 19:19:41 +0100 Subject: [PATCH 20/29] change sizing of context menu. add backround --- src/main.cpp | 6 +++++- src/ui/ContextMenu.cpp | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c9b04e6..54c3be0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include "engine.hpp" #include "spritesheet.hpp" #include "ui/Menu.hpp" +#include "ui/ContextMenu.hpp" #include "window.hpp" #include <memory> @@ -15,13 +16,16 @@ int main() { // render main menu std::shared_ptr<Menu> menu = std::make_shared<Menu>(0); + std::shared_ptr<ContextMenu> context_menu = std::make_shared<ContextMenu>(); + context_menu->setOptions({"Move", "Info", "Wait"}); + std::string basePath = SDL_GetBasePath(); std::string relativePath = "assets/main_background.png"; std::string fullPath = basePath + relativePath; menu->loadBackground(engine.renderer(), fullPath.c_str()); - engine.push_scene(menu); + engine.push_scene(context_menu); /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), std::vector<Unit>()); diff --git a/src/ui/ContextMenu.cpp b/src/ui/ContextMenu.cpp index e6717b9..cf673d3 100644 --- a/src/ui/ContextMenu.cpp +++ b/src/ui/ContextMenu.cpp @@ -15,6 +15,7 @@ namespace advanced_wars { } void ContextMenu::render(Engine* engine) { + if (!options.empty()) { if (TTF_Init() == -1) { std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; @@ -24,7 +25,7 @@ namespace advanced_wars { std::string basePath = SDL_GetBasePath(); std::string relativePath = "assets/ARCADECLASSIC.TTF"; std::string fullPath = basePath + relativePath; - TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 48); + TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 16); if (!font) { std::cerr << "Failed to load font: " << TTF_GetError() << std::endl; return; @@ -34,7 +35,14 @@ namespace advanced_wars { SDL_Color yellow = {255, 255, 0, 255}; int startY = 100; // Startposition für das Menü - int spacing = 40; // Abstand zwischen den Optionen + int spacing = 20; // Abstand zwischen den Optionen + + //box around options + SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 255, 128); + SDL_Rect box = {190, startY - 3, 50, static_cast<int>(options.size() * spacing)}; + SDL_RenderFillRect(engine->renderer(), &box); + + SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255); for (size_t i = 0; i < options.size(); ++i) { SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white); -- GitLab From bdcd843d08f75133428d0f303989da5a6b70ec32 Mon Sep 17 00:00:00 2001 From: fdai7466 <nicolas-paul.will@hs-fulda.de> Date: Wed, 29 Jan 2025 18:01:08 +0100 Subject: [PATCH 21/29] add variable position for context menu --- src/level.cpp | 36 ++++++++++++++++++++++++++++++++---- src/level.hpp | 3 +++ src/main.cpp | 2 +- src/ui/ContextMenu.cpp | 23 ++++++++++++++--------- src/ui/ContextMenu.hpp | 6 ++++++ 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/level.cpp b/src/level.cpp index af6b8b4..ec13749 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -5,13 +5,16 @@ #include <iostream> #include <string> #include "ui/pausemenu.hpp" +#include "ui/ContextMenu.hpp" namespace advanced_wars { Level::Level(std::string name, int width, int height, std::vector<Tile> tiles, std::vector<Building> buildings, std::vector<Unit> units) : name(name), width(width), height(height), buildings(buildings), - units(units) {}; + units(units), context_menu(ContextMenu()), context_menu_active(false){ + context_menu.setOptions({"Move", "Info", "Wait"}); + } void Level::render(Engine *engine) { // Iterate over all events @@ -20,10 +23,17 @@ void Level::render(Engine *engine) { engine->events().pop_front(); } // Set background color for renderer - if (SDL_SetRenderDrawColor(engine->renderer(), 255, 0, 0, 0)) { + if (SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255)) { std::cout << "Could not set render draw color: " << SDL_GetError() << std::endl; } + + SDL_RenderClear(engine->renderer()); + + if(context_menu_active) { + context_menu.render(engine); + } + } void Level::handleEvent(Engine *engine, SDL_Event &event) { @@ -35,10 +45,28 @@ void Level::handleEvent(Engine *engine, SDL_Event &event) { SDL_Texture *currentTexture = SDL_CreateTexture(engine->renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 800, 600); PauseMenu pauseMenu(0, currentTexture); - engine->push_scene(std::make_shared<PauseMenu>(pauseMenu)); - + engine->push_scene(std::make_shared<PauseMenu>(pauseMenu)); + } + if(context_menu_active){ + if(event.key.keysym.sym == SDLK_DOWN) { + context_menu.handleEvent(event); } + if(event.key.keysym.sym == SDLK_UP) { + context_menu.handleEvent(event); + } + if(event.key.keysym.sym == SDLK_RETURN) { + if(context_menu.getSelectedOption() == "Wait"){ + context_menu_active = false; + } + } + + } + } + if(event.type == SDL_MOUSEBUTTONDOWN) { + context_menu.update(event.button.x, event.button.y); + context_menu_active = true; + } } } // namespace advanced_wars diff --git a/src/level.hpp b/src/level.hpp index 303257b..4766401 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -7,6 +7,7 @@ #include <SDL.h> #include <string> #include <vector> +#include "ui/ContextMenu.hpp" namespace advanced_wars { @@ -27,6 +28,8 @@ private: int height; std::vector<Building> buildings; std::vector<Unit> units; + ContextMenu context_menu; + bool context_menu_active; }; } // namespace advanced_wars diff --git a/src/main.cpp b/src/main.cpp index 54c3be0..4f6d815 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,7 +25,7 @@ int main() { std::string fullPath = basePath + relativePath; menu->loadBackground(engine.renderer(), fullPath.c_str()); - engine.push_scene(context_menu); + engine.push_scene(menu); /* Level level("Osnabrück", 20, 20, std::vector<Tile>(), std::vector<Building>(), std::vector<Unit>()); diff --git a/src/ui/ContextMenu.cpp b/src/ui/ContextMenu.cpp index cf673d3..cb4320b 100644 --- a/src/ui/ContextMenu.cpp +++ b/src/ui/ContextMenu.cpp @@ -15,7 +15,6 @@ namespace advanced_wars { } void ContextMenu::render(Engine* engine) { - if (!options.empty()) { if (TTF_Init() == -1) { std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl; @@ -32,18 +31,17 @@ namespace advanced_wars { } SDL_Color white = {255, 255, 255, 255}; - SDL_Color yellow = {255, 255, 0, 255}; + SDL_Color yellow = {192, 255, 0, 255}; - int startY = 100; // Startposition für das Menü int spacing = 20; // Abstand zwischen den Optionen //box around options - SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 255, 128); - SDL_Rect box = {190, startY - 3, 50, static_cast<int>(options.size() * spacing)}; + SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 255, 255); + SDL_Rect box = {x, y - 3, 50, static_cast<int>(options.size() * spacing)}; SDL_RenderFillRect(engine->renderer(), &box); SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255); - + for (size_t i = 0; i < options.size(); ++i) { SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white); if (!textSurface) { @@ -51,7 +49,7 @@ namespace advanced_wars { } SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine->renderer(), textSurface); - SDL_Rect textRect = {200, startY + static_cast<int>(i * spacing), textSurface->w, textSurface->h}; + SDL_Rect textRect = {x+10, y + static_cast<int>(i * spacing), textSurface->w, textSurface->h}; SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect); SDL_DestroyTexture(textTexture); @@ -69,10 +67,17 @@ namespace advanced_wars { selectedOption = (selectedOption + 1) % options.size(); } else if (event.key.keysym.sym == SDLK_UP) { selectedOption = (selectedOption - 1 + options.size()) % options.size(); - } else if (event.key.keysym.sym == SDLK_RETURN) { - std::cout << "Selected option: " << options[selectedOption] << std::endl; } } } + std::string ContextMenu::getSelectedOption() { + return options[selectedOption]; + } + + void ContextMenu::update(int x, int y) { + this->x = x; + this->y = y; + } + } diff --git a/src/ui/ContextMenu.hpp b/src/ui/ContextMenu.hpp index 9b98bcb..c8e386c 100644 --- a/src/ui/ContextMenu.hpp +++ b/src/ui/ContextMenu.hpp @@ -13,6 +13,8 @@ class ContextMenu : public Scene { private: size_t selectedOption; std::vector<std::string> options; + int x; + int y; public: ContextMenu(); @@ -23,6 +25,10 @@ public: void handleEvent(SDL_Event& event); + void update(int x, int y); + + std::string getSelectedOption(); + ~ContextMenu(); }; -- GitLab From d17844daba52f8807b7d17cb572eb9ce05149888 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 18:30:01 +0100 Subject: [PATCH 22/29] Refactoring: Renaming Pascal-cased files to snake-cased files --- src/level.cpp | 2 +- src/level.hpp | 2 +- src/main.cpp | 4 ++-- src/ui/{ContextMenu.cpp => contextmenu.cpp} | 2 +- src/ui/{ContextMenu.hpp => contextmenu.hpp} | 0 src/ui/{Menu.cpp => menu.cpp} | 2 +- src/ui/{Menu.hpp => menu.hpp} | 0 7 files changed, 6 insertions(+), 6 deletions(-) rename src/ui/{ContextMenu.cpp => contextmenu.cpp} (99%) rename src/ui/{ContextMenu.hpp => contextmenu.hpp} (100%) rename src/ui/{Menu.cpp => menu.cpp} (99%) rename src/ui/{Menu.hpp => menu.hpp} (100%) diff --git a/src/level.cpp b/src/level.cpp index ec13749..99855be 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -5,7 +5,7 @@ #include <iostream> #include <string> #include "ui/pausemenu.hpp" -#include "ui/ContextMenu.hpp" +#include "ui/contextmenu.hpp" namespace advanced_wars { diff --git a/src/level.hpp b/src/level.hpp index 4766401..5cbc656 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -7,7 +7,7 @@ #include <SDL.h> #include <string> #include <vector> -#include "ui/ContextMenu.hpp" +#include "ui/contextmenu.hpp" namespace advanced_wars { diff --git a/src/main.cpp b/src/main.cpp index 4f6d815..1ad887c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ #include "engine.hpp" #include "spritesheet.hpp" -#include "ui/Menu.hpp" -#include "ui/ContextMenu.hpp" +#include "ui/menu.hpp" +#include "ui/contextmenu.hpp" #include "window.hpp" #include <memory> diff --git a/src/ui/ContextMenu.cpp b/src/ui/contextmenu.cpp similarity index 99% rename from src/ui/ContextMenu.cpp rename to src/ui/contextmenu.cpp index cb4320b..8bae5ff 100644 --- a/src/ui/ContextMenu.cpp +++ b/src/ui/contextmenu.cpp @@ -1,4 +1,4 @@ -#include "ContextMenu.hpp" +#include "contextmenu.hpp" #include <iostream> #include <SDL_ttf.h> diff --git a/src/ui/ContextMenu.hpp b/src/ui/contextmenu.hpp similarity index 100% rename from src/ui/ContextMenu.hpp rename to src/ui/contextmenu.hpp diff --git a/src/ui/Menu.cpp b/src/ui/menu.cpp similarity index 99% rename from src/ui/Menu.cpp rename to src/ui/menu.cpp index 556e282..9dafaff 100644 --- a/src/ui/Menu.cpp +++ b/src/ui/menu.cpp @@ -1,4 +1,4 @@ -#include "Menu.hpp" +#include "menu.hpp" #include <SDL.h> #include <SDL_image.h> #include <SDL_ttf.h> diff --git a/src/ui/Menu.hpp b/src/ui/menu.hpp similarity index 100% rename from src/ui/Menu.hpp rename to src/ui/menu.hpp -- GitLab From 3ef419942645fde4a410f1279b03b7bb75695266 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:00:08 +0100 Subject: [PATCH 23/29] Adding debug flags to CMakeLists.txt --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a950f99..eea2dfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,12 @@ file(GLOB_RECURSE ADVANCED_WARS_SOURCES set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_BUILD_TYPE Debug) + +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic") +set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic") + +add_definitions(-DDEBUG) # Compiler-Warnungen aktivieren if(MSVC) -- GitLab From c8f3fb030b4ce2c8a185327c13a473e0fa2f31ca Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:04:46 +0100 Subject: [PATCH 24/29] Fixing an issue where Engine::render() could access an invalid scene after pop_scene() was called --- src/engine.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index eb7baba..317a4e2 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -44,14 +44,13 @@ void Engine::push_scene(std::shared_ptr<Scene> scene) { } std::optional<std::shared_ptr<Scene>> Engine::pop_scene() { - if (!this->scenes.empty()) { + if (this->scenes.empty()) { return std::nullopt; - } else { - std::shared_ptr<Scene> tmp = scenes.at(scenes.size() - 1); + } + std::shared_ptr<Scene> tmp = scenes.back(); this->scenes.pop_back(); - return std::optional<std::shared_ptr<Scene>>(tmp); - } + return tmp; } void Engine::set_spritesheet(Spritesheet spritesheet) { @@ -80,10 +79,17 @@ void Engine::render() { } if (scenes.empty()) { + SDL_RenderPresent(this->sdl_renderer); + return; + } + + std::shared_ptr<Scene> currentScene = scenes.back(); + if (!currentScene) { + SDL_RenderPresent(this->sdl_renderer); return; } - this->scenes.at(scenes.size() - 1)->render(this); + currentScene->render(this); SDL_RenderPresent(this->sdl_renderer); } -- GitLab From aeadab52fbeecc1b4088568a3144ba3e8c6df57c Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:15:41 +0100 Subject: [PATCH 25/29] Implementing return_to_menu function and enhance pause menu event handling Implementing pause menu functionality (resume and exit) --- src/engine.cpp | 9 +++++++++ src/engine.hpp | 2 ++ src/ui/pausemenu.cpp | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/engine.cpp b/src/engine.cpp index 317a4e2..e961618 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -43,6 +43,15 @@ void Engine::push_scene(std::shared_ptr<Scene> scene) { this->scenes.push_back(scene); } +void Engine::return_to_menu() { + // TODO: discuss if we outsource this to a separate function + // clear everything except the first scene + while (this->scenes.size() > 1) { + this->scenes.pop_back(); + } +} + + std::optional<std::shared_ptr<Scene>> Engine::pop_scene() { if (this->scenes.empty()) { return std::nullopt; diff --git a/src/engine.hpp b/src/engine.hpp index b7ae83d..003af97 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -35,6 +35,8 @@ public: std::optional<std::shared_ptr<Scene>> pop_scene(); + void return_to_menu(); + std::deque<SDL_Event> &events(); void set_spritesheet(Spritesheet spritesheet); diff --git a/src/ui/pausemenu.cpp b/src/ui/pausemenu.cpp index 26e1294..0dd5928 100644 --- a/src/ui/pausemenu.cpp +++ b/src/ui/pausemenu.cpp @@ -11,16 +11,28 @@ PauseMenu::PauseMenu(int selectedOption, SDL_Texture *backgroundTexture) if (TTF_Init() == -1) { std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl; } + + if (!backgroundTexture) { + this->backgroundTexture = nullptr; + } } PauseMenu::~PauseMenu() { if (backgroundTexture) { SDL_DestroyTexture(backgroundTexture); + backgroundTexture = nullptr; } TTF_Quit(); } void PauseMenu::render(Engine *engine) { + + while (!engine->events().empty()) { + SDL_Event event = engine->events().at(0); + engine->events().pop_front(); + handleEvent(engine, event); + } + SDL_Renderer *renderer = engine->renderer(); // Render the existing level @@ -67,6 +79,27 @@ void PauseMenu::render(Engine *engine) { } void PauseMenu::handleEvent(Engine *engine, SDL_Event &event) { + if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_DOWN) { + selectedOption = (selectedOption + 1) % options.size(); + } else if (event.key.keysym.sym == SDLK_UP) { + selectedOption = (selectedOption - 1 + options.size()) % options.size(); + } else if (event.key.keysym.sym == SDLK_ESCAPE) { + std::cout << "Resuming game..." << std::endl; + engine->pop_scene(); + } else if (event.key.keysym.sym == SDLK_RETURN) { + if (options[selectedOption] == "Exit") { + // exit into main menu + std::cout << "Exiting game..." << std::endl; + engine->return_to_menu(); + } else if (options[selectedOption] == "Resume") { + // resume game + std::cout << "Resuming game..." << std::endl; + engine->pop_scene(); + } + } + + } // Handle events for the pause menu } -- GitLab From 53eb13b07a6d0d14d9dcd0fd97c89b19269d2a18 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:23:22 +0100 Subject: [PATCH 26/29] Adding pre-processor statements --- src/ui/pausemenu.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp index 655e68a..62dbcc7 100644 --- a/src/ui/pausemenu.hpp +++ b/src/ui/pausemenu.hpp @@ -1,3 +1,6 @@ +#ifndef PAUSE_MENU_HPP +#define PAUSE_MENU_HPP + #include "../scene.hpp" #include <SDL.h> #include <array> @@ -27,4 +30,6 @@ public: ~PauseMenu(); }; -} // namespace advanced_wars \ No newline at end of file +} // namespace advanced_wars + +#endif // PAUSE_MENU_HPP \ No newline at end of file -- GitLab From 681ec1a4de0db79bbe72b69abbabd680a9e736e0 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:24:54 +0100 Subject: [PATCH 27/29] Fixing typo `backgroundTextureS` -> `backgroundTexture` --- src/ui/pausemenu.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp index 62dbcc7..47bcb15 100644 --- a/src/ui/pausemenu.hpp +++ b/src/ui/pausemenu.hpp @@ -19,7 +19,7 @@ private: SDL_Texture *backgroundTexture; public: - PauseMenu(int selectedOption, SDL_Texture *backgroundTextureS); + PauseMenu(int selectedOption, SDL_Texture *backgroundTexture); void render(Engine *engine) override; -- GitLab From 89df337fb5ebd6432cc02e4373bc6c6d96837c5c Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:25:48 +0100 Subject: [PATCH 28/29] Adding documentation & comments to menu.hpp & pausemenu.hpp --- src/ui/menu.hpp | 64 +++++++++++++++++++++++++++++++++++++++--- src/ui/pausemenu.hpp | 66 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/ui/menu.hpp b/src/ui/menu.hpp index df0419d..8b32ad6 100644 --- a/src/ui/menu.hpp +++ b/src/ui/menu.hpp @@ -10,24 +10,80 @@ namespace advanced_wars { +/** + * @class Menu + * @brief Represents the main menu of the game, allowing navigation between different options. + * + * This menu provides three selectable options: + * - "Start Game": Begins a new game session. + * - "Options": Opens the game settings. + * - "Exit": Closes the application. + */ class Menu : public Scene { private: - size_t selectedOption; - std::array<std::string, 3> options; - SDL_Texture *backgroundTexture; + size_t selectedOption; ///< Index of the currently selected menu option. + std::array<std::string, 3> options; ///< The available menu options. + SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if any). public: + /** + * @brief Constructs the Menu with an initial selected option. + * + * Initializes the menu with the available options and sets the currently + * selected option based on the given index. + * + * @param selectedOption The index of the initially selected menu option. + */ Menu(int selectedOption); + /** + * @brief Renders the menu on the screen. + * + * This method clears the screen, draws the background (if available), + * renders the menu title, and displays the selectable options. The currently + * selected option is highlighted in a different color. + * + * @param engine Pointer to the game engine, used for rendering. + */ void render(Engine *engine) override; + /** + * @brief Handles user input events for menu navigation. + * + * This method processes keyboard input to navigate through the menu options. + * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option. + * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option. + * - **Enter (`SDLK_RETURN`)**: Confirms the selection: + * - **"Start Game"**: Loads the game scene. + * - **"Options"**: Opens the settings menu. + * - **"Exit"**: Closes the application. + * + * @param engine Pointer to the game engine, used to manage scenes. + * @param event The SDL event containing user input data. + */ void handleEvent(Engine *engine, SDL_Event &event); + /** + * @brief Loads a background image as a texture. + * + * This method loads an image file, converts it into an SDL texture, and + * assigns it as the menu's background. If the loading fails, an error is + * logged, and the menu will display a plain black background instead. + * + * @param renderer The SDL renderer used to create the texture. + * @param imagePath The file path to the background image. + */ void loadBackground(SDL_Renderer *renderer, const std::string &imagePath); + /** + * @brief Destroys the menu and releases resources. + * + * Cleans up allocated resources, including the background texture (if loaded), + * and ensures that SDL_Image is properly shut down. + */ ~Menu(); }; } // namespace advanced_wars -#endif // MENU_SYSTEM_HPP \ No newline at end of file +#endif // MENU_SYSTEM_HPP diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp index 47bcb15..2d3a998 100644 --- a/src/ui/pausemenu.hpp +++ b/src/ui/pausemenu.hpp @@ -12,21 +12,81 @@ namespace advanced_wars { +/** + * @class PauseMenu + * @brief A scene that represents the in-game pause menu. + * + * The pause menu allows the player to: + * - **Resume**: Return to the current game scene. + * - **Options**: (Currently not implemented). + * - **Exit**: Return to the main menu. + * + * The menu supports keyboard navigation and responds to user input. + */ class PauseMenu : public Scene { private: - size_t selectedOption; - std::array<std::string, 3> options; - SDL_Texture *backgroundTexture; + size_t selectedOption; ///< Index of the currently selected menu option. + std::array<std::string, 3> options; ///< The available pause menu options. + SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if available). public: + /** + * @brief Constructs the pause menu with a background texture. + * + * The pause menu initializes the menu options and stores the provided + * background texture. If no texture is provided, a default black background is used. + * + * @param selectedOption The index of the initially selected menu option. + * @param backgroundTexture A pointer to the background texture (can be nullptr). + */ PauseMenu(int selectedOption, SDL_Texture *backgroundTexture); + /** + * @brief Renders the pause menu on the screen. + * + * This method: + * - Draws the background (if available). + * - Displays the menu options with the currently selected option highlighted. + * - Presents the rendered frame to the screen. + * + * @param engine Pointer to the game engine, used for rendering. + */ void render(Engine *engine) override; + /** + * @brief Handles user input events for menu navigation. + * + * This method processes keyboard input to navigate and interact with the pause menu. + * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option. + * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option. + * - **Escape (`SDLK_ESCAPE`)**: Resumes the game by removing the pause menu. + * - **Enter (`SDLK_RETURN`)**: Executes the selected option: + * - **"Resume"**: Closes the pause menu and resumes the game. + * - **"Exit"**: Returns to the main menu. + * + * @param engine Pointer to the game engine, used to manage scenes. + * @param event The SDL event containing user input data. + */ void handleEvent(Engine *engine, SDL_Event &event); + /** + * @brief Loads a background image as a texture. + * + * This method loads an image file, converts it into an SDL texture, and assigns it + * as the menu’s background. If the loading fails, an error is logged, and the menu + * will display a plain black background instead. + * + * @param renderer The SDL renderer used to create the texture. + * @param imagePath The file path to the background image. + */ void loadBackground(SDL_Renderer *renderer, const std::string &imagePath); + /** + * @brief Destroys the pause menu and releases resources. + * + * Cleans up allocated resources, including the background texture (if loaded), + * and ensures that SDL_ttf is properly shut down. + */ ~PauseMenu(); }; -- GitLab From 45baa9dc6a09fc1e9156c397495d83243104ab41 Mon Sep 17 00:00:00 2001 From: David Hermann <redeagle.private@gmail.com> Date: Wed, 29 Jan 2025 20:33:03 +0100 Subject: [PATCH 29/29] Changing include guards to `#pragma once` in /ui --- src/ui/contextmenu.hpp | 7 ++----- src/ui/menu.hpp | 7 ++----- src/ui/pausemenu.hpp | 7 ++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/ui/contextmenu.hpp b/src/ui/contextmenu.hpp index c8e386c..94b095f 100644 --- a/src/ui/contextmenu.hpp +++ b/src/ui/contextmenu.hpp @@ -1,5 +1,4 @@ -#ifndef CONTEXTMENU_HPP -#define CONTEXTMENU_HPP +#pragma once #include <SDL.h> #include <vector> @@ -32,6 +31,4 @@ public: ~ContextMenu(); }; -} - -#endif // CONTEXTMENU_HPP +} \ No newline at end of file diff --git a/src/ui/menu.hpp b/src/ui/menu.hpp index 8b32ad6..43f84d0 100644 --- a/src/ui/menu.hpp +++ b/src/ui/menu.hpp @@ -1,5 +1,4 @@ -#ifndef MENU_SYSTEM_HPP -#define MENU_SYSTEM_HPP +#pragma once #include "../scene.hpp" #include <SDL.h> @@ -84,6 +83,4 @@ public: ~Menu(); }; -} // namespace advanced_wars - -#endif // MENU_SYSTEM_HPP +} // namespace advanced_wars \ No newline at end of file diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp index 2d3a998..6dc2d2c 100644 --- a/src/ui/pausemenu.hpp +++ b/src/ui/pausemenu.hpp @@ -1,5 +1,4 @@ -#ifndef PAUSE_MENU_HPP -#define PAUSE_MENU_HPP +#pragma once #include "../scene.hpp" #include <SDL.h> @@ -90,6 +89,4 @@ public: ~PauseMenu(); }; -} // namespace advanced_wars - -#endif // PAUSE_MENU_HPP \ No newline at end of file +} // namespace advanced_wars \ No newline at end of file -- GitLab