diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ba47cf3..77a13829 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,8 @@ set(SOURCES sources/Component/IntroAnimation/IntroAnimationComponent.cpp sources/System/IntroAnimation/IntroAnimationSystem.hpp sources/System/IntroAnimation/IntroAnimationSystem.cpp + sources/System/Renderer/CameraSystem.cpp + sources/System/Renderer/CameraSystem.cpp sources/Runner/SplashScreenScene.cpp sources/Runner/TitleScreenScene.cpp sources/Runner/MainMenuScene.cpp diff --git a/sources/Component/Tag/TagComponent.hpp b/sources/Component/Tag/TagComponent.hpp index 74bf6253..9775c06d 100644 --- a/sources/Component/Tag/TagComponent.hpp +++ b/sources/Component/Tag/TagComponent.hpp @@ -52,11 +52,12 @@ namespace BBM // interact with bombs & stop the explosion constexpr const char Blowable[] = "Blowable"; + // interact with visual features like camera + constexpr const char Player[] = "Player"; constexpr const char Unbreakable[] = "Unbreakable"; constexpr const char Breakable[] = "Breakable"; constexpr const char Hole[] = "Hole"; constexpr const char Bumper[] = "Bumper"; - constexpr const char Player[] = "Player"; // interact with bombs (getting damage etc) but doesn't stop explosion constexpr const char BlowablePass[] = "BlowablePass"; } diff --git a/sources/Models/Vector3.hpp b/sources/Models/Vector3.hpp index d1d1d919..3f6ef2cf 100644 --- a/sources/Models/Vector3.hpp +++ b/sources/Models/Vector3.hpp @@ -135,7 +135,7 @@ namespace BBM double magnitude() const { - return (std::sqrt(std::pow(this->x, 2) + std::pow(this->y, 2), std::pow(this->z, 2))); + return (std::sqrt(std::pow(this->x, 2) + std::pow(this->y, 2) + std::pow(this->z, 2))); } Vector3 normalize() @@ -168,6 +168,11 @@ namespace BBM return (point * this) / std::pow(this->magnitude(), 2) * this; } + Vector3 abs() const + { + return Vector3(std::abs(this->x), std::abs(this->y), std::abs(this->z)); + } + Vector3 trunc() const requires(std::is_floating_point_v) { return Vector3(std::trunc(this->x), std::trunc(this->y), std::trunc(this->z)); diff --git a/sources/Runner/GameScene.cpp b/sources/Runner/GameScene.cpp index a6b8a3c3..69e954fa 100644 --- a/sources/Runner/GameScene.cpp +++ b/sources/Runner/GameScene.cpp @@ -19,8 +19,6 @@ #include "Component/Renderer/Drawable2DComponent.hpp" #include #include "Drawables/2D/Text.hpp" -#include "Component/Renderer/Drawable2DComponent.hpp" -#include "Component/Button/ButtonComponent.hpp" #include "Drawables/Texture.hpp" #include "Component/Gravity/GravityComponent.hpp" #include "Component/BumperTimer/BumperTimerComponent.hpp" @@ -28,7 +26,6 @@ #include "Model/Model.hpp" #include "Map/Map.hpp" #include "Component/Score/ScoreComponent.hpp" -#include "Drawables/2D/Text.hpp" namespace RAY3D = RAY::Drawables::Drawables3D; namespace RAY2D = RAY::Drawables::Drawables2D; @@ -39,7 +36,7 @@ namespace BBM { auto scene = std::make_shared(); scene->addEntity("camera") - .addComponent(8, 20, 7) + .addComponent(8, 0, -5) .addComponent(Vector3f(8, 0, 8)); scene->addEntity("Timer") .addComponent(std::chrono::minutes (3), [](WAL::Entity &, WAL::Wal &) { @@ -62,16 +59,16 @@ namespace BBM {SoundComponent::BOMB, "assets/sounds/bomb_drop.ogg"}, //{SoundComponent::DEATH, "assets/sounds/death.ogg"} }; - + return scene.addEntity("player") .addComponent() .addComponent("assets/player/player.iqm", true) - .addComponent() .addComponent() .addComponent() .addComponent() .addComponent() .addComponent>() + .addComponent>() .addComponent("assets/player/player.iqm", 3) .addComponent(BBM::Vector3f{0.25, 0, 0.25}, BBM::Vector3f{.75, 2, .75}) .addComponent() diff --git a/sources/Runner/LobbyScene.cpp b/sources/Runner/LobbyScene.cpp index c1596c17..6c0f6f3a 100644 --- a/sources/Runner/LobbyScene.cpp +++ b/sources/Runner/LobbyScene.cpp @@ -200,7 +200,7 @@ namespace BBM player.addComponent(i, ready, playerTile); } scene->addEntity("camera") - .addComponent(8, 20, 7) + .addComponent(-5, 0, -5) .addComponent(Vector3f(8, 0, 8)); play.getComponent().setButtonLinks(&lavaOption, &back, &back, &howToPlay); howToPlay.getComponent().setButtonLinks(&play, nullptr, &play); diff --git a/sources/Runner/Runner.cpp b/sources/Runner/Runner.cpp index b56b94fc..e9229812 100644 --- a/sources/Runner/Runner.cpp +++ b/sources/Runner/Runner.cpp @@ -46,6 +46,7 @@ #include "System/Gravity/GravitySystem.hpp" #include "System/BumperTimer/BumperTimerSystem.hpp" #include "System/Music/MusicSystem.hpp" +#include "System/Renderer/CameraSystem.hpp" #include "System/Lobby/LobbySystem.hpp" #include "System/Score/ScoreSystem.hpp" #include "System/EndCondition/EndConditionSystem.hpp" @@ -108,6 +109,7 @@ namespace BBM .addSystem() // .addSystem() .addSystem() + .addSystem() .addSystem(); } diff --git a/sources/System/Animator/AnimatorSystem.cpp b/sources/System/Animator/AnimatorSystem.cpp index e4df9dbc..23f312dc 100644 --- a/sources/System/Animator/AnimatorSystem.cpp +++ b/sources/System/Animator/AnimatorSystem.cpp @@ -30,7 +30,7 @@ namespace BBM auto anim = dynamic_cast(drawable); auto health = entity->tryGetComponent(); - if (health && health->getHealthPoint() <= 0) + if (health && health->getHealthPoint() <= 0 || entity->shouldDelete()) return; if (anim && controllable.move != Vector2f(0, 0)) { anim->setRotationAngle(controllable.move.angle(Vector2f(-1, 0))); diff --git a/sources/System/Renderer/CameraSystem.cpp b/sources/System/Renderer/CameraSystem.cpp new file mode 100644 index 00000000..3c4e538c --- /dev/null +++ b/sources/System/Renderer/CameraSystem.cpp @@ -0,0 +1,79 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#include "CameraSystem.hpp" +#include "Entity/Entity.hpp" +#include "Component/Tag/TagComponent.hpp" + +namespace BBM +{ + CameraSystem::CameraSystem(WAL::Wal &wal) + : System(wal) + {} + + bool CameraSystem::introAnimation(WAL::ViewEntity &entity, bool restart) + { + auto &pos = entity.get(); + static Vector3f posTarget(8, 25, 7); + static bool hasEnded = false; + + if (restart) { + hasEnded = false; + return (false); + } + if (pos.position.distance(posTarget) < 4 || hasEnded) { + hasEnded = true; + return (true); + } + + auto &cam = entity.get(); + + pos.position += (posTarget - pos.position) / 100; + return (false); + } + + void CameraSystem::onUpdate(WAL::ViewEntity &entity, + std::chrono::nanoseconds dtime) + { + if (!introAnimation(entity)) + return; + auto &pos = entity.get(); + auto &cam = entity.get(); + Vector3f newCameraPos = Vector3f(-1, -1, -1); + std::vector playerPos; + float maxDist = 0; + float lowerXDist = 0; + float lowerZDist = 0; + + for (auto &[entity, pos, _] : this->_wal.getScene()->view>()) { + if (!entity.hasComponent()) + entity.addComponent(); + playerPos.emplace_back(pos.position); + } + if (playerPos.size() == 0) + introAnimation(entity, true); + if (playerPos.size() == 1) + newCameraPos = playerPos[0]; + for (int i = 0; i < playerPos.size(); i++) + for (int j = 0; j < playerPos.size(); j++) { + if (maxDist < playerPos[i].distance(playerPos[j])) { + maxDist = playerPos[i].distance(playerPos[j]); + newCameraPos = (playerPos[i] + playerPos[j]) / 2; + } + if (lowerXDist < std::abs((playerPos[i].x - playerPos[j].x))) + lowerXDist = std::abs((playerPos[i].x - playerPos[j].x)); + if (lowerZDist < std::abs((playerPos[i].z - playerPos[j].z))) + lowerZDist = std::abs((playerPos[i].z - playerPos[j].z)); + } + maxDist += (lowerXDist + lowerZDist) / 2; + if (maxDist < 14) + maxDist = 14; + if (maxDist > 25) + maxDist = 25; + cam.target += (newCameraPos.abs() - pos.position.abs()) / 10; + newCameraPos.y = maxDist; + newCameraPos.z -= 1; + pos.position += (newCameraPos.abs() - pos.position.abs()) / 10; + } +} \ No newline at end of file diff --git a/sources/System/Renderer/CameraSystem.hpp b/sources/System/Renderer/CameraSystem.hpp new file mode 100644 index 00000000..ce3a804f --- /dev/null +++ b/sources/System/Renderer/CameraSystem.hpp @@ -0,0 +1,36 @@ +// +// Created by Tom Augier on 05/06/2021 +// + +#pragma once + +#include "System/System.hpp" +#include "Window.hpp" +#include "Component/Renderer/CameraComponent.hpp" +#include "Component/Position/PositionComponent.hpp" +#include +#include "Wal.hpp" + +namespace BBM +{ + class CameraSystem : public WAL::System + { + public: + //! @inherit + void onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds) override; + + //! @brief introduciton animation when entering gameScene + bool introAnimation(WAL::ViewEntity &entity, bool restart = false); + + //! @brief ctor + CameraSystem(WAL::Wal &wal); + //! @brief Default copy ctor + CameraSystem(const CameraSystem &) = default; + //! @brief Default dtor + ~CameraSystem() override = default; + //! @brief A CameraManager screen system can't be assigned. + CameraSystem &operator=(const CameraSystem &) = delete; + }; +} + + \ No newline at end of file diff --git a/sources/System/Renderer/RenderSystem.cpp b/sources/System/Renderer/RenderSystem.cpp index ac7f32b8..6fb43b5f 100644 --- a/sources/System/Renderer/RenderSystem.cpp +++ b/sources/System/Renderer/RenderSystem.cpp @@ -12,6 +12,7 @@ #include "Drawables/ADrawable3D.hpp" #include "Drawables/ADrawable2D.hpp" #include "Component/Shaders/ShaderComponent.hpp" +#include "Component/Tag/TagComponent.hpp" #include #include "Models/Vector3.hpp" #include "Component/Collision/CollisionComponent.hpp" @@ -164,10 +165,11 @@ namespace BBM void RenderSystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) { - const auto &pos = entity.get(); - const auto &cam = entity.get(); - _camera.setPosition(pos.position); + auto &pos = entity.get(); + auto &cam = entity.get(); + _camera.setTarget(cam.target); + _camera.setPosition(pos.position); } void RenderSystem::setDebug(bool debug) diff --git a/sources/System/Renderer/RenderSystem.hpp b/sources/System/Renderer/RenderSystem.hpp index 6d5e6e99..e5679be5 100644 --- a/sources/System/Renderer/RenderSystem.hpp +++ b/sources/System/Renderer/RenderSystem.hpp @@ -6,6 +6,7 @@ #include "Component/Renderer/CameraComponent.hpp" #include "Component/Position/PositionComponent.hpp" +#include "Component/Movable/MovableComponent.hpp" #include "Component/Renderer/Drawable3DComponent.hpp" #include "System/System.hpp" #include "Camera/Camera2D.hpp"