diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml new file mode 100644 index 0000000..43692db --- /dev/null +++ b/.github/workflows/doxygen.yaml @@ -0,0 +1,24 @@ +on: + push: + branches: [ main ] + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: 'true' # might need recursive, tbd + - name: Doxygen Action + uses: mattnotmitt/doxygen-action@v1.1.0 + with: + doxyfile-path: 'docs/Doxyfile' + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/html diff --git a/.gitignore b/.gitignore index 31d3def..f50581f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ build/ *.app # Generated by Visual Studio -.vscode/ .vs/ *.suo *.user @@ -56,7 +55,22 @@ build/ # Sublime Text *.sublime-workspace -*.sublime-project + +# Created by https://www.gitignore.io/api/visualstudiocode +# Edit at https://www.gitignore.io/?templates=visualstudiocode + +### VisualStudioCode ### +.vscode/* # Maybe .vscode/**/* instead - see comments +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +**/.history + +# End of https://www.gitignore.io/api/visualstudiocode # macOS .DS_Store @@ -75,3 +89,7 @@ Desktop.ini compile_commands.json *.puml + +docs/latex/ +docs/html/ +docs/diagrams/ diff --git a/.gitmodules b/.gitmodules index 3ae9513..57f7b27 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,6 +14,12 @@ path = extern/SDL_ttf url = https://github.com/libsdl-org/SDL_ttf.git branch = release-2.22.x +[submodule "extern/tmxlite"] + path = extern/tmxlite + url = https://github.com/fallahn/tmxlite.git +[submodule "docs/doxygen-awesome-css"] + path = docs/doxygen-awesome-css + url = https://github.com/jothepro/doxygen-awesome-css.git [submodule "extern/magic_enum"] path = extern/magic_enum url = https://github.com/Neargye/magic_enum.git diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..4de5278 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "debug", + "type": "cppdbg", + "miDebuggerPath": "c:\\mingw64\\bin\\gdb.exe", + "request": "launch", + "program": "${workspaceFolder}/build/SDL_Minigame.exe", + "cwd": "${workspaceFolder}", + "preLaunchTask": "build-debug" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..10708b6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cmake.configureOnOpen": true, + "editor.tabSize": 4, + "editor.insertSpaces": true, +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6647c0b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,67 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "build-engine-debug", + "command": "cd build; cmake -DCMAKE_BUILD_TYPE=Debug; cmake --build .", + "problemMatcher": [], + "group": "build" + }, + { + "type": "shell", + "label": "build-engine", + "command": "cd build; cmake -DCMAKE_BUILD_TYPE=Release; cmake --build .", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "docker-build", + "label": "build-doxygen", + "dockerBuild": { + "context": "${workspaceRoot}/docs/docker", + "tag": "vego_doxygen-docker", + }, + "problemMatcher": [], + }, + { + "type": "docker-run", + "label": "gen-doxygen", + "dockerRun": { + "image": "vego_doxygen-docker", + "remove": true, + "volumes": [ + { + "localPath": "${workspaceFolder}", + "containerPath": "/source" + }, + { + "localPath": "${workspaceFolder}/docs", + "containerPath": "/output" + }, + { + "localPath": "${workspaceFolder}/docs/Doxyfile", + "containerPath": "/Doxyfile" + }, + ] + }, + "problemMatcher": [], + }, + { + "type": "process", + "label": "open-doxygen", + "command": "explorer", + "windows": { + "command": "explorer.exe" + }, + "args": ["${workspaceFolder}\\docs\\html\\index.html"], + "problemMatcher": [], + "dependsOn": "gen-doxygen", + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 24a3f77..4f6988c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15) project(engine) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) @@ -17,10 +17,13 @@ set(SDL2TTF_VENDORED ON) set(SDL2_SOURCE_DIR “${ENGINE_SOURCE_DIR}/extern/SDL”) +set(TMXLITE_STATIC_LIB TRUE) + add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) +add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL) add_subdirectory(extern/magic_enum EXCLUDE_FROM_ALL) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) @@ -35,10 +38,12 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu SDL2_mixer::SDL2_mixer-static SDL2_ttf::SDL2_ttf-static magic_enum::magic_enum + tmxlite ) if(CMAKE_BUILD_TYPE MATCHES "Debug") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") # -fsanitize=address -fno-omit-frame-pointer") + #target_link_libraries(${PROJECT_NAME} PRIVATE "-fsanitize=address") endif() # link/copy compile commands to root dir diff --git a/README.md b/README.md index bc145bd..ced168c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,35 @@ -##### Compiling: +# VEGO-Engine + +A **VE**ry **GO**od engine, to develop small, lightweight minigames without calling all those SDL functions yourself. This project orginates as a university project at UAS Technikum Wien. + +## Getting started + +### Compiling + +To compile this projects the following prerequisites need to be met: + +- A C++ compiler, for example GCC + - On Windows you can use GCC via [MinGW](https://www.mingw-w64.org/) +- CMake + +The project can be cloned and compiled with the following commands: ```sh -git submodule update --init --recursive # only needed once +git clone --recurse-submodules -j8 https://github.com/VEGO-Engine/Engine.git cmake -S . -B build cmake --build build ``` -For Windows systems using MinGW the flag `-G "MinGW Makefiles"` has to be specified -The executable can be found as `build/SDL_Minigame` after building +Depending on the system, you might need to specify which generator to use, for example on a Windows system using MinGW: + +```sh +git clone --recurse-submodules -j8 https://github.com/VEGO-Engine/Engine.git +cmake -S . -B build -G "MinGW Makefiles" +cmake --build build +``` + +Compiling the whole project might take a while, but the Engine by itself will not build to an executable. To do that you can compile the [project template](https://github.com/VEGO-Engine/Project_Template). If the template compiles without any errors, you can use the project template to start working on your own game. + +### Usage + +As mentioned above, we provide a [project template](https://github.com/VEGO-Engine/Project_Template). To use the template, simply clone it and start working. You can change the name for your project freely, see the documentation on the template for further information. To push to your own remote, create a new repository on the platform of your choice, and edit origin in the local git repository. diff --git a/assets/Map.aseprite b/assets/Map.aseprite deleted file mode 100644 index 7cb0feb..0000000 Binary files a/assets/Map.aseprite and /dev/null differ diff --git a/assets/MapNew-Sheet.aseprite b/assets/MapNew-Sheet.aseprite deleted file mode 100644 index 7f27b16..0000000 Binary files a/assets/MapNew-Sheet.aseprite and /dev/null differ diff --git a/assets/MapNew.aseprite b/assets/MapNew.aseprite deleted file mode 100644 index fb12db2..0000000 Binary files a/assets/MapNew.aseprite and /dev/null differ diff --git a/assets/MapNew.json b/assets/MapNew.json deleted file mode 100644 index f7526fc..0000000 --- a/assets/MapNew.json +++ /dev/null @@ -1,106 +0,0 @@ -{ "frames": [ - { - "filename": "MapNew.aseprite", - "frame": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 32, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 64, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 96, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 128, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 160, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 192, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 224, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 256, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - }, - { - "filename": "MapNew.aseprite", - "frame": { "x": 288, "y": 0, "w": 32, "h": 32 }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 }, - "sourceSize": { "w": 32, "h": 32 }, - "duration": 100 - } - ], - "meta": { - "app": "https://www.aseprite.org/", - "version": "1.3.2-x64", - "format": "RGBA8888", - "size": { "w": 320, "h": 32 }, - "scale": "1", - "frameTags": [ - ], - "layers": [ - ], - "slices": [ - ] - } -} diff --git a/assets/MapNewBackup.aseprite b/assets/MapNewBackup.aseprite deleted file mode 100644 index fb12db2..0000000 Binary files a/assets/MapNewBackup.aseprite and /dev/null differ diff --git a/assets/MapTest.aseprite b/assets/MapTest.aseprite deleted file mode 100644 index c047008..0000000 Binary files a/assets/MapTest.aseprite and /dev/null differ diff --git a/assets/Player1Victory.png b/assets/Player1Victory.png deleted file mode 100644 index f50a386..0000000 Binary files a/assets/Player1Victory.png and /dev/null differ diff --git a/assets/Player2Victory.png b/assets/Player2Victory.png deleted file mode 100644 index 7a20be3..0000000 Binary files a/assets/Player2Victory.png and /dev/null differ diff --git a/assets/SDL_map_test.txt b/assets/SDL_map_test.txt deleted file mode 100644 index 809f2e3..0000000 --- a/assets/SDL_map_test.txt +++ /dev/null @@ -1,20 +0,0 @@ -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,2,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,2,2,2,3 -3,3,3,2,3,3,3,3,2,3,7,1,1,1,9,3,3,3,3,3,3,3,2,2,3 -3,3,2,2,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,2,2,2,3,3,3,3,3,7,1,1,1,9,3,3,2,3,3,3,3,3,3,3 -3,3,2,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,2,3,3,3,3 -3,3,3,2,2,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,2,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,2,2,3,3,3,3 -3,3,3,3,3,3,3,2,3,3,7,1,1,1,9,3,2,3,3,2,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,2,3,3,3,3,3,3,3,3 -2,2,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,2,2,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 -3,3,3,3,3,3,3,3,3,3,7,1,1,1,9,3,3,3,3,3,3,3,3,3,3 diff --git a/assets/VictoryBackup.aseprite b/assets/VictoryBackup.aseprite deleted file mode 100644 index b53cd97..0000000 Binary files a/assets/VictoryBackup.aseprite and /dev/null differ diff --git a/assets/atk_speed_powerup.png b/assets/atk_speed_powerup.png deleted file mode 100644 index 9bcce69..0000000 Binary files a/assets/atk_speed_powerup.png and /dev/null differ diff --git a/assets/cat.png b/assets/cat.png deleted file mode 100644 index 4b52f0f..0000000 Binary files a/assets/cat.png and /dev/null differ diff --git a/assets/characterSelection.png b/assets/characterSelection.png deleted file mode 100644 index 68e958a..0000000 Binary files a/assets/characterSelection.png and /dev/null differ diff --git a/assets/chicken_gentleman_spritesheet.png b/assets/chicken_gentleman_spritesheet.png deleted file mode 100644 index 848c426..0000000 Binary files a/assets/chicken_gentleman_spritesheet.png and /dev/null differ diff --git a/assets/chicken_knight_spritesheet.png b/assets/chicken_knight_spritesheet.png deleted file mode 100644 index 2304ae6..0000000 Binary files a/assets/chicken_knight_spritesheet.png and /dev/null differ diff --git a/assets/chicken_mlady_spritesheet.png b/assets/chicken_mlady_spritesheet.png deleted file mode 100644 index c075990..0000000 Binary files a/assets/chicken_mlady_spritesheet.png and /dev/null differ diff --git a/assets/chicken_neutral.png b/assets/chicken_neutral.png deleted file mode 100644 index 8a68462..0000000 Binary files a/assets/chicken_neutral.png and /dev/null differ diff --git a/assets/chicken_neutral_knight.png b/assets/chicken_neutral_knight.png deleted file mode 100644 index 1cf69c9..0000000 Binary files a/assets/chicken_neutral_knight.png and /dev/null differ diff --git a/assets/chicken_neutral_mlady.png b/assets/chicken_neutral_mlady.png deleted file mode 100644 index 3973d7d..0000000 Binary files a/assets/chicken_neutral_mlady.png and /dev/null differ diff --git a/assets/chicken_neutral_wizard.png b/assets/chicken_neutral_wizard.png deleted file mode 100644 index aba3980..0000000 Binary files a/assets/chicken_neutral_wizard.png and /dev/null differ diff --git a/assets/chicken_spritesheet.png b/assets/chicken_spritesheet.png deleted file mode 100644 index ba003eb..0000000 Binary files a/assets/chicken_spritesheet.png and /dev/null differ diff --git a/assets/chicken_wizard_spritesheet.png b/assets/chicken_wizard_spritesheet.png deleted file mode 100644 index 8694c93..0000000 Binary files a/assets/chicken_wizard_spritesheet.png and /dev/null differ diff --git a/assets/chicken_wizzard_spritesheet.png b/assets/chicken_wizzard_spritesheet.png deleted file mode 100644 index 27e8796..0000000 Binary files a/assets/chicken_wizzard_spritesheet.png and /dev/null differ diff --git a/assets/cow.png b/assets/cow.png deleted file mode 100644 index 956895f..0000000 Binary files a/assets/cow.png and /dev/null differ diff --git a/assets/dirt.png b/assets/dirt.png deleted file mode 100644 index b60025b..0000000 Binary files a/assets/dirt.png and /dev/null differ diff --git a/assets/egg.png b/assets/egg.png deleted file mode 100644 index f0a12bf..0000000 Binary files a/assets/egg.png and /dev/null differ diff --git a/assets/grass.png b/assets/grass.png deleted file mode 100644 index b096692..0000000 Binary files a/assets/grass.png and /dev/null differ diff --git a/assets/grass_water_left.png b/assets/grass_water_left.png deleted file mode 100644 index 6a22a75..0000000 Binary files a/assets/grass_water_left.png and /dev/null differ diff --git a/assets/grass_water_right.png b/assets/grass_water_right.png deleted file mode 100644 index fa75ce7..0000000 Binary files a/assets/grass_water_right.png and /dev/null differ diff --git a/assets/heart.png b/assets/heart.png deleted file mode 100644 index 867809b..0000000 Binary files a/assets/heart.png and /dev/null differ diff --git a/assets/heart_powerup.png b/assets/heart_powerup.png deleted file mode 100644 index 0a2a92d..0000000 Binary files a/assets/heart_powerup.png and /dev/null differ diff --git a/assets/iconImage.bmp b/assets/iconImage.bmp deleted file mode 100644 index 6eddbef..0000000 Binary files a/assets/iconImage.bmp and /dev/null differ diff --git a/assets/movement_speed_powerup.png b/assets/movement_speed_powerup.png deleted file mode 100644 index e0876ec..0000000 Binary files a/assets/movement_speed_powerup.png and /dev/null differ diff --git a/assets/sound/background_music.mp3 b/assets/sound/background_music.mp3 deleted file mode 100644 index f79cd6c..0000000 Binary files a/assets/sound/background_music.mp3 and /dev/null differ diff --git a/assets/sound/steps.wav b/assets/sound/steps.wav deleted file mode 100644 index a060c29..0000000 Binary files a/assets/sound/steps.wav and /dev/null differ diff --git a/assets/sound/throw_egg.wav b/assets/sound/throw_egg.wav deleted file mode 100644 index 67dc0e7..0000000 Binary files a/assets/sound/throw_egg.wav and /dev/null differ diff --git a/assets/startscreen.png b/assets/startscreen.png deleted file mode 100644 index a1fe40d..0000000 Binary files a/assets/startscreen.png and /dev/null differ diff --git a/assets/stone.png b/assets/stone.png deleted file mode 100644 index 4798d7b..0000000 Binary files a/assets/stone.png and /dev/null differ diff --git a/assets/title_screen.png b/assets/title_screen.png deleted file mode 100644 index e8bb2f3..0000000 Binary files a/assets/title_screen.png and /dev/null differ diff --git a/assets/title_screen_backup.aseprite b/assets/title_screen_backup.aseprite deleted file mode 100644 index 21d6030..0000000 Binary files a/assets/title_screen_backup.aseprite and /dev/null differ diff --git a/assets/water.png b/assets/water.png deleted file mode 100644 index 88dfbeb..0000000 Binary files a/assets/water.png and /dev/null differ diff --git a/assets/water1.ase b/assets/water1.ase deleted file mode 100644 index 86e75e3..0000000 Binary files a/assets/water1.ase and /dev/null differ diff --git a/assets/water1.png b/assets/water1.png deleted file mode 100644 index 7ef949c..0000000 Binary files a/assets/water1.png and /dev/null differ diff --git a/Doxyfile b/docs/Doxyfile similarity index 98% rename from Doxyfile rename to docs/Doxyfile index f3a09ee..a1de95c 100644 --- a/Doxyfile +++ b/docs/Doxyfile @@ -42,13 +42,13 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "My Project" +PROJECT_NAME = "VEGO-Engine" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 0.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -67,14 +67,14 @@ PROJECT_LOGO = # when the HTML document is shown. Doxygen will copy the logo to the output # directory. -PROJECT_ICON = +PROJECT_ICON = assets/chicken_neutral_knight.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = +OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format @@ -396,7 +396,7 @@ AUTOLINK_SUPPORT = YES # diagrams that involve STL classes more complete and accurate. # The default value is: NO. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. @@ -842,7 +842,7 @@ CITE_BIB_FILES = # messages are off. # The default value is: NO. -QUIET = NO +QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES @@ -949,7 +949,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = +INPUT = ./include ./src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -989,63 +989,15 @@ INPUT_FILE_ENCODING = # be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cxxm \ - *.cpp \ - *.cppm \ - *.ccm \ - *.c++ \ - *.c++m \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ +FILE_PATTERNS = *.cpp \ *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.ixx \ - *.l \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.pyw \ - *.f90 \ - *.f95 \ - *.f03 \ - *.f08 \ - *.f18 \ - *.f \ - *.for \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf \ - *.ice + *.hpp # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -1084,14 +1036,17 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = ./include \ + ./src # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. -EXAMPLE_PATTERNS = * +EXAMPLE_PATTERNS = *.cpp \ + *.h \ + *.hpp # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands @@ -1325,7 +1280,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = docs/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1365,7 +1320,10 @@ HTML_STYLESHEET = # documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = docs/doxygen-awesome-css/doxygen-awesome.css \ + docs/doxygen-awesome-css/doxygen-awesome-sidebar-only.css \ + docs/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css \ + docs/custom.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1375,7 +1333,10 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = docs/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js \ + docs/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js \ + docs/doxygen-awesome-css/doxygen-awesome-paragraph-link.js \ + docs/doxygen-awesome-css/doxygen-awesome-interactive-toc.js # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. @@ -1388,7 +1349,7 @@ HTML_EXTRA_FILES = # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE = AUTO_LIGHT +HTML_COLORSTYLE = LIGHT # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to @@ -1716,7 +1677,7 @@ DISABLE_INDEX = NO # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES # When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the # FULL_SIDEBAR option determines if the side bar is limited to only the treeview @@ -2502,7 +2463,7 @@ HIDE_UNDOC_RELATIONS = YES # set to NO # The default value is: NO. -HAVE_DOT = NO +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of @@ -2639,7 +2600,7 @@ DOT_WRAP_THRESHOLD = 17 # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -TEMPLATE_RELATIONS = NO +TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the @@ -2727,7 +2688,7 @@ DIR_GRAPH_MAX_DEPTH = 1 # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = SVG # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. @@ -2739,13 +2700,13 @@ DOT_IMAGE_FORMAT = png # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. -INTERACTIVE_SVG = NO +INTERACTIVE_SVG = YES # The DOT_PATH tag can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = +DOT_PATH = /usr/bin/dot # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile diff --git a/docs/Doxyfile.bak b/docs/Doxyfile.bak new file mode 100644 index 0000000..cf23eae --- /dev/null +++ b/docs/Doxyfile.bak @@ -0,0 +1,63 @@ +# Doxyfile + +# Project information +PROJECT_NAME = "SDL Minigame" +PROJECT_NUMBER = "1.0" +PROJECT_ICON = assets/chicken_neutral_knight.png +OUTPUT_DIRECTORY = docs + +OPTIMIZE_OUTPUT_FOR_C = YES +EXTRACT_ALL = NO +EXTRACT_LOCAL_CLASSES = YES + +CLASS_DIAGRAMS = YES + +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +DOT_PATH = /usr/bin/dot + +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = YES +UML_LIMIT_NUM_FIELDS = 50 +TEMPLATE_RELATIONS = YES +DOT_TRANSPARENT = YES + +# Source files +INPUT = ./include ./src +FILE_PATTERNS = *.cpp *.h *.hpp +EXAMPLE_PATH = ./include ./src +EXAMPLE_PATTERNS = *.cpp *.h *.hpp + +# Output formats +GENERATE_XML = YES +GENERATE_HTML = YES +DOT_IMAGE_FORMAT = SVG +COLLABORATION_GRAPH = YES +GENERATE_LATEX = NO + +# Extra settings +USE_MATHJAX = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +EXTRACT_ANON_NSPACES = YES +SHOW_FILES = YES +SHOW_INCLUDE_FILES = YES +SHOW_USED_FILES = YES +RECURSIVE = YES + +# Class diagram options +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES +HTML_COLLABORATION = YES + +# idk everything else +TAB_SIZE = 4 \ No newline at end of file diff --git a/docs/custom.css b/docs/custom.css new file mode 100644 index 0000000..720b3bd --- /dev/null +++ b/docs/custom.css @@ -0,0 +1,54 @@ +html { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #bd93f9; + --primary-dark-color: #9270e4; + --primary-light-color: #9270e4; + + /* page base colors */ + --page-background-color: #ffffff; + --page-foreground-color: #2f4153; + --page-secondary-foreground-color: #6f7e8e; + + /* color for all separators on the website: hr, borders, ... */ + --separator-color: #bd93f965; + + /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ + --border-radius-large: 22px; + --border-radius-small: 9px; + --border-radius-medium: 14px; + + /* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */ + --spacing-small: 8px; + --spacing-medium: 14px; + --spacing-large: 19px; + + --top-height: 125px; + + ... +} + +html.dark-mode { + color-scheme: dark; + + --primary-color: #bd93f9; + --primary-dark-color: #9270e4; + --primary-light-color: #9270e4; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --page-background-color: #21222c; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #3a3246; + --side-nav-background: #282a36; + --side-nav-foreground: #f8f8f2; + --toc-background: #282A36; + --searchbar-background: var(--page-background-color); + + ... +} + +.paramname em { + font-weight: 600; + color: var(--primary-dark-color); +} \ No newline at end of file diff --git a/docs/diagrams/.clang-uml b/docs/diagrams/.clang-uml deleted file mode 100644 index f987536..0000000 --- a/docs/diagrams/.clang-uml +++ /dev/null @@ -1,62 +0,0 @@ -compilation_database_dir: ../.. -output_directory: . -diagrams: - - includes: - type: include - relative_to: ../.. - glob: - - src/*.cpp - - include/*.h - generate_system_headers: true - include: - paths: - - src - - include - plantuml: - before: - - 'skinparam linetype ortho' - - includes_no_external: - type: include - relative_to: ../.. - glob: - - src/*.cpp - - include/*.h - include: - paths: - - src - - include - plantuml: - before: - - 'skinparam linetype ortho' - - classes: - type: class - relative_to: ../.. - glob: - - src/*.cpp - - include/*.h - include: - paths: - - src - - include - plantuml: - before: - - 'skinparam linetype ortho' - - load_map_example_sequence: - type: sequence - relative_to: ../.. - glob: - - src/*.cpp - - include/*.h - include: - paths: - - src - - include - start_from: - - function: "Map::loadMap(const char *,int,int)" - plantuml: - before: - - 'skinparam linetype ortho' \ No newline at end of file diff --git a/docs/diagrams/classes.svg b/docs/diagrams/classes.svg deleted file mode 100644 index df3320a..0000000 --- a/docs/diagrams/classes.svg +++ /dev/null @@ -1 +0,0 @@ -Component~Component() constexpr = default : voiddraw() : voidinit() : voidupdate() : voidentity : Entity *Vector2DVector2D() : voidVector2D(float x, float y) : voidoperator*(const int & i) : Vector2D &zero() : Vector2D &x : floaty : floatColliderComponentColliderComponent(const char * tag) : voidColliderComponent(const char * tag, float hitboxScale) : voidhandleCollision(Vector2D & characterPos, SDL_Rect & characterCollider, SDL_Rect & componentCollider) : voidinit() : voidremoveCollision() : voidupdate() : voidcollider : SDL_RecthasCollision : boolhitboxScale : floatisProjectile : booltag : const char *transform : TransformComponent *GroupLabelMAPTILESPLAYERSENEMIESCOLLIDERSPROJECTILEHEARTSPOWERUPSTeamLabelNONEBLUEREDEntityEntity(Manager & mManager) : voidaddComponent<T,TArgs...>(TArgs &&... mArgs) : T &addGroup(Group mGroup) : voiddelGroup(Group mGroup) : voiddestroy() : voiddraw() const : voidgetComponent<T>() const : T &getGroupBitSet() : std::bitset<MAX_GROUPS>getManager() : Manager &getTeam() : TeamLabelhasComponent<T>() const : _BoolhasGroup(Group mGroup) : boolisActive() const : boolsetTeam(TeamLabel teamLabel) : voidupdate() const : voidactive : boolcomponentArray : ComponentArraycomponentBitSet : ComponentBitSetcomponents : std::vector<std::unique_ptr<Component>>groupBitSet : GroupBitSetmanager : Manager &teamLabel : TeamLabelPowerupTypeHEARTWALKINGSPEEDSHOOTINGSPEEDAssetManagerAssetManager(Manager * manager) : void~AssetManager() : voidaddSoundEffect(std::string id, const char * path) : voidaddTexture(std::string id, const char * path) : voidcalculateSpawnPosition() : Vector2DcalculateType() : PowerupTypecreatePowerup(Vector2D pos, PowerupType type) : voidcreateProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char * texturePath, TeamLabel teamLabel) : voidgetSound(std::string id) : Mix_Chunk *getTexture(std::string id) : SDL_Texture *man : Manager *soundEffects : std::map<std::string,Mix_Chunk *>textures : std::map<std::string,SDL_Texture *>TextureDictpowerupDictionary : std::map<PowerupType,std::string>tileDictionary : const std::map<int,std::string>TileComponentTileComponent() = default : voidTileComponent(int x, int y, int w, int h, int id) : void~TileComponent() = default : voidinit() : voidpath : const char *sprite : SpriteComponent *textureDict : TextureDicttileID : inttileRect : SDL_Recttransform : TransformComponent *TransformComponentTransformComponent() : voidTransformComponent(int scale) : voidTransformComponent(float x, float y) : voidTransformComponent(float x, float y, int scale) : voidTransformComponent(float x, float y, int w, int h, int scale) : voidinit() : voidmodifySpeed(int8_t modifier) : voidupdate() : voiddirection : Vector2Dheight : intposition : Vector2Dscale : intspeed : intwidth : intAnimationAnimation() : voidAnimation(uint8_t index, uint8_t frames, uint8_t speed) : voidframes : uint8_tindex : uint8_tspeed : uint8_tAnimationTypeIDLEWALKDirectionLEFTRIGHTSpriteComponentSpriteComponent() = default : voidSpriteComponent(const char * path) : voidSpriteComponent(const char * path, bool isAnimated) : void~SpriteComponent() : voiddraw() : voidinit() : voidplayAnimation(AnimationType type) : voidsetDirection(Direction direction) : voidsetTexture(const char * path) : voidupdate() : voidanimated : boolanimationIndex : intanimations : std::map<AnimationType,std::unique_ptr<Animation>>destRect : SDL_Rectflipped : boolframes : uint8_tspeed : uint8_tsrcRect : SDL_Recttexture : SDL_Texture *transform : TransformComponent *ManageraddEntity() : Entity &addToGroup(Entity * mEntity, Group mGroup) : voidaddToTeam(Entity * mEntity, Team mTeam) : voiddraw() : voidgetAll() : std::vector<Entity *>getGroup(Group mGroup) : std::vector<Entity *> &getTeam(Team mTeam) : std::vector<Entity *> &refresh() : voidupdate() : voidentities : std::vector<std::unique_ptr<Entity>>entitiesByGroup : std::array<std::vector<Entity *>,MAX_GROUPS>entitiesByTeam : std::array<std::vector<Entity *>,MAX_TEAMS>TextureManagerTextureManager() : void~TextureManager() : voiddraw(SDL_Texture * texture, SDL_Rect src, SDL_Rect dest, bool flipped = false) : voidloadTexture(const char * fileName) : SDL_Texture *splitSpriteSheet(SDL_Texture * spriteSheet, int width, int height, int spritesOnSheet) : std::vector<SDL_Rect>texture_cache : std::map<std::string,SDL_Texture *>SoundTypesSTEPSTHROW_EGGSoundManagerSoundManager() : voidSoundManager(const SoundManager &) = deleted : void~SoundManager() : voidoperator=(const SoundManager &) = deleted : voidloadSound(const char * fileName) : Mix_Chunk *playSound(SoundTypes sound) : voidsound_cache : std::map<const char *,Mix_Chunk *>KeyboardControllerKeyboardController() = default : voidKeyboardController(SDL_Scancode up, SDL_Scancode down, SDL_Scancode left, SDL_Scancode right, SDL_Scancode fire, Vector2D fireVelocity) : void~KeyboardController() constexpr = default : voidinit() : voidmodifyAtkSpeed(int8_t modifier) : voidupdate() : voiddown : SDL_Scancodefire : SDL_ScancodefireCooldown : uint32_tfireVelocity : Vector2Dkeystates : const uint8_t *lastFireTime : uint32_tleft : SDL_Scancodeplayer : TransformComponent *right : SDL_Scancodesprite : SpriteComponent *transform : TransformComponent *up : SDL_ScancodeProjectileComponentProjectileComponent(int range, int speed, Vector2D direction) : void~ProjectileComponent() : voidinit() : voidupdate() : voiddirection : Vector2Ddistance : intrange : intspeed : inttransformComponent : TransformComponent *HealthComponentHealthComponent(int health, Direction side) : void~HealthComponent() : voidcreateHeartComponents(int x) : voidgetHealth() : intinit() : voidmodifyHealth(int health = -1) : voidrefreshHearts() : voidsetHealth(int health) : voidhealth : intside : DirectionGameGame() : void~Game() : voidaddTile(unsigned long id, int x, int y) : voidclean() : voidgetWinner() const : TeamLabelhandleEvents() : voidinit(const char * title, int xpos, int ypos, int width, int height, bool fullscreen) : voidrefreshPlayers() : voidrender() : voidrunning() const : boolselectCharacters(const char *& playerSprite, const char *& enemySprite) : voidsetWinner(TeamLabel winningTeam) : voidupdate() : voidassets : AssetManager *collisionHandler : CollisionHandler *counter : intevent : SDL_EventisRunning : boolrenderer : SDL_Renderer *soundManager : SoundManager *textureManager : TextureManager *window : SDL_Window *winner : TeamLabeldirectionLEFTRIGHTUPDOWNCollisionHandlerCollisionHandler(Manager & mManager) : void~CollisionHandler() : voidgetAnyIntersection<T>(Entity * entity, Vector2D posMod = = {}, const std::initializer_list<GroupLabel> & groupLabels = = {}, const std::initializer_list<TeamLabel> & teamLabels = = {}, bool negateTeam = false) : TgetColliders(const std::initializer_list<GroupLabel> & groupLabels, const std::initializer_list<TeamLabel> & teamLabels = = {}, bool negateTeam = false) : std::vector<ColliderComponent *>getIntersection(Entity * entityA, Entity * entityB, Vector2D posModA = Vector2D(0,0), Vector2D posModB = Vector2D(0,0)) : IntersectionBitSetgetIntersectionWithBounds(Entity * entity, Vector2D posMod = Vector2D(0,0)) : IntersectionBitSetupdate() : voidmanager : Manager &PowerupComponentPowerupComponent(PowerupType type) : void~PowerupComponent() : voidatkSpeedEffect(Entity * player) : voidheartEffect(Entity * player) : voidmovementSpeedEffect(Entity * player) : voidupdate() : voidpickupFunc : void (PowerupComponent::*)(Entity *)PlayerComponentMapMap() = default : void~Map() constexpr = default : voidloadMap(const char * path, int sizeX, int sizeY) : boolStatsMOVEMENT_SPEEDATTACK_SPEEDStatEffectsComponentStatEffectsComponent() : void~StatEffectsComponent() : voidinit() : voidmodifyStatDur(Stats stat, int duration) : voidmodifyStatValue(Stats stat, int modifier) : voidupdate() : voidbuffs : std::array<int,MAX_STATS>PopupWindowPopupWindow(const char * title, const std::string & message) : void~PopupWindow() : voidhandleWinnerEvents() : voidrenderWinnerPopup(TeamLabel winner) : voidshouldContinue() const : boolcontinueGame : boolinteracted : boolrenderer : SDL_Renderer *texture : SDL_Texture *window : SDL_Window *GameObjectGameObject(const char * texturesheet, int x, int y) : void~GameObject() constexpr = default : voidrender() : voidupdate() : voiddestRect : SDL_RectobjTexture : SDL_Texture *srcRect : SDL_RectxPos : intyPos : intentitytransformmanagerteamLabelmantransformspritetextureDictpositiondirectiontransformtransformplayerspritefireVelocitytransformComponentdirectionsidewinnercollisionHandlerassetstextureManagersoundManagermanager \ No newline at end of file diff --git a/docs/diagrams/howto.md b/docs/diagrams/howto.md deleted file mode 100644 index 01260b8..0000000 --- a/docs/diagrams/howto.md +++ /dev/null @@ -1,12 +0,0 @@ -Need [clang-uml](https://clang-uml.github.io/index.html) - -```sh -clang-uml -clang-uml --add-compile-flag -I/usr/lib/clang/16/include # might need additional flags, example for my machine -clang-uml --print-from -n load_map_example_sequence # to get availabel commands for sequence diagram -``` - -then use plant uml to generate an actual `.svg` vector graphic -```sh -plantuml -tsvg *.puml -``` \ No newline at end of file diff --git a/docs/diagrams/includes.svg b/docs/diagrams/includes.svg deleted file mode 100644 index 288e1de..0000000 --- a/docs/diagrams/includes.svg +++ /dev/null @@ -1 +0,0 @@ -srcincludeTileComponent.cppManager.cppAssetManager.cppProjectileComponent.cppPlayerComponent.cppCollisionHandler.cppEntity.cppMap.cppSpriteComponent.cppStatEffectsComponent.cppHealthComponent.cppVector2D.cppColliderComponent.cppECS.cppTransformComponent.cppSoundManager.cppTextureManager.cppPowerupComponent.cppmain.cppKeyboardController.cppGame.cppPopupWindow.cppGameObject.cppTileComponent.hComponent.hTextureDict.hAssetManager.hEntity.hColliderComponent.hVector2D.hECS.hConstants.hTransformComponent.hSpriteComponent.hAnimationHandler.hDirection.hManager.hTextureManager.hSoundManager.hComponents.hKeyboardController.hProjectileComponent.hHealthComponent.hGame.hCollisionHandler.hPowerupComponent.hPlayerComponent.hMap.hStatEffectsComponent.hPopupWindow.hGameObject.hSDL.hmapstringSDL_render.hSDL_mixer.harraymemorybitsetvectorSDL_rect.hcstddefiostreamcstdintalgorithmSDL_image.hinitializer_listtupleutilitycassertcstdiocctypefstreamSDL_timer.hstdexceptctimeSDL_ttf.hSDL_error.h \ No newline at end of file diff --git a/docs/diagrams/includes_no_external.svg b/docs/diagrams/includes_no_external.svg deleted file mode 100644 index 6bb4891..0000000 --- a/docs/diagrams/includes_no_external.svg +++ /dev/null @@ -1 +0,0 @@ -srcincludeTileComponent.cppManager.cppAssetManager.cppProjectileComponent.cppPlayerComponent.cppCollisionHandler.cppEntity.cppMap.cppSpriteComponent.cppStatEffectsComponent.cppHealthComponent.cppVector2D.cppColliderComponent.cppECS.cppTransformComponent.cppSoundManager.cppTextureManager.cppPowerupComponent.cppmain.cppKeyboardController.cppGame.cppPopupWindow.cppGameObject.cppTileComponent.hComponent.hTextureDict.hAssetManager.hEntity.hColliderComponent.hVector2D.hECS.hConstants.hTransformComponent.hSpriteComponent.hAnimationHandler.hDirection.hManager.hTextureManager.hSoundManager.hComponents.hKeyboardController.hProjectileComponent.hHealthComponent.hGame.hCollisionHandler.hPowerupComponent.hPlayerComponent.hMap.hStatEffectsComponent.hPopupWindow.hGameObject.h \ No newline at end of file diff --git a/docs/diagrams/load_map_example_sequence.svg b/docs/diagrams/load_map_example_sequence.svg deleted file mode 100644 index 797ac13..0000000 --- a/docs/diagrams/load_map_example_sequence.svg +++ /dev/null @@ -1 +0,0 @@ -MapMapGameGameManagerManagerEntityEntityTileComponentTileComponentgetComponentTypeID<TileComponent>()getComponentTypeID<TileComponent>()getNewComponentTypeID()getNewComponentTypeID()TransformComponentTransformComponentgetComponentTypeID<TransformComponent>()getComponentTypeID<TransformComponent>()Vector2DVector2DgetComponentTypeID<T>()getComponentTypeID<T>()getComponentTypeID<ColliderComponent>()getComponentTypeID<ColliderComponent>()getComponentTypeID<SpriteComponent>()getComponentTypeID<SpriteComponent>()getComponentTypeID<HealthComponent>()getComponentTypeID<HealthComponent>()getComponentTypeID<KeyboardController>()getComponentTypeID<KeyboardController>()getComponentTypeID<StatEffectsComponent>()getComponentTypeID<StatEffectsComponent>()SpriteComponentSpriteComponentTextureManagerTextureManagerColliderComponentColliderComponentStatEffectsComponentStatEffectsComponentloadMap(const char *,int,int)loopaltaddTile(unsigned long,int,int)addEntity()Entity(Manager &)addComponent(int &,int &,const int &,const int &,unsigned long &)TileComponent(int,int,int,int,int)init()addComponent(int &,int &,int &,int &,int &&)TransformComponent(float,float,int,int,int)init()zero()getComponent() constaddComponent(const char *&)SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()getComponent() constaltaddComponent(const char (&)[6])ColliderComponent(const char *)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group) \ No newline at end of file diff --git a/docs/diagrams/sequence.svg b/docs/diagrams/sequence.svg deleted file mode 100644 index d0b5207..0000000 --- a/docs/diagrams/sequence.svg +++ /dev/null @@ -1 +0,0 @@ -main(int,char **)main(int,char **)GameGameTextureManagerTextureManagerManagerManagerMapMapEntityEntityTileComponentTileComponentgetComponentTypeID<TileComponent>()getComponentTypeID<TileComponent>()getNewComponentTypeID()getNewComponentTypeID()TransformComponentTransformComponentgetComponentTypeID<TransformComponent>()getComponentTypeID<TransformComponent>()Vector2DVector2DgetComponentTypeID<T>()getComponentTypeID<T>()getComponentTypeID<ColliderComponent>()getComponentTypeID<ColliderComponent>()getComponentTypeID<SpriteComponent>()getComponentTypeID<SpriteComponent>()getComponentTypeID<HealthComponent>()getComponentTypeID<HealthComponent>()getComponentTypeID<KeyboardController>()getComponentTypeID<KeyboardController>()getComponentTypeID<StatEffectsComponent>()getComponentTypeID<StatEffectsComponent>()SpriteComponentSpriteComponentColliderComponentColliderComponentStatEffectsComponentStatEffectsComponentAssetManagerAssetManagerSoundManagerSoundManagerKeyboardControllerKeyboardControllerHealthComponentHealthComponentComponentComponentCollisionHandlerCollisionHandlerPowerupComponentPowerupComponentgetComponentTypeID<PowerupComponent>()getComponentTypeID<PowerupComponent>()PopupWindowPopupWindowGame()init(const char *,int,int,int,int,bool)loadTexture(const char *)selectCharacters(const char *&,const char *&)looploadTexture(const char *)getGroup(Group)getGroup(Group)getGroup(Group)getGroup(Group)getGroup(Group)Map()alt[loadMap(const char *,int,int)]loopaltaddTile(unsigned long,int,int)addEntity()Entity(Manager &)addComponent(int &,int &,const int &,const int &,unsigned long &)TileComponent(int,int,int,int,int)init()addComponent(int &,int &,int &,int &,int &&)TransformComponent(float,float,int,int,int)init()zero()getComponent() constaddComponent(const char *&)SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()getComponent() constaltaddComponent(const char (&)[6])ColliderComponent(const char *)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)addSoundEffect(std::string,const char *)loadSound(const char *)addSoundEffect(std::string,const char *)loadSound(const char *)setTeam(TeamLabel)addToTeam(Entity *,Team)addComponent(int &&,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char *&,bool &&)SpriteComponent(const char *,bool)playAnimation(AnimationType)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()Vector2D(float,float)addComponent(SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,Vector2D &&)KeyboardController(SDL_Scancode,SDL_Scancode,SDL_Scancode,SDL_Scancode,SDL_Scancode,Vector2D)init()getComponent() constgetComponent() constaddComponent(const char (&)[7],float &&)ColliderComponent(const char *,float)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addComponent(int &&,Direction &&)HealthComponent(int,Direction)init()refreshHearts()loop[getManager()][getGroup(Group)]alt[getTeam()][getTeam()]destroy()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()loopaltcreateHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)createHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()addGroup(Group)addToGroup(Entity *,Group)setTeam(TeamLabel)addToTeam(Entity *,Team)addComponent(int &&,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char *&,bool &&)SpriteComponent(const char *,bool)playAnimation(AnimationType)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()Vector2D(float,float)addComponent(SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,SDL_Scancode &&,Vector2D &&)KeyboardController(SDL_Scancode,SDL_Scancode,SDL_Scancode,SDL_Scancode,SDL_Scancode,Vector2D)init()getComponent() constgetComponent() constaddComponent(const char (&)[6],float &&)ColliderComponent(const char *,float)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addComponent(int &&,Direction &&)HealthComponent(int,Direction)init()refreshHearts()loop[getManager()][getGroup(Group)]alt[getTeam()][getTeam()]destroy()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()loopaltcreateHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)createHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()addGroup(Group)addToGroup(Entity *,Group)looploop[running() const]handleEvents()update()getComponent() constgetComponent() constrefresh()update()loopupdate() constloopupdate()altcalculateSpawnPosition()Vector2D(float,float)looploop[getColliders(const std::initializer_list<GroupLabel> &,const std::initializer_list<TeamLabel> &,bool)]loop[getAll()]alt[getGroupBitSet()]alt[getTeam()]alt[hasComponent() const]getComponent() constVector2D(float,float)calculateType()createPowerup(Vector2D,PowerupType)addEntity()Entity(Manager &)addComponent(float &,float &,int &&,int &&,int &&)TransformComponent(float,float,int,int,int)init()zero()tryaddComponent(char *&&)SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()[std::runtime_error]addComponent(const char (&)[8],float &&)ColliderComponent(const char *,float)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addComponent(PowerupType &)PowerupComponent(PowerupType)init()addGroup(Group)addToGroup(Entity *,Group)loop[getGroup(Group)]alt[getComponent() const][getHealth()]getTeam()setWinner(TeamLabel)render()loopdraw() constloopdraw()loopdraw() constloopdraw()loopdraw() constloopdraw()loopdraw() constloopdraw()loopdraw() constloopdraw()getWinner() constPopupWindow(const char *,const std::string &)renderWinnerPopup(TeamLabel)loophandleWinnerEvents()shouldContinue() constrefreshPlayers()loopdestroy()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()getComponent() constVector2D(float,float)getComponent() constVector2D(float,float)getComponent() constsetHealth(int)refreshHearts()loop[getManager()][getGroup(Group)]alt[getTeam()][getTeam()]destroy()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()loopaltcreateHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)createHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)getComponent() constsetHealth(int)refreshHearts()loop[getManager()][getGroup(Group)]alt[getTeam()][getTeam()]destroy()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()alt[hasComponent() const]getComponent() constremoveCollision()loopaltcreateHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)createHeartComponents(int)getManager()addEntity()Entity(Manager &)addComponent(int &,int &&,int &&)TransformComponent(float,float,int)init()zero()addComponent(const char (&)[17])SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()addGroup(Group)addToGroup(Entity *,Group)getTeam()setTeam(TeamLabel)addToTeam(Entity *,Team)update()getComponent() constgetComponent() constrefresh()update()loopupdate() constloopupdate()altcalculateSpawnPosition()Vector2D(float,float)looploop[getColliders(const std::initializer_list<GroupLabel> &,const std::initializer_list<TeamLabel> &,bool)]loop[getAll()]alt[getGroupBitSet()]alt[getTeam()]alt[hasComponent() const]getComponent() constVector2D(float,float)calculateType()createPowerup(Vector2D,PowerupType)addEntity()Entity(Manager &)addComponent(float &,float &,int &&,int &&,int &&)TransformComponent(float,float,int,int,int)init()zero()tryaddComponent(char *&&)SpriteComponent(const char *)setTexture(const char *)loadTexture(const char *)init()getComponent() constupdate()[std::runtime_error]addComponent(const char (&)[8],float &&)ColliderComponent(const char *,float)init()alt[hasComponent() const]addComponent()TransformComponent()zero()init()zero()StatEffectsComponent()init()getComponent() constupdate()addComponent(PowerupType &)PowerupComponent(PowerupType)init()addGroup(Group)addToGroup(Entity *,Group)loop[getGroup(Group)]alt[getComponent() const][getHealth()]getTeam()setWinner(TeamLabel)clean() \ No newline at end of file diff --git a/docs/docker/Dockerfile b/docs/docker/Dockerfile new file mode 100644 index 0000000..69b7c81 --- /dev/null +++ b/docs/docker/Dockerfile @@ -0,0 +1,13 @@ +FROM alpine:latest + +RUN apk --update --no-cache add doxygen graphviz git + +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +WORKDIR /source + +ENTRYPOINT ["/entrypoint.sh"] + +CMD ["doxygen", "/Doxyfile_copy"] \ No newline at end of file diff --git a/docs/docker/entrypoint.sh b/docs/docker/entrypoint.sh new file mode 100644 index 0000000..748948e --- /dev/null +++ b/docs/docker/entrypoint.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cp /Doxyfile /Doxyfile_copy +echo "OUTPUT_DIRECTORY = /output" >> /Doxyfile_copy + +exec "$@" \ No newline at end of file diff --git a/docs/doxygen-awesome-css b/docs/doxygen-awesome-css new file mode 160000 index 0000000..df88fe4 --- /dev/null +++ b/docs/doxygen-awesome-css @@ -0,0 +1 @@ +Subproject commit df88fe4fdd97714fadfd3ef17de0b4401f804052 diff --git a/docs/header.html b/docs/header.html new file mode 100644 index 0000000..c342193 --- /dev/null +++ b/docs/header.html @@ -0,0 +1,110 @@ + + + + + + + + + + + $projectname: $title + + + $title + + + + + + + + + + + + + + + + + + + + + + + + $treeview + $search + $mathjax + $darkmode + + $extrastylesheet + + + + + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber + +
+ +
$projectbrief
+ +
+
$projectbrief
+
$searchbox
$searchbox
+
+ + \ No newline at end of file diff --git a/engine.sublime-project b/engine.sublime-project new file mode 100644 index 0000000..1466f8e --- /dev/null +++ b/engine.sublime-project @@ -0,0 +1,49 @@ +{ + "folders": + [ + { + "path": "." + } + ], + "settings": + { + "tab_size": 4 + }, + "build_systems": [ + { + "name": "Build engine", + "shell_cmd": "cmake --build build", + "working_dir": "$project_path", + "variants": [ + { + "name": "Debug", + "shell_cmd": "cmake -DCMAKE_BUILD_TYPE=Debug build && cmake --build build", + }, + { + "name": "Release", + "shell_cmd": "cmake -DCMAKE_BUILD_TYPE=Release build && cmake --build build", + }, + ] + }, + { + "name": "Generate CMake", + "shell_cmd": "cmake -S . -B build", + "working_dir": "$project_path", + }, + { + "name": "Doxygen", + "shell_cmd": "xdg-open $project_path/docs/html/index.html", + "working_dir": "$project_path", + "variants": [ + { + "name": "Build image", + "shell_cmd": "docker build -t vego_engine-docker $project_path/docs/docker", + }, + { + "name": "Generate documentation", + "shell_cmd": "docker run --rm -v \"$project_path:/source\" -v \"$project_path/docs:/output\" -v \"$project_path/docs/Doxyfile:/Doxyfile\" vego_engine-docker", + }, + ] + } + ] +} diff --git a/extern/tmxlite b/extern/tmxlite new file mode 160000 index 0000000..fcef1a2 --- /dev/null +++ b/extern/tmxlite @@ -0,0 +1 @@ +Subproject commit fcef1a28ade8406e290d5fd168a8950e6996844f diff --git a/include/CollisionHandler.h b/include/CollisionHandler.h index 41993fb..9802f7d 100644 --- a/include/CollisionHandler.h +++ b/include/CollisionHandler.h @@ -1,5 +1,9 @@ #pragma once +//! \file CollisionHandler.h +//! \file CollisionHandler.cpp +//! \file TransformComponent.cpp + #include "ColliderComponent.h" #include "Constants.h" #include "Entity.h" @@ -17,9 +21,11 @@ class ColliderComponent; class Entity; +// [IntersectionBitSet] constexpr uint8_t DIRECTION_C = 4; using IntersectionBitSet = std::bitset; +// [IntersectionBitSet] class CollisionHandler { @@ -46,6 +52,20 @@ public: std::initializer_list const& groupLabels, std::initializer_list const& excludedEntities = {}); + /*! + * + * \brief Tests entity against all entities with the specified labels for a collision + * \details Tests the given entity against every other entity with the specified labels for intersections between their collison boxes. + * If the primary entity has no ColliderComponent, the equivalent of no collision is returned immediately, other entities are skipped + * if they don't have a ColliderComponent + * \param entity The primary entity to check against. Return values will be relative to this entity + * \param posMod Modifier to apply toposition before checking collisions. + * \param groupLabels Entities need to have at least one listed GroupLabels to get checked against + * \param teamLabels Entities need to have one of the specified TeamLabels to get checked against + * \param negateTeam If set to true, entities will only be checked against if they **don't** have one of the specified TeamLabels + * \see ColliderComponent + * + */ template T getAnyIntersection( Entity* entity, diff --git a/include/Component.h b/include/Component.h index 095b370..566fee9 100644 --- a/include/Component.h +++ b/include/Component.h @@ -9,7 +9,6 @@ public: virtual void init() {} virtual void update() {} - virtual void draw() {} virtual ~Component() = default; }; \ No newline at end of file diff --git a/include/Entity.h b/include/Entity.h index 073b65d..aa067a4 100644 --- a/include/Entity.h +++ b/include/Entity.h @@ -22,29 +22,48 @@ using ComponentBitSet = std::bitset; using GroupBitSet = std::bitset; using ComponentArray = std::array; +/*! + * + * \brief Main class for any object in game, stores associations, labeling and components + * \details The entity class is the primary class each object in the game needs to use. Add components to assign functionality. + * + * \todo More detailed description + * \todo Some functions in entity class are only supposed to be called in specific context, which might be valid uses for `friend` keyword. Example: Entity() should only be called from Manager::addEntity(). Verify each functions intended use/scope. + * + */ class Entity { public: -/*! TODO */ + /*! + * \brief Used for rendering order (last is highest) or retrieving entities of group + * \todo Label used in singular entity shouldn't use plural + * \todo HEARTS are rendered above POWERUPS, missleading order + * \todo PROJECTILE are rendered above POWERUPS, missleading order + * \todo Generalize HEARTS as UI or similar + */ enum class GroupLabel { - MAPTILES, - PLAYERS, - ENEMIES, - COLLIDERS, - PROJECTILE, - HEARTS, - POWERUPS + MAPTILES, //!< Entity using TileComponent + PLAYERS, //!< Primary entity in player controll + ENEMIES, //!< \deprecated All players now grouped as Entity::PLAYERS + COLLIDERS, //!< Fixed collider entity, e.g. a wall + PROJECTILE, //!< \todo Document + HEARTS, //!< \todo Document + POWERUPS //!< \todo Document }; + /*! + * \todo Document + */ explicit Entity(Manager& mManager) : manager(mManager) { }; - void update() const; - void draw() const; + void update() const; //!< Call each frame to update all components - bool isActive() const { return this->active; } + bool isActive() const { return this->active; } //!< \sa destroy() + //! Mark for destruction for Manager::refresh() and disables collision + //! \sa ColliderComponent void destroy() { this->active = false; if (this->hasComponent()) { @@ -52,18 +71,23 @@ public: } } - bool hasGroup(Group mGroup); - void addGroup(Group mGroup); - void delGroup(Group mGroup); + bool hasGroup(Group mGroup); //!< \sa GroupLabel + void addGroup(Group mGroup); //!< \sa GroupLabel + void delGroup(Group mGroup); //!< \sa GroupLabel + //! \returns bitset with true on position GroupLabel if the entity belongs to group + //! \sa GroupLabel std::bitset getGroupBitSet(); + //! \sa Manager Manager& getManager() { return manager; }; - template bool hasComponent() const + template bool hasComponent() const //! \sa Component { return componentBitSet[getComponentTypeID()]; } + //! \brief Adds specified type as component and calls Component::init() + //! \param mArgs Constructor arguments of component template T& addComponent(TArgs&&...mArgs) { T* c(new T(std::forward(mArgs)...)); @@ -78,7 +102,7 @@ public: return *c; }; - template T& getComponent() const + template T& getComponent() const //! \returns Component of type T { auto ptr(componentArray[getComponentTypeID()]); return *static_cast(ptr); diff --git a/include/GameInternal.h b/include/GameInternal.h index e300f2f..44cec2d 100644 --- a/include/GameInternal.h +++ b/include/GameInternal.h @@ -9,6 +9,7 @@ #include "Manager.h" #include "Vector2D.h" #include "Entity.h" +#include "RenderManager.h" typedef std::function gamefunction; @@ -42,8 +43,8 @@ public: /* static */ TextureManager* textureManager; /* static */ SoundManager* soundManager; - // moved globals Manager manager; + RenderManager renderManager; Map* map; // game specific, might not be needed for all types of games std::vector& tiles; diff --git a/include/GameObject.h b/include/GameObject.h deleted file mode 100644 index 1c209ae..0000000 --- a/include/GameObject.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -class GameObject -{ -public: - GameObject(const char* texturesheet, int x, int y); - ~GameObject() = default; - - void update(); - void render(); - -private: - int xPos; - int yPos; - - SDL_Texture* objTexture; - SDL_Rect srcRect; - SDL_Rect destRect; -}; - diff --git a/include/Manager.h b/include/Manager.h index 3282d9d..8b9ceb3 100644 --- a/include/Manager.h +++ b/include/Manager.h @@ -10,21 +10,31 @@ #include "Entity.h" class GameInternal; +/*! + * + * \brief Is responsible for managing all entities + * \details The manager class handles update and draw calls collectively for all entities, and provides functionality to get all or a subset of all entities + * \sa Entity + * \sa Entity::GroupLabel + * \sa Entity::TeamLabel + * + */ class Manager { public: Manager(GameInternal* game) : game(game) {}; - void update(); - void draw(); + void update(); //!< \sa Entity::update() + //! Disables all functionality of entities marked for destruction + //! \sa Entity::destroy() void refresh(); - void addToGroup(Entity* mEntity, Group mGroup); - std::vector& getGroup(Group mGroup); + void addToGroup(Entity* mEntity, Group mGroup); //!< \todo `friend` to Entity + std::vector& getGroup(Group mGroup); //!< \returns std::vector containing all entities in group Entity::GroupLabel - std::vector getAll(); + std::vector getAll(); //!< \returns std::vector containing all entities - Entity& addEntity(); + Entity& addEntity(); //!< Creates and returns a new, empty entity GameInternal* getGame() { return this->game; }; diff --git a/include/Map.h b/include/Map.h index 32184be..5e96186 100644 --- a/include/Map.h +++ b/include/Map.h @@ -1,27 +1,52 @@ #pragma once -#include +#include +#include #include -#include +#include + +#include +#include +#include +#include class GameInternal; class Map { public: - Map() = default; - ~Map() = default; - - // code comment below is a test for doxygen - do not remove - /*! - * - * \brief - * This loads a map - * - * \param path The path to the map file - * \return Boolean for success - * + * \brief Loads a .tmx map + * \details Loads a `.tmx` file and extracts all relevant data. Any entities (including tiles) are only spawned once + * \param path Path to the `.tmx` map file + * \sa Map::generateTiles() */ - static void loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map>* textureDict /* backreference */); - static void addTile(unsigned long id, int x, int y, GameInternal* game, const std::map>* textureDict); -}; + Map(const char* path); + void generateTiles(); //!< Generates the map based on the loaded definition +private: + // struct required for initialisation + struct MapData { + const std::vector* tileSets; + const std::vector* mapLayers; + const tmx::Vector2u* mapSize; + const tmx::Vector2u* mapTileSize; + const std::vector* texturePaths; + }; + + struct TileSetData { + std::string texturePath{}; + tmx::Vector2i textureSize; + uint32_t tileCount{}; + tmx::Vector2u tileCount2D; + uint32_t firstGID{}; + }; + + tmx::Map map; + Map::MapData mapData; + std::vector> tileConstructors; + + void loadTileLayer(const tmx::TileLayer& layer); + static void addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision); + + template + static std::optional getLayerProperty(const std::vector& properties, std::string propertyName) { return std::nullopt; }; +}; \ No newline at end of file diff --git a/include/RenderManager.h b/include/RenderManager.h new file mode 100644 index 0000000..86aa614 --- /dev/null +++ b/include/RenderManager.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "RenderObject.h" + +class RenderManager { +public: + RenderManager() {}; + + /* + * Remove an object from the list of objects to be rendered + * \param renderObject The object to be removed + * \sa RenderObject + */ + void remove(RenderObject* obj); + /* + * Add an object to be rendered + * \param renderObject The object to be rendered + * \sa RenderObject + */ + void add(RenderObject* obj); + + void renderAll(); //!< Render all objects. If the list has been modified, sorts it based on z-index first + +private: + std::vector renderObjects; + bool isSorted; +}; \ No newline at end of file diff --git a/include/RenderObject.h b/include/RenderObject.h new file mode 100644 index 0000000..ba4b929 --- /dev/null +++ b/include/RenderObject.h @@ -0,0 +1,27 @@ +#pragma once + +class RenderManager; + +class RenderObject +{ +public: + virtual void draw() = 0; + + RenderObject(int zIndex, RenderManager& renderManager); + ~RenderObject(); + + int getZIndex() { return this->zIndex; }; + + //! Comparitor to compare two ptr based on z-index + struct ZIndexComparator { + bool operator()(RenderObject const *lhs, RenderObject const *rhs ) const { + return lhs->zIndex < rhs->zIndex; + } + }; + +private: + int zIndex = 0; + +protected: + RenderManager& renderManager; +}; \ No newline at end of file diff --git a/include/SpriteComponent.h b/include/SpriteComponent.h index f887097..5cc3b53 100644 --- a/include/SpriteComponent.h +++ b/include/SpriteComponent.h @@ -4,15 +4,16 @@ #include #include #include -#include +#include "TextureEnumBase.h" #include "AnimationHandler.h" #include "Component.h" #include "Direction.h" +#include "RenderObject.h" class TransformComponent; -class SpriteComponent : public Component +class SpriteComponent : public Component, public RenderObject { public: int animationIndex = 0; @@ -31,14 +32,18 @@ private: uint8_t speed = 100; bool flipped = false; + int textureXOffset; + int textureYOffset; + public: - SpriteComponent() = default; - SpriteComponent(Textures textureEnum); + SpriteComponent(Textures texture, int zIndex); + SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex); SpriteComponent( - Textures textureEnum, + Textures texture, bool isAnimated, std::map>* animationList, - std::string defaultAnimation); + std::string defaultAnimation, + int zIndex); ~SpriteComponent(); void setTexture(Textures texture); diff --git a/include/TransformComponent.h b/include/TransformComponent.h index bfe3160..7a15aa4 100644 --- a/include/TransformComponent.h +++ b/include/TransformComponent.h @@ -24,6 +24,7 @@ public: TransformComponent(float x, float y, int w, int h, int scale); void init() override; + /*! TODO: document usage of collision handler */ void update() override; void setPositionAfterCollision(Vector2D& positionChange); void modifySpeed(int8_t modifier); diff --git a/include/VEGO.h b/include/VEGO.h new file mode 100644 index 0000000..550fd61 --- /dev/null +++ b/include/VEGO.h @@ -0,0 +1,9 @@ +#include "GameInternal.h" + +namespace vego { + extern GameInternal* game; +} + +inline GameInternal& VEGO_Game() { + return *vego::game; +}; \ No newline at end of file diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 41c3889..f90b6d1 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -48,7 +48,7 @@ void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, auto& projectile(man->addEntity()); projectile.addComponent(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects - projectile.addComponent(textureEnum); + projectile.addComponent(textureEnum, 4); projectile.addComponent(range, speed, velocity, owner); projectile.addComponent("projectile", 0.6f); projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE); @@ -60,7 +60,7 @@ void AssetManager::createPowerup(Vector2D pos, std::function pic powerups.addComponent(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects try { - powerups.addComponent(texture); + powerups.addComponent(texture, 3); } catch (std::runtime_error e) { std::cout << e.what() << std::endl; diff --git a/src/CollisionHandler.cpp b/src/CollisionHandler.cpp index 3e0eaec..5477c6c 100644 --- a/src/CollisionHandler.cpp +++ b/src/CollisionHandler.cpp @@ -109,6 +109,17 @@ std::vector CollisionHandler::getColliders( return colliders; } +/*! + * + * \details Refer to getAnyIntersection() for more details + * \return A bitset of intersections, describing the directions of intersection. Position `Direction` in bitset true if edge in that direction collides + * \see Direction + * \see IntersectionBitSet + * \snippet CollisionHandler.h IntersectionBitSet + * \details Example usage for IntersectionBitSet (TransformComponent::update()): + * \snippet{trimleft} TransformComponent.cpp getAnyIntersection example code + * + */ template<> IntersectionBitSet CollisionHandler::getAnyIntersection( Entity* entity, @@ -116,6 +127,7 @@ IntersectionBitSet CollisionHandler::getAnyIntersection( std::initializer_list const& groupLabels, std::initializer_list const& excludedEntities) { + if (!entity->hasComponent()) return std::bitset(); IntersectionBitSet intersections; for (auto& collider : getColliders(groupLabels, excludedEntities)) { intersections |= getIntersection(entity, collider->entity, posMod); @@ -123,6 +135,13 @@ IntersectionBitSet CollisionHandler::getAnyIntersection( return intersections; }; +/*! + * + * \details Refer to getAnyIntersection() for more details + * \return The first entity with collision found + * \see Entity + * + */ template<> Entity* CollisionHandler::getAnyIntersection( Entity* entity, @@ -130,6 +149,7 @@ Entity* CollisionHandler::getAnyIntersection( std::initializer_list const& groupLabels, std::initializer_list const& excludedEntities) { + if (!entity->hasComponent()) return nullptr; for (auto& collider : getColliders(groupLabels, excludedEntities)) { SDL_Rect rect = entity->getComponent().collider + posMod; if (SDL_HasIntersection(&rect, &collider->collider)) { @@ -137,4 +157,27 @@ Entity* CollisionHandler::getAnyIntersection( } } return nullptr; +}; + +/*! + * + * \details Refer to getAnyIntersection() for more details + * \return True if any collision was found, otherwise false + * + */ +template<> +bool CollisionHandler::getAnyIntersection( + Entity* entity, + Vector2D posMod, + std::initializer_list const& groupLabels, + std::initializer_list const& excludedEntities) +{ + if (!entity->hasComponent()) return false; + for (auto& collider : getColliders(groupLabels, excludedEntities)) { + SDL_Rect rect = entity->getComponent().collider + posMod; + if (SDL_HasIntersection(&rect, &collider->collider)) { + return true; + } + } + return false; }; \ No newline at end of file diff --git a/src/Entity.cpp b/src/Entity.cpp index 4710983..60455c1 100644 --- a/src/Entity.cpp +++ b/src/Entity.cpp @@ -9,11 +9,6 @@ void Entity::update() const for (auto const& c : components) c->update(); } -void Entity::draw() const -{ - for (auto const& c : components) c->draw(); -} - bool Entity::hasGroup(Group mGroup) { return groupBitSet[mGroup]; diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 29d1622..0ef8c69 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -4,6 +4,8 @@ #include "CollisionHandler.h" #include "AssetManager.h" +#include "RenderManager.h" +#include "SDL_mixer.h" #include "SoundManager.h" #include "TileComponent.h" #include "Direction.h" @@ -18,6 +20,7 @@ GameInternal::GameInternal() : manager(this), + renderManager(), tiles(manager.getGroup((size_t)Entity::GroupLabel::MAPTILES)), players(manager.getGroup((size_t)Entity::GroupLabel::PLAYERS)), projectiles(manager.getGroup((size_t)Entity::GroupLabel::PROJECTILE)), @@ -60,11 +63,11 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he return; } - SDL_Surface* icon = SDL_LoadBMP("assets/iconImage.bmp"); - if(!icon) + // bad + SDL_Surface* icon; + if((icon = SDL_LoadBMP("assets/iconImage.bmp"))) { - std::cout << "ERROR: Couldn't create icon!" << std::endl; - return; + SDL_SetWindowIcon(window, icon); } SDL_SetWindowIcon(window, icon); @@ -78,13 +81,6 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he } SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); - - //SDL_Texture* backgroundTexture = GameInternal::textureManager->loadTexture("assets/startscreen.png"); - - SDL_RenderClear(renderer); - //SDL_RenderCopy(renderer, backgroundTexture, NULL, NULL); - SDL_RenderPresent(renderer); - if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { std::cout << "ERROR: Mixer couldnt be initialized! " << SDL_GetError() << std::endl; @@ -95,45 +91,6 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he Mix_Volume(-1, MIX_MAX_VOLUME); Mix_AllocateChannels(16); - //SDL_Event event; - bool hasQuit = false; - - while (!hasQuit) - { - SDL_PollEvent(&event); - - if (event.type == SDL_QUIT) - { - hasQuit = true; - break; - } - - if (event.type == SDL_KEYDOWN) - { - if (event.key.keysym.scancode == SDL_SCANCODE_RETURN) - { - std::cout << "Enter pressed > Game start..." << std::endl; - break; - } - - if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) - { - std::cout << "Escape pressed > Game quit..." << std::endl; - hasQuit = true; - } - } - } - - if (hasQuit) - { - this->setRunning(false); - return; - } - - if (this->isRunning() == false) return; - - map = new Map(); - // loading sounds // assets->addSoundEffect("throw_egg", "assets/sound/throw_egg.wav"); // assets->addSoundEffect("steps", "assets/sound/steps.wav"); @@ -170,21 +127,7 @@ void GameInternal::update() void GameInternal::render() { SDL_RenderClear(renderer); - for (auto& t : tiles) - t->draw(); - - for (auto& p : powerups) - p->draw(); - - for (auto& p : players) - p->draw(); - - for (auto& p : projectiles) - p->draw(); - - for (auto& h : hearts) - h->draw(); - + this->renderManager.renderAll(); SDL_RenderPresent(renderer); } diff --git a/src/GameObject.cpp b/src/GameObject.cpp deleted file mode 100644 index 24a4665..0000000 --- a/src/GameObject.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "GameObject.h" - -#include "SDL_error.h" -#include "TextureManager.h" -#include "GameInternal.h" - -GameObject::GameObject(const char* texturesheet, int x, int y) -{ - // seems not to be used, and was using deprecated functionality - SDL_SetError("GameObject not implemented"); - - this->xPos = x; - this->yPos = y; -} - -void GameObject::update() -{ - xPos++; - yPos++; - - srcRect.h = 32; - srcRect.w = 32; - srcRect.x = 0; - srcRect.y = 0; - - destRect.h = srcRect.h *2; - destRect.w = srcRect.w *2; - destRect.x = xPos; - destRect.y = yPos; -} - -void GameObject::render() -{ - SDL_SetError("GameObject not implemented"); - // SDL_RenderCopy(Game::renderer, objTexture, &srcRect, &destRect); -} diff --git a/src/Manager.cpp b/src/Manager.cpp index 50cb5ea..09eea97 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -6,11 +6,6 @@ #include "Constants.h" #include "Entity.h" -void Manager::draw() -{ - for (auto& e : entities) e->draw(); -} - void Manager::refresh() { for (auto i(0u); i < MAX_GROUPS; i++) diff --git a/src/Map.cpp b/src/Map.cpp index 796002d..6b72837 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -1,68 +1,186 @@ #include "Map.h" +#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include "Constants.h" +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ColliderComponent.h" #include "GameInternal.h" -#include "SDL_error.h" +#include "SpriteComponent.h" +#include "TextureManager.h" #include "TileComponent.h" +#include "VEGO.h" -void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map>* textureDict /* backreference */) -{ - std::string tileIDstr; - char singleChar = 0; - std::ifstream mapFile; - mapFile.open(path); - if (!mapFile.is_open()) { - SDL_SetError("Error loading map: Couldn't open map file!"); - std::cout << "ERROR: Map couldnt be loaded! " << SDL_GetError() << std::endl; - SDL_ClearError(); - } +template<> std::optional Map::getLayerProperty(const std::vector& properties, std::string propertyName) { + auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { + return property.getName().compare(propertyName) == 0; + }); - int x = 0, y = 0; // needed outside for-loop for error handling - for (; !mapFile.eof(); mapFile.get(singleChar)) - { - if (singleChar == ',' || singleChar == '\n') { - if (tileIDstr.empty()) - continue; - Map::addTile(std::stoi(tileIDstr), x * TILE_SIZE, y * TILE_SIZE, game, textureDict); - tileIDstr.clear(); - x++; - if (singleChar == '\n') { - if (x != sizeX) { - SDL_SetError("Error loading map: specified x size doesn't match map file!"); - std::cout << "ERROR: Map couldnt be loaded! " << SDL_GetError() << std::endl; - SDL_ClearError(); - } - x = 0; - y++; - continue; - } - continue; - } - if (!std::isdigit(singleChar)) continue; - tileIDstr += singleChar; - } - if (y != sizeY) { - SDL_SetError("Error loading map: specified y size doesn't match map file!"); - std::cout << "ERROR: Map couldnt be loaded! " << SDL_GetError() << std::endl; - SDL_ClearError(); - } + if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Boolean) { + return zIndexIterator->getBoolValue(); + } - mapFile.close(); + return std::nullopt; } -void Map::addTile(unsigned long id, int x, int y, GameInternal* game, const std::map>* textureDict) // tile entity +template<> std::optional Map::getLayerProperty(const std::vector& properties, std::string propertyName) { - auto& tile(game->manager.addEntity()); - tile.addComponent(x, y, TILE_SIZE, TILE_SIZE, id, textureDict); - - if(tile.getComponent().hasCollision()) - tile.addComponent(tile.getComponent().getName().data()); + auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { + return property.getName().compare(propertyName) == 0; + }); - tile.addGroup((size_t)Entity::GroupLabel::MAPTILES); + if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Int) { + return zIndexIterator->getIntValue(); + } + + return std::nullopt; +} + +Map::Map(const char* path) +{ + if (!this->map.load(path)) { + // TODO: log to console + // TODO: error handling + } + + std::vector texturePaths = {}; + + for (const auto& tileSet : map.getTilesets()) { + texturePaths.emplace_back(tileSet.getImagePath()); + } + + this->mapData = { + &map.getTilesets(), + &map.getLayers(), + &map.getTileCount(), + &map.getTileSize(), + &texturePaths + }; + + + for (auto& layer : *this->mapData.mapLayers) { + + if (layer->getType() == tmx::Layer::Type::Tile) { + loadTileLayer(layer->getLayerAs()); + continue; + } + if (layer->getType() == tmx::Layer::Type::Object) { + // spawn objects + continue; + } + } +} + +void Map::loadTileLayer(const tmx::TileLayer& layer) +{ + const std::vector& properties = layer.getProperties(); + int zIndex = getLayerProperty(properties, "zIndex").value_or(0); + bool collision = getLayerProperty(properties, "collision").value_or(false); + + const auto& tiles = layer.getTiles(); + + // for each tile set + auto tileConstructorRange = std::views::iota(0) + | std::views::take(this->mapData.tileSets->size()) + // return the tile set metadata + | std::views::transform([&](uint16_t i) { + const char* texturePath = this->mapData.texturePaths->at(i).c_str(); + + tmx::Vector2i textureSize; + SDL_QueryTexture( + VEGO_Game().textureManager->loadTexture(texturePath), + nullptr, + nullptr, + &(textureSize.x), + &(textureSize.y) + ); + + tmx::Vector2u tileCount2D = { textureSize.x / this->mapData.mapTileSize->x, textureSize.y / this->mapData.mapTileSize->y }; + + uint32_t tileCount = this->mapData.tileSets->at(i).getTileCount(); + uint32_t firstGID = this->mapData.tileSets->at(i).getFirstGID(); + + return TileSetData { texturePath, textureSize, tileCount, tileCount2D, firstGID }; + }) + | std::views::transform([=, this](const TileSetData& data) { + // for each tile on the tile set + return std::views::iota(0) + | std::views::take(this->mapData.mapSize->x * this->mapData.mapSize->y) + // only take tiles that are on the ID range of the tile set + | std::views::filter([=](uint16_t idx) { + return + idx < tiles.size() + && tiles[idx].ID >= data.firstGID + && tiles[idx].ID < (data.firstGID + data.tileCount); + }) + // extract tile data + | std::views::transform([=, this](uint16_t idx) { + const auto x = idx % this->mapData.mapSize->x; + const auto y = idx / this->mapData.mapSize->x; + + const auto idIndex = (tiles[idx].ID - data.firstGID); + + uint32_t u = idIndex % data.tileCount2D.x; + uint32_t v = idIndex / data.tileCount2D.y; + u *= this->mapData.mapTileSize->x; // TODO: we should be using the tile set size, as this may be different from the map's grid size + v *= this->mapData.mapTileSize->y; + + // normalise the UV + u /= data.textureSize.x; + v /= data.textureSize.y; + + // vert pos + const float tilePosX = static_cast(x) * this->mapData.mapTileSize->x; + const float tilePosY = (static_cast(y) * this->mapData.mapTileSize->y); + + // return tile data as a function to spawn said tile + return std::function( + [tilePosX, tilePosY, capture0 = *this->mapData.mapTileSize, u, v, zIndex, capture1 = data.texturePath, collision] { + Map::addTile(tilePosX, tilePosY, capture0, u, v, zIndex, capture1, collision); + } + ); + }); + }) + // 2D view to 1D vector; might be better keep as view with scene management + | std::views::join + | std::ranges::to(); + + this->tileConstructors.insert(this->tileConstructors.end(), tileConstructorRange.begin(), tileConstructorRange.end()); +} + +void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int v, int zIndex, std::string texturePath, bool hasCollision) +{ + auto& tile(VEGO_Game().manager.addEntity()); + + tile.addComponent(x, y, mapTileSize.x, mapTileSize.y, 1); + tile.addComponent(texturePath.c_str(), v, u, zIndex); // why does uv need to be reversed? + + if (hasCollision) { + // tag currently does not have a clear purposes, TODO: figure out appropriate tag name + tile.addComponent("hello I am a collider of a tile!"); + tile.addGroup((size_t)Entity::GroupLabel::MAPTILES); + } +} + +void Map::generateTiles() +{ + std::ranges::for_each(this->tileConstructors, [](auto& function) { + function(); + }); } \ No newline at end of file diff --git a/src/RenderManager.cpp b/src/RenderManager.cpp new file mode 100644 index 0000000..e2e82af --- /dev/null +++ b/src/RenderManager.cpp @@ -0,0 +1,24 @@ +#include "RenderManager.h" +#include "RenderObject.h" +#include + +void RenderManager::renderAll() +{ + if (!this->isSorted) { + std::ranges::sort(this->renderObjects, RenderObject::ZIndexComparator()); + } + for (RenderObject* obj : this->renderObjects) { + obj->draw(); + } +} + +void RenderManager::add(RenderObject* renderObject) { + this->renderObjects.emplace_back(renderObject); + this->isSorted = false; +} + +void RenderManager::remove(RenderObject* renderObject) +{ + this->renderObjects.erase(std::remove(this->renderObjects.begin(), this->renderObjects.end(), renderObject), this->renderObjects.end()); + this->isSorted = false; +} \ No newline at end of file diff --git a/src/RenderObject.cpp b/src/RenderObject.cpp new file mode 100644 index 0000000..5c21ee9 --- /dev/null +++ b/src/RenderObject.cpp @@ -0,0 +1,10 @@ +#include "RenderObject.h" +#include "RenderManager.h" + +RenderObject::RenderObject(int zIndex, RenderManager& renderManager) : zIndex(zIndex), renderManager(renderManager) { + renderManager.add(this); +} + +RenderObject::~RenderObject() { + this->renderManager.remove(this); +} \ No newline at end of file diff --git a/src/SpriteComponent.cpp b/src/SpriteComponent.cpp index d7728ab..36f6766 100644 --- a/src/SpriteComponent.cpp +++ b/src/SpriteComponent.cpp @@ -6,22 +6,31 @@ #include "AnimationHandler.h" #include "Direction.h" +#include "ProjectileComponent.h" +#include "RenderObject.h" #include "TextureManager.h" #include "Entity.h" #include "TransformComponent.h" #include "GameInternal.h" #include "Manager.h" +#include "VEGO.h" -SpriteComponent::SpriteComponent(Textures textureEnum) +SpriteComponent::SpriteComponent(Textures texture, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0) { - this->textureEnum = textureEnum; + this->textureEnum = texture; +} + +SpriteComponent::SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) +{ + this->textureEnum = texture; } SpriteComponent::SpriteComponent( - Textures textureEnum, + Textures texture, bool isAnimated, std::map>* animationMap, - std::string defaultAnimation) + std::string defaultAnimation, + int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0) { animated = isAnimated; @@ -29,14 +38,14 @@ SpriteComponent::SpriteComponent( playAnimation(defaultAnimation); - this->textureEnum = textureEnum; + this->textureEnum = texture; } SpriteComponent::~SpriteComponent() {} void SpriteComponent::setTexture(Textures texture) { - this->texture = this->entity->getManager().getGame()->textureManager->loadTexture(texture); + this->texture = VEGO_Game().textureManager->loadTexture(texture); } void SpriteComponent::init() @@ -45,20 +54,22 @@ void SpriteComponent::init() this->transform = &entity->getComponent(); - this->srcRect.x = this->srcRect.y = 0; this->srcRect.w = transform->width; this->srcRect.h = transform->height; + this->srcRect.x = this->textureXOffset * this->srcRect.w; + this->srcRect.y = this->textureYOffset * this->srcRect.h;; this->update(); } void SpriteComponent::update() { + // This code is not compatible for animated tiles if (animated) { srcRect.x = srcRect.w * static_cast((SDL_GetTicks() / speed) % frames); - } - srcRect.y = animationIndex * transform->height; + srcRect.y = animationIndex * transform->height; + } this->destRect.x = this->transform->position.x; this->destRect.y = this->transform->position.y; @@ -68,7 +79,7 @@ void SpriteComponent::update() void SpriteComponent::draw() { - this->entity->getManager().getGame()->textureManager->draw(this->entity->getManager().getGame()->renderer, this->texture, this->srcRect, this->destRect, this->animated && this->flipped); + this->entity->getManager().getGame()->textureManager->draw(VEGO_Game().renderer, this->texture, this->srcRect, this->destRect, this->animated && this->flipped); } void SpriteComponent::playAnimation(std::string type) diff --git a/src/TileComponent.cpp b/src/TileComponent.cpp index 3664e19..5f36e2f 100644 --- a/src/TileComponent.cpp +++ b/src/TileComponent.cpp @@ -32,7 +32,7 @@ void TileComponent::init() this->entity->addComponent(this->tileRect.x, this->tileRect.y, this->tileRect.w, this->tileRect.h, 1); this->transform = &entity->getComponent(); - this->entity->addComponent(this->texture); + this->entity->addComponent(this->texture, 0); this->sprite = &entity->getComponent(); } diff --git a/src/TransformComponent.cpp b/src/TransformComponent.cpp index 4baf67e..e8e299b 100644 --- a/src/TransformComponent.cpp +++ b/src/TransformComponent.cpp @@ -72,7 +72,8 @@ void TransformComponent::modifySpeed(int8_t modifier) void TransformComponent::setPositionAfterCollision(Vector2D& positionChange) { - std::initializer_list colliders = { Entity::GroupLabel::MAPTILES, Entity::GroupLabel::COLLIDERS }; + std::initializer_list colliders = { Entity::GroupLabel::MAPTILES, Entity::GroupLabel::COLLIDERS }; + // [getAnyIntersection example code] IntersectionBitSet intersections = (CollisionHandler::getIntersectionWithBounds(entity, Vector2D(positionChange.x, 0)) | (this->entity->getManager() @@ -88,4 +89,5 @@ void TransformComponent::setPositionAfterCollision(Vector2D& positionChange) if (intersections.test((size_t)Direction::UP) || intersections.test((size_t)Direction::DOWN)) positionChange.y = 0; + // [getAnyIntersection example code] } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index cc8be77..da7f8a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,12 @@ #include #include +#include "VEGO.h" #include "Entity.h" #include "GameInternal.h" #include "Constants.h" -GameInternal* game = nullptr; +GameInternal* vego::game = nullptr; int main(int argc, char* argv[]) { @@ -17,15 +18,15 @@ int main(int argc, char* argv[]) Uint32 frameStart; int frameTime; - game = new GameInternal(); + vego::game = new GameInternal(); - game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false); - while (game->isRunning()) { + vego::game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false); + while (vego::game->isRunning()) { frameStart = SDL_GetTicks(); - game->handleEvents(); - game->update(); - game->render(); + vego::game->handleEvents(); + vego::game->update(); + vego::game->render(); frameTime = SDL_GetTicks() - frameStart; @@ -34,7 +35,7 @@ int main(int argc, char* argv[]) } } - game->clean(); + vego::game->clean(); return 0; } \ No newline at end of file