From 9b9d38b7df00573f2ef904bd46222151f27c6ef4 Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Wed, 22 Nov 2023 22:36:17 +0100 Subject: [PATCH 01/14] [#151]: Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index be61dc46..1b820fed 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ # Looper Looper is a game engine with an integrated editor and a 2D type game with a level editor, all written in modern C++20. It uses Vulkan for rendering and ImGui/glfw3 for UI and window/input handling. The project is compatible with Ubuntu and Windows. +For past and future video logs, please visit my [Youtube](https://www.youtube.com/watch?v=Qh-vOKMPQGQ&list=PLRLVUsGGaSH-s0A_2w_eo2LQEfTZuqi7Y) channel. [![Watch the video](https://raw.githubusercontent.com/wiki/JacobDomagala/Looper/Looper_github.gif)](https://www.youtube.com/watch?v=Qh-vOKMPQGQ) From b2fdf40e4de50ce29b19900cafaa7116b52b7153 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 24 Nov 2023 12:34:08 +0100 Subject: [PATCH 02/14] [#151]: Use newer version of conan --- .github/workflows/code_quality.yml | 5 +++-- .github/workflows/ubuntu.yml | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index 24a150fd..3085a731 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -18,8 +18,9 @@ jobs: echo "#!/bin/bash root_dir=\${1} build_dir=\${2} - pip install conan==1.59.0 --break-system-packages - conan install \$root_dir --install-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install + pip install conan --break-system-packages + conan profile detect + conan install \$root_dir --output-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install wget https://sdk.lunarg.com/sdk/download/1.3.216.0/linux/vulkansdk-linux-x86_64-1.3.216.0.tar.gz tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/dependencies source \$root_dir/dependencies/1.3.216.0/setup-env.sh" > init_script.sh diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 36af8164..e98b7eb2 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -28,7 +28,7 @@ jobs: libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-dri3-dev \ libxcb-util-dev libxcb-cursor-dev - pip install conan==1.59.0 + pip install conan wget https://sdk.lunarg.com/sdk/download/$SDK_VERSION/linux/vulkansdk-linux-x86_64-$SDK_VERSION.tar.gz tar xf vulkansdk-linux-x86_64-$SDK_VERSION.tar.gz @@ -46,8 +46,7 @@ jobs: working-directory: ${{runner.workspace}}/build run: | # Use newer ABI - conan profile new default --detect - conan profile update settings.compiler.libcxx=libstdc++11 default + conan profile detect conan install $GITHUB_WORKSPACE --output-folder=build --build=missing --settings=build_type=$BUILD_TYPE - name: Run CMake From a15be59d1092d146bea39fe1774b19d7d8f61a4d Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 24 Nov 2023 14:49:48 +0100 Subject: [PATCH 03/14] [#151]: Update stb conan version --- conanfile.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.txt b/conanfile.txt index 103b43f7..1c83cd0a 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -4,7 +4,7 @@ fmt/10.1.0 glfw/3.3.8 imgui/1.89.9 -stb/20200203 +stb/cci.20230920 glm/0.9.9.8 nlohmann_json/3.11.2 From a3668947d033e5bf8609b0f7d03d600a9039445f Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 24 Nov 2023 14:52:38 +0100 Subject: [PATCH 04/14] [#151]: Update conan version for Windows --- .github/workflows/windows.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e5ed5579..58dfe420 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -39,8 +39,6 @@ jobs: - name: Install Conan id: conan uses: turtlebrowser/get-conan@main - with: - version: 1.59.0 - name: Cache Conan packages id: cache-conan From 9ed629a2f58e378e7de69d86ba761dd0c0c9a741 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 24 Nov 2023 14:56:18 +0100 Subject: [PATCH 05/14] [#151]: Remove cmake generator --- .github/workflows/code_quality.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- .github/workflows/windows.yml | 2 +- conanfile.txt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index 3085a731..92598fc1 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -20,7 +20,7 @@ jobs: build_dir=\${2} pip install conan --break-system-packages conan profile detect - conan install \$root_dir --output-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install + conan install \$root_dir --install-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install wget https://sdk.lunarg.com/sdk/download/1.3.216.0/linux/vulkansdk-linux-x86_64-1.3.216.0.tar.gz tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/dependencies source \$root_dir/dependencies/1.3.216.0/setup-env.sh" > init_script.sh diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e98b7eb2..20d859b3 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -47,7 +47,7 @@ jobs: run: | # Use newer ABI conan profile detect - conan install $GITHUB_WORKSPACE --output-folder=build --build=missing --settings=build_type=$BUILD_TYPE + conan install $GITHUB_WORKSPACE --install-folder=build --build=missing --settings=build_type=$BUILD_TYPE - name: Run CMake shell: bash diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 58dfe420..c809fe37 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -51,7 +51,7 @@ jobs: working-directory: ${{runner.workspace}}/build run: | conan profile detect - conan install $env:GITHUB_WORKSPACE --output-folder=build --build=missing --settings=build_type=$env:BUILD_TYPE + conan install $env:GITHUB_WORKSPACE --install-folder=build --build=missing --settings=build_type=$env:BUILD_TYPE - name: Configure CMake and build working-directory: ${{runner.workspace}}/build diff --git a/conanfile.txt b/conanfile.txt index 1c83cd0a..d7688094 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -9,5 +9,5 @@ glm/0.9.9.8 nlohmann_json/3.11.2 [generators] -cmake_find_package_multi -cmake +CMakeToolchain +CMakeDeps From eb6992d75f9f58bd12a5e91d72e3ce7bfc1e29c9 Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Sat, 25 Nov 2023 23:11:38 +0100 Subject: [PATCH 06/14] [#151]: Fix CMakeLists file --- .gitignore | 3 ++- engine/CMakeLists.txt | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 505000af..63a2e0bf 100644 --- a/.gitignore +++ b/.gitignore @@ -318,4 +318,5 @@ dependencies/glfw/glfw* *imgui.ini /CMakeSettings.json *.cache/* -compile_commands.json \ No newline at end of file +compile_commands.json +CMakeUserPresets.json diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index e982e878..beb361b6 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -15,11 +15,14 @@ target_include_directories(${MODULE_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" " # Load all TPLs -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGETS) find_package(Vulkan REQUIRED) +find_package(fmt REQUIRED) +find_package(glfw3 REQUIRED) +find_package(imgui REQUIRED) +find_package(glm REQUIRED) +find_package(nlohmann_json REQUIRED) -target_link_libraries_system(${MODULE_NAME} PUBLIC stb_image CONAN_PKG::fmt CONAN_PKG::glfw CONAN_PKG::imgui CONAN_PKG::glm CONAN_PKG::nlohmann_json) +target_link_libraries_system(${MODULE_NAME} PUBLIC stb_image fmt::fmt glfw imgui::imgui glm::glm nlohmann_json::nlohmann_json) target_link_libraries(${MODULE_NAME} PUBLIC project_warnings project_options Vulkan::Vulkan) target_compile_features(${MODULE_NAME} PRIVATE cxx_std_20) From b3679a7daa92c14476669fb67b83d45fe388b895 Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Sat, 25 Nov 2023 23:18:11 +0100 Subject: [PATCH 07/14] [#151]: Fix workflows and update README --- .github/workflows/code_quality.yml | 3 ++- .github/workflows/ubuntu.yml | 5 +++-- .github/workflows/windows.yml | 4 ++-- README.md | 3 --- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index 92598fc1..af9f64fd 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -20,7 +20,7 @@ jobs: build_dir=\${2} pip install conan --break-system-packages conan profile detect - conan install \$root_dir --install-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install + conan install \$root_dir --output-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install wget https://sdk.lunarg.com/sdk/download/1.3.216.0/linux/vulkansdk-linux-x86_64-1.3.216.0.tar.gz tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/dependencies source \$root_dir/dependencies/1.3.216.0/setup-env.sh" > init_script.sh @@ -28,6 +28,7 @@ jobs: - name: Run static analysis uses: JacobDomagala/StaticAnalysis@master with: + cmake_args: -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release exclude_dir: dependencies init_script: init_script.sh apt_pckgs: xorg-dev python3-pip diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 20d859b3..23ee88f0 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -47,7 +47,7 @@ jobs: run: | # Use newer ABI conan profile detect - conan install $GITHUB_WORKSPACE --install-folder=build --build=missing --settings=build_type=$BUILD_TYPE + conan install $GITHUB_WORKSPACE --output-folder=build --build=missing --settings=build_type=$BUILD_TYPE - name: Run CMake shell: bash @@ -55,7 +55,8 @@ jobs: run: | source ${{runner.workspace}}/Looper/$SDK_VERSION/setup-env.sh cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DWARNINGS_AS_ERRORS=ON -DENABLE_INCLUDE_WHAT_YOU_USE=OFF\ - -DENABLE_SANITIZER_ADDRESS=ON -DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=OFF -DENABLE_SANITIZER_LEAK=ON -DUNITY_BUILD=ON + -DENABLE_SANITIZER_ADDRESS=ON -DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=OFF -DENABLE_SANITIZER_LEAK=ON -DUNITY_BUILD=ON\ + -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake - name: Build working-directory: ${{runner.workspace}}/build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c809fe37..6ada4e40 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -51,14 +51,14 @@ jobs: working-directory: ${{runner.workspace}}/build run: | conan profile detect - conan install $env:GITHUB_WORKSPACE --install-folder=build --build=missing --settings=build_type=$env:BUILD_TYPE + conan install $env:GITHUB_WORKSPACE --output-folder=build --build=missing --settings=build_type=$env:BUILD_TYPE - name: Configure CMake and build working-directory: ${{runner.workspace}}/build run: | $env:VULKAN_SDK="$env:VULKAN_DIR\$env:SDK_VERSION" - cmake $env:GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE + cmake $env:GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=${{runner.workspace}}\build\build\conan_toolchain.cmake cmake --build . --config $env:BUILD_TYPE > output.txt cat output.txt diff --git a/README.md b/README.md index 1b820fed..9a5338ef 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ The typical build process would look like this: # Create build directory mkdir build && cd build -# Use newer ABI -conan profile new default --detect -conan profile update settings.compiler.libcxx=libstdc++11 default conan install .. --output-folder=build --build=missing --settings=build_type=Release # Generate build system for Windows/Linux From 5036cacb2cacb7142fcd7f148c60cde2025acc06 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Sun, 26 Nov 2023 19:42:33 +0100 Subject: [PATCH 08/14] [#151]: Fix SA issue --- engine/game/level.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/engine/game/level.cpp b/engine/game/level.cpp index 53606101..37cf8bf2 100644 --- a/engine/game/level.cpp +++ b/engine/game/level.cpp @@ -551,20 +551,18 @@ Level::GetObjectRef(Object::ID objectID) switch (Object::GetTypeFromID(objectID)) { case ObjectType::ENEMY: { - auto it = std::find_if(m_objects.begin(), m_objects.end(), [objectID](const auto& object) { - return object->GetID() == objectID; - }); + auto it = stl::find_if( + m_objects, [objectID](const auto& object) { return object->GetID() == objectID; }); if (it != m_objects.end()) { - requestedObject = (*it).get(); + requestedObject = it->get(); } } break; case ObjectType::PLAYER: { - // Assume it's the player - return *m_player; + requestedObject = m_player.get(); } break; @@ -575,9 +573,8 @@ Level::GetObjectRef(Object::ID objectID) if (animatePtr) { auto& points = animatePtr->GetAnimationKeypoints(); - auto it = std::find_if(points.begin(), points.end(), [objectID](const auto& point) { - return point.GetID() == objectID; - }); + auto it = stl::find_if( + points, [objectID](const auto& point) { return point.GetID() == objectID; }); if (it != points.end()) { @@ -591,8 +588,8 @@ Level::GetObjectRef(Object::ID objectID) case ObjectType::PATHFINDER_NODE: { auto& nodes = m_pathFinder.GetAllNodes(); - auto it = std::find_if(nodes.begin(), nodes.end(), - [objectID](const auto& node) { return node.GetID() == objectID; }); + auto it = + stl::find_if(nodes, [objectID](const auto& node) { return node.GetID() == objectID; }); if (it != nodes.end()) { @@ -610,6 +607,8 @@ Level::GetObjectRef(Object::ID objectID) // NOLINTNEXTLINE assert(requestedObject); + // requestedObject will never be nullptr + // NOLINTNEXTLINE return *requestedObject; } From e0308d4e2ec4e3ea72d176fbcfe80ebe1f9cd011 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Sun, 26 Nov 2023 20:33:47 +0100 Subject: [PATCH 09/14] [#151]: Set minimum height for tools menu --- editor/gui/editor_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index fefe3c0c..a6924bf7 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -1127,7 +1127,7 @@ EditorGUI::UpdateUI() windowSize_ = parent_.GetWindowSize(); windowWidth_ = windowSize_.x / 7; - toolsWindowHeight_ = windowSize_.y / 20; + toolsWindowHeight_ = std::max(windowSize_.y / 20.0f, 64.0f); levelWindowHeight_ = windowSize_.y - toolsWindowHeight_; gameObjectWindowHeight_ = windowSize_.y; From 703faa16ae7ea53c4bd14bc9c9f4b89b53e940d6 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Sun, 26 Nov 2023 21:56:05 +0100 Subject: [PATCH 10/14] [#151]: Fix animation of objects in Editor --- editor/editor.cpp | 18 ++++++++++++++---- engine/core/application.cpp | 2 +- engine/core/application.hpp | 2 +- engine/game/animatable.cpp | 6 ++++++ engine/game/animatable.hpp | 3 +++ engine/game/enemy.cpp | 2 +- engine/game/game.cpp | 6 +++--- engine/game/game_object.cpp | 6 ++++++ engine/game/game_object.hpp | 7 +++++-- 9 files changed, 40 insertions(+), 12 deletions(-) diff --git a/editor/editor.cpp b/editor/editor.cpp index 294bb4f5..f1446155 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -593,7 +593,7 @@ Editor::Render(VkCommandBuffer cmdBuffer) const auto idx = static_cast< size_t >(layer); const auto& numObjects = renderData.numMeshes.at(idx); const auto renderThisLayer = renderLayerToDraw_ == -1 ? true : renderLayerToDraw_ == layer; - + if (numObjects == 0 or !renderThisLayer) { continue; @@ -1037,14 +1037,20 @@ Editor::Update() if (m_animateGameObject && m_currentSelectedGameObject) { - auto moveBy = std::dynamic_pointer_cast< Animatable >(m_currentSelectedGameObject) - ->SingleAnimate(m_deltaTime); + const auto& animatable = std::dynamic_pointer_cast< Animatable >(m_currentSelectedGameObject); + auto moveBy = animatable->SingleAnimate(deltaTime_); if (glm::length(moveBy) > 0.0f) { + const auto prevPosition = m_currentSelectedGameObject->GetPreviousPosition(); + const auto direction = m_currentSelectedGameObject->GetPosition() - prevPosition; + + const auto viewAngle = glm::atan(direction.y, direction.x); + + m_currentSelectedGameObject->Rotate(viewAngle); m_currentSelectedGameObject->Move(moveBy); } - else + else if (animatable->AnimationFinished()) { m_animateGameObject = false; } @@ -1123,6 +1129,8 @@ Editor::MainLoop() while (IsRunning() and (singleFrameTimer.count() >= TARGET_TIME_MICRO)) { const time::ScopedTimer frameTimer(&timeLastFrame_); + + deltaTime_ = m_timer.GetMsDeltaTime(); InputManager::PollEvents(); // Run all deffered work units @@ -1159,6 +1167,8 @@ Editor::MainLoop() { LaunchGameLoop(); } + + m_timer.ToggleTimer(); } } } diff --git a/engine/core/application.cpp b/engine/core/application.cpp index 1a3eaccc..d5bf379c 100644 --- a/engine/core/application.cpp +++ b/engine/core/application.cpp @@ -33,7 +33,7 @@ Application::GetCamera() time::milliseconds Application::GetDeltaTime() const { - return m_deltaTime; + return deltaTime_; } bool diff --git a/engine/core/application.hpp b/engine/core/application.hpp index c284d0a0..0be7e3df 100644 --- a/engine/core/application.hpp +++ b/engine/core/application.hpp @@ -102,7 +102,7 @@ class Application : public InputListener std::unique_ptr< renderer::Window > m_window = {}; renderer::Camera m_camera = {}; time::Timer m_timer = {}; - time::milliseconds m_deltaTime = {}; + time::milliseconds deltaTime_ = {}; int32_t m_frames = 0; float m_frameTimer = 0.0f; int32_t m_framesLastSecond = 0; diff --git a/engine/game/animatable.cpp b/engine/game/animatable.cpp index 86708b8b..0eadb707 100644 --- a/engine/game/animatable.cpp +++ b/engine/game/animatable.cpp @@ -187,6 +187,12 @@ Animatable::SingleAnimate(time::milliseconds updateTime) return Animate(updateTime); } +bool +Animatable::AnimationFinished() const +{ + return currentState_.m_animationFinished; +} + AnimationPoint Animatable::CreateAnimationNode(Object::ID parentID, const glm::vec2& position) { diff --git a/engine/game/animatable.hpp b/engine/game/animatable.hpp index fa12e751..b2467b47 100644 --- a/engine/game/animatable.hpp +++ b/engine/game/animatable.hpp @@ -66,6 +66,9 @@ class Animatable glm::vec2 SingleAnimate(time::milliseconds updateTime); + bool + AnimationFinished() const; + AnimationPoint CreateAnimationNode(Object::ID parentID, const glm::vec2& position = glm::vec2{}); diff --git a/engine/game/enemy.cpp b/engine/game/enemy.cpp index 3092dd07..a66b333d 100644 --- a/engine/game/enemy.cpp +++ b/engine/game/enemy.cpp @@ -169,7 +169,7 @@ Enemy::EnemyMove(const glm::vec2& moveBy) if (GameObject::m_gameObjectStatesQueue.GetNumFrames() > 1) { - prevPosition = glm::vec2(GameObject::m_gameObjectStatesQueue.PeekLastState().previousPosition_); + prevPosition = GetPreviousPosition(); } const auto direction = m_currentGameObjectState.m_position - prevPosition; diff --git a/engine/game/game.cpp b/engine/game/game.cpp index 39d1d38d..ab11db0a 100644 --- a/engine/game/game.cpp +++ b/engine/game/game.cpp @@ -133,7 +133,7 @@ Game::MoveGameObject(GameObject* gameObject, const glm::vec2& moveBy) const void Game::KeyEvents() // NOLINT { - const auto floatDeltaTime = static_cast< float >(m_deltaTime.count()); + const auto floatDeltaTime = static_cast< float >(deltaTime_.count()); // Camera movement is disabled const auto cameraMovement = 0.05f * floatDeltaTime; const auto playerMovement = 0.5f * floatDeltaTime; @@ -229,7 +229,7 @@ Game::MouseEvents() constexpr float borderValue = 0.5f; constexpr float modifier = 1.f; - const auto cameraMovement = modifier * floorf(static_cast< float >(m_deltaTime.count())); + const auto cameraMovement = modifier * floorf(static_cast< float >(deltaTime_.count())); auto cameraMoveBy = glm::vec2(); const auto cursor = m_window->GetCursorNormalized(); @@ -347,7 +347,7 @@ Game::IsRunning() const void Game::ProcessInput(time::milliseconds deltaTime) { - m_deltaTime = deltaTime; + deltaTime_ = deltaTime; MouseEvents(); KeyEvents(); diff --git a/engine/game/game_object.cpp b/engine/game/game_object.cpp index 990752f4..a852af23 100644 --- a/engine/game/game_object.cpp +++ b/engine/game/game_object.cpp @@ -82,6 +82,12 @@ GameObject::GetPosition() const return m_currentGameObjectState.m_position; } +glm::vec2 +GameObject::GetPreviousPosition() const +{ + return m_currentGameObjectState.previousPosition_; +} + glm::vec2 GameObject::GetCenteredPosition() const { diff --git a/engine/game/game_object.hpp b/engine/game/game_object.hpp index 839b0924..be05d481 100644 --- a/engine/game/game_object.hpp +++ b/engine/game/game_object.hpp @@ -48,14 +48,17 @@ class GameObject : public Object [[nodiscard]] virtual glm::ivec2 GetSize() const; - // Get centered position in global(OpenGL) coords + // Get centered position in global(Vulkan) coords [[nodiscard]] virtual glm::vec2 GetCenteredPosition() const; - // Get position in global (OpenGL) coords + // Get position in global (Vulkan) coords [[nodiscard]] virtual glm::vec2 GetPosition() const; + [[nodiscard]] glm::vec2 + GetPreviousPosition() const; + [[nodiscard]] virtual bool CheckIfCollidedScreenPosion(const glm::vec2& screenPosition) const; From 3dcafe758c1786443da6f674137ccceb0d96be98 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Mon, 27 Nov 2023 01:02:48 +0100 Subject: [PATCH 11/14] [#151]: Update texture section for selected object --- editor/gui/editor_gui.cpp | 45 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index a6924bf7..2b22f1fb 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -947,36 +947,37 @@ EditorGUI::RenderGameObjectMenu() // NOLINT if (ImGui::CollapsingHeader("Shader")) { const auto sectionSize = ImGui::GetContentRegionAvail(); + const auto currentPos = ImGui::GetCursorScreenPos(); + ImGui::SetCursorScreenPos(ImVec2(currentPos.x + sectionSize.x / 4.0f, currentPos.y)); ImGui::Image(static_cast< ImTextureID >( GetDescriptor(currentlySelectedGameObject_->GetSprite().GetTexture()->GetID(), descriptorPool_, descriptorSetLayout_)), - {sectionSize.x, sectionSize.x}); + {glm::min(sectionSize.x, 128.0f), glm::min(sectionSize.x, 128.0f)}); - DrawWidget("Texture", [this, sectionSize]() { + if (ImGui::BeginTable("TextureInfoTable", 2)) + { auto& sprite = currentlySelectedGameObject_->GetSprite(); - const float fullWidth = sectionSize.x; - const float inputTextWidth = fullWidth * 0.90f; - const float buttonWidth = fullWidth * 0.10f; - - ImGui::PushItemWidth(inputTextWidth); - ImGui::InputText("##Texture", sprite.GetTextureName().data(), - sprite.GetTextureName().size(), ImGuiInputTextFlags_ReadOnly); - ImGui::PopItemWidth(); // Always pair a Push call with a Pop - - ImGui::SameLine(); + CreateRow("Name", fmt::format("{}", sprite.GetTextureName())); + CreateRow("ID", fmt::format("{}", sprite.GetTexture()->GetID())); + CreateActionRowLabel("File", [this]() { + auto& sprite = currentlySelectedGameObject_->GetSprite(); + + ImGui::InputText("##Texture", sprite.GetTextureName().data(), + sprite.GetTextureName().size(), ImGuiInputTextFlags_ReadOnly); + ImGui::SameLine(); - ImGui::PushItemWidth(buttonWidth); - if (ImGui::Button(ICON_FA_PENCIL "")) - { - auto textureName = FileManager::FileDialog( - IMAGES_DIR, {{"PNG texture", "png"}, {"JPEG texture", "jpg"}}, false); - if (!textureName.empty()) + if (ImGui::Button(ICON_FA_PENCIL "")) { - sprite.SetTextureFromFile(textureName); + auto textureName = FileManager::FileDialog( + IMAGES_DIR, {{"PNG texture", "png"}, {"JPEG texture", "jpg"}}, false); + if (!textureName.empty()) + { + sprite.SetTextureFromFile(textureName); + } } - } - ImGui::PopItemWidth(); // Always pair a Push call with a Pop - }); + }); + } + ImGui::EndTable(); } if (currentlySelectedGameObject_->GetType() == ObjectType::ENEMY) From 6c179f9deab567bfcc8cf57ce10bf8cf6e42e99b Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Mon, 27 Nov 2023 13:06:16 +0100 Subject: [PATCH 12/14] [#151]: Use stb from conan instead of downloading it --- .github/workflows/code_quality.yml | 7 ++++--- CMakeLists.txt | 3 +-- dependencies/CMakeLists.txt | 18 ------------------ dependencies/stb_image/CMakeLists.txt | 3 --- engine/CMakeLists.txt | 3 ++- 5 files changed, 7 insertions(+), 27 deletions(-) delete mode 100644 dependencies/CMakeLists.txt delete mode 100644 dependencies/stb_image/CMakeLists.txt diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index af9f64fd..0aa97259 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -22,14 +22,15 @@ jobs: conan profile detect conan install \$root_dir --output-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install wget https://sdk.lunarg.com/sdk/download/1.3.216.0/linux/vulkansdk-linux-x86_64-1.3.216.0.tar.gz - tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/dependencies - source \$root_dir/dependencies/1.3.216.0/setup-env.sh" > init_script.sh + mkdir vulkan + tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/vulkan + source \$root_dir/vulkan/1.3.216.0/setup-env.sh" > init_script.sh - name: Run static analysis uses: JacobDomagala/StaticAnalysis@master with: cmake_args: -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release - exclude_dir: dependencies + exclude_dir: vulkan init_script: init_script.sh apt_pckgs: xorg-dev python3-pip verbose: true diff --git a/CMakeLists.txt b/CMakeLists.txt index effb89ee..2c605b91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(cmake/util_functions.cmake) -add_subdirectory(dependencies) add_subdirectory(engine) add_subdirectory(game) add_subdirectory(editor) @@ -47,4 +46,4 @@ compile_shader(SOURCE_FILE "${SHADERS_PATH}/default.frag" OUTPUT_FILE_NAME "${S compile_shader(SOURCE_FILE "${SHADERS_PATH}/ui.vert" OUTPUT_FILE_NAME "${SHADERS_PATH}/ui.vert.spv") compile_shader(SOURCE_FILE "${SHADERS_PATH}/ui.frag" OUTPUT_FILE_NAME "${SHADERS_PATH}/ui.frag.spv") compile_shader(SOURCE_FILE "${SHADERS_PATH}/line.vert" OUTPUT_FILE_NAME "${SHADERS_PATH}/line.vert.spv") -compile_shader(SOURCE_FILE "${SHADERS_PATH}/line.frag" OUTPUT_FILE_NAME "${SHADERS_PATH}/line.frag.spv") \ No newline at end of file +compile_shader(SOURCE_FILE "${SHADERS_PATH}/line.frag" OUTPUT_FILE_NAME "${SHADERS_PATH}/line.frag.spv") diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt deleted file mode 100644 index 9120c074..00000000 --- a/dependencies/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Function to download resource from git repo -function(FIND_AND_DOWNLOAD_GIT_RESOURCE ResourceName ResourceURL) - if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ResourceName}) - message("${ResourceName} not found!") - execute_process(COMMAND git clone --recursive ${ResourceURL} ${CMAKE_CURRENT_SOURCE_DIR}/${ResourceName}) - else() - message("${ResourceName} found!") - endif() -endfunction() - -include(FindVulkan) -if (NOT Vulkan_FOUND) - message(FATAL_ERROR "Could not find Vulkan library!") -else() - message(STATUS ${Vulkan_LIBRARY}) -endif() - -add_subdirectory(stb_image) diff --git a/dependencies/stb_image/CMakeLists.txt b/dependencies/stb_image/CMakeLists.txt deleted file mode 100644 index ba4fe0a8..00000000 --- a/dependencies/stb_image/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -FIND_AND_DOWNLOAD_GIT_RESOURCE(stb_image https://github.com/nothings/stb.git) -add_library(stb_image INTERFACE IMPORTED GLOBAL) -target_include_directories(stb_image INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stb_image") diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index beb361b6..02cec4c1 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -21,8 +21,9 @@ find_package(glfw3 REQUIRED) find_package(imgui REQUIRED) find_package(glm REQUIRED) find_package(nlohmann_json REQUIRED) +find_package(stb REQUIRED) -target_link_libraries_system(${MODULE_NAME} PUBLIC stb_image fmt::fmt glfw imgui::imgui glm::glm nlohmann_json::nlohmann_json) +target_link_libraries_system(${MODULE_NAME} PUBLIC stb::stb fmt::fmt glfw imgui::imgui glm::glm nlohmann_json::nlohmann_json) target_link_libraries(${MODULE_NAME} PUBLIC project_warnings project_options Vulkan::Vulkan) target_compile_features(${MODULE_NAME} PRIVATE cxx_std_20) From 2ebbb9be41f71e544e2ae87a67155f051296fc35 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Mon, 27 Nov 2023 18:04:27 +0100 Subject: [PATCH 13/14] [#151]: Fix issues with updating collision map --- editor/editor.cpp | 2 ++ editor/gui/editor_gui.cpp | 12 ++++++++---- editor/main.cpp | 3 ++- engine/game/animatable.cpp | 21 +++++++++++++++++++-- engine/game/animatable.hpp | 3 +++ engine/game/game_object.cpp | 2 ++ engine/game/level.cpp | 12 ++++++++---- engine/game/path_finder.cpp | 8 ++++---- engine/renderer/sprite.cpp | 2 +- 9 files changed, 49 insertions(+), 16 deletions(-) diff --git a/editor/editor.cpp b/editor/editor.cpp index f1446155..0668c09d 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -804,6 +804,8 @@ Editor::CreateLevel(const std::string& name, const glm::ivec2& size) m_levelFileName = (LEVELS_DIR / (name + ".dgl")).string(); gui_.LevelLoaded(m_currentLevel); + m_currentLevel->GenerateTextureForCollision(); + SetupRendererData(); } diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index 2b22f1fb..341b4388 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -561,12 +561,13 @@ void EditorGUI::RenderCreateNewLevelWindow() { const auto halfSize = windowSize_ / 2.0f; - std::unordered_map< std::string, glm::ivec2 > sizes = {{"Small", glm::ivec2{4096, 4096}}, + std::unordered_map< std::string, glm::ivec2 > sizes = {{"Small", glm::ivec2{8192, 8192}}, {"Medium", glm::ivec2{16384, 16384}}, {"Large", glm::ivec2{65536, 65536}}}; - static glm::ivec2 size = {1024, 1024}; + static std::string name = "DummyLevelName"; static std::string currentSize = "Small"; + static glm::ivec2 size = sizes[currentSize]; ImGui::SetNextWindowPos({halfSize.x - 160, halfSize.y - 60}); ImGui::SetNextWindowSize({300, 180}); @@ -904,6 +905,7 @@ EditorGUI::RenderGameObjectMenu() // NOLINT if (ImGui::Checkbox("##Has Collision", &collision)) { currentlySelectedGameObject_->SetHasCollision(collision); + parent_.GetLevel().UpdateCollisionTexture(); } }); @@ -926,6 +928,7 @@ EditorGUI::RenderGameObjectMenu() // NOLINT if (ImGui::SliderFloat2("##Size", &sprite_size.x, 10, 1000)) { currentlySelectedGameObject_->SetSize(sprite_size); + parent_.GetLevel().UpdateCollisionTexture(); } }); @@ -1021,8 +1024,9 @@ EditorGUI::RenderGameObjectMenu() // NOLINT time::Timer::ConvertToMs(animatablePtr->GetAnimationDuration()).count(); if (parent_.IsObjectAnimated()) { - timer += static_cast< float >(parent_.GetDeltaTime().count()); - timer = glm::min(animationDuration, timer); + // timer += static_cast< float >(parent_.GetDeltaTime().count()); + // timer = glm::min(animationDuration, timer); + timer = animatablePtr->GetTotalTimeElapsed().count(); } ImGui::SameLine(); diff --git a/editor/main.cpp b/editor/main.cpp index ca3d0eb7..ec89011b 100644 --- a/editor/main.cpp +++ b/editor/main.cpp @@ -4,7 +4,8 @@ int main(int /* argc */, char** /* argv */) { - looper::Editor editor(looper::USE_DEFAULT_SIZE); + // looper::Editor editor(looper::USE_DEFAULT_SIZE); + looper::Editor editor({1920, 1080}); editor.MainLoop(); return EXIT_SUCCESS; diff --git a/engine/game/animatable.cpp b/engine/game/animatable.cpp index 0eadb707..a5f19fb8 100644 --- a/engine/game/animatable.cpp +++ b/engine/game/animatable.cpp @@ -26,6 +26,17 @@ Animatable::GetAnimationType() const void Animatable::UpdateAnimationPoint() { + if (currentState_.m_isReverse + and currentState_.m_currentAnimationPoint == m_animationPoints.begin()) + { + return; + } + if (not currentState_.m_isReverse + and currentState_.m_currentAnimationPoint == m_animationPoints.end()) + { + return; + } + currentState_.m_isReverse ? --currentState_.m_currentAnimationPoint : ++currentState_.m_currentAnimationPoint; @@ -85,8 +96,7 @@ Animatable::SetCorrectAnimationPoint(time::milliseconds& updateTime) auto animationDurationMs = time::Timer::ConvertToMs(currentState_.m_currentAnimationPoint->m_timeDuration); - while (updateTime >= animationDurationMs - && currentState_.m_currentAnimationPoint != m_animationPoints.begin()) + while (updateTime >= animationDurationMs) { updateTime -= animationDurationMs; animationValue += currentState_.m_currentAnimationEnd - currentState_.m_currentAnimationBegin; @@ -149,6 +159,7 @@ Animatable::Animate(time::milliseconds updateTime) auto animateBy = glm::vec2(); currentState_.m_animationFinished = false; + currentState_.m_totalTimeElapsed += updateTime; auto currentAnimationStepSize = AnimateInCurrentSection(updateTime); if (currentState_.m_currentTimeElapsed < currentState_.m_currentAnimationPoint->m_timeDuration) @@ -315,6 +326,12 @@ Animatable::ResetAnimation() currentState_.m_totalTimeElapsed = time::milliseconds(0); } +time::milliseconds +Animatable::GetTotalTimeElapsed() const +{ + return currentState_.m_totalTimeElapsed; +} + void Animatable::UpdateAnimationData() { diff --git a/engine/game/animatable.hpp b/engine/game/animatable.hpp index b2467b47..7ef0d6ff 100644 --- a/engine/game/animatable.hpp +++ b/engine/game/animatable.hpp @@ -111,6 +111,9 @@ class Animatable [[nodiscard]] glm::vec2 GetAnimationStartLocation() const; + [[nodiscard]] time::milliseconds + GetTotalTimeElapsed() const; + void Update(bool isReverse); diff --git a/engine/game/game_object.cpp b/engine/game/game_object.cpp index a852af23..6a3aa2c3 100644 --- a/engine/game/game_object.cpp +++ b/engine/game/game_object.cpp @@ -139,6 +139,8 @@ GameObject::SetHasCollision(bool hasCollision) { m_appHandle.GetLevel().GetPathfinder().SetNodeFreed(node, m_id); } + + m_currentGameObjectState.m_occupiedNodes.clear(); } else { diff --git a/engine/game/level.cpp b/engine/game/level.cpp index 37cf8bf2..8467d67a 100644 --- a/engine/game/level.cpp +++ b/engine/game/level.cpp @@ -339,6 +339,7 @@ Level::GameObjectMoved(const std::array< glm::vec2, 4 >& box, if (m_pathFinder.IsInitialized()) { + // TODO: Discard common tiles and only free/occupy unique ones for (auto tileID : currentTiles) { m_pathFinder.SetNodeFreed(tileID, objectID); @@ -356,10 +357,13 @@ Level::GameObjectMoved(const std::array< glm::vec2, 4 >& box, std::vector< Tile > Level::GetTilesFromBoundingBox(const std::array< glm::vec2, 4 >& box) const { - std::vector< Tile > ret; + std::set< Tile > ret; - auto insertToVec = [&ret](std::vector< Tile > tiles) { - ret.insert(ret.end(), tiles.begin(), tiles.end()); + auto insertToVec = [&ret](const std::vector< Tile >& tiles) { + for (const auto& tile : tiles) + { + ret.insert(tile); + } }; insertToVec(GetTilesAlongTheLine(box[0], box[3])); @@ -367,7 +371,7 @@ Level::GetTilesFromBoundingBox(const std::array< glm::vec2, 4 >& box) const insertToVec(GetTilesAlongTheLine(box[2], box[1])); insertToVec(GetTilesAlongTheLine(box[1], box[0])); - return ret; + return std::vector< Tile >{ret.begin(), ret.end()}; } Tile diff --git a/engine/game/path_finder.cpp b/engine/game/path_finder.cpp index 176b1ae2..b3fb3ed2 100644 --- a/engine/game/path_finder.cpp +++ b/engine/game/path_finder.cpp @@ -275,11 +275,11 @@ PathFinder::SetNodeOccupied(const Tile& nodeCoords, Object::ID objectID) { if (nodeCoords != INVALID_TILE) { - auto node_found = GetNodeItFromTile(nodes_, nodeCoords); - node_found->occupied_ = true; - node_found->objectsOccupyingThisNode_.push_back(objectID); + auto nodeFound = GetNodeItFromTile(nodes_, nodeCoords); + nodeFound->occupied_ = true; + nodeFound->objectsOccupyingThisNode_.push_back(objectID); - nodesModifiedLastFrame_.insert(node_found->id_); + nodesModifiedLastFrame_.insert(nodeFound->id_); } } diff --git a/engine/renderer/sprite.cpp b/engine/renderer/sprite.cpp index e761095a..d0c72d11 100644 --- a/engine/renderer/sprite.cpp +++ b/engine/renderer/sprite.cpp @@ -213,7 +213,7 @@ void Sprite::SetTranslateValue(const glm::vec2& translateBy) { currentState_.currentPosition_ = initialPosition_ + glm::vec3{translateBy, 0.0f}; - currentState_.translateVal_ += translateBy; + currentState_.translateVal_ = currentState_.currentPosition_; changed_ = true; } From 17ea5b8b106ee991519cef394f5d0b3b35eb16bc Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Tue, 28 Nov 2023 00:29:48 +0100 Subject: [PATCH 14/14] [#151]: Update README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9a5338ef..2c47f74b 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ # Looper Looper is a game engine with an integrated editor and a 2D type game with a level editor, all written in modern C++20. It uses Vulkan for rendering and ImGui/glfw3 for UI and window/input handling. The project is compatible with Ubuntu and Windows. -For past and future video logs, please visit my [Youtube](https://www.youtube.com/watch?v=Qh-vOKMPQGQ&list=PLRLVUsGGaSH-s0A_2w_eo2LQEfTZuqi7Y) channel. - -[![Watch the video](https://raw.githubusercontent.com/wiki/JacobDomagala/Looper/Looper_github.gif)](https://www.youtube.com/watch?v=Qh-vOKMPQGQ) +![gif](https://raw.githubusercontent.com/wiki/JacobDomagala/Looper/Looper_github.gif) ## Requirements - C++20 compatible compiler (e.g. GCC, Clang, MSVC) @@ -41,5 +39,9 @@ cmake --build . ## Contributing If you would like to contribute to the project, please fork the repository and submit a pull request with your proposed changes. We welcome any improvements or new features that enhance the functionality and user experience of Looper. +## Youtube +For past and future video logs, please visit my [Youtube](https://www.youtube.com/watch?v=Qh-vOKMPQGQ&list=PLRLVUsGGaSH-s0A_2w_eo2LQEfTZuqi7Y) channel.
+[![Playlist](https://img.youtube.com/vi/cyZFLKrvoPc/0.jpg)](https://www.youtube.com/watch?v=cyZFLKrvoPc&list=PLRLVUsGGaSH-s0A_2w_eo2LQEfTZuqi7Y "YouTube Playlist") + ## License Please refer to the LICENSE file in the repository for details on the licensing of this project.