From 2778cb4c6da3feac36a13c2a3c1acddc3dc3ff27 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 8 Jan 2024 13:06:22 +0100 Subject: [PATCH] feat (./ParticleSystem) --- GameEngine/CMakeLists.txt | 1 + GameEngine/src/Exodia/Project/Project.cpp | 4 + .../src/Exodia/Scene/Components/Component.hpp | 2 +- .../Exodia/Scene/Components/Components.hpp | 1 + .../DefaultComponents/ParticleComponent.hpp | 33 ++++ GameEngine/src/Exodia/Scene/SceneHeaders.hpp | 1 + .../Scene/System/Particle/ParticleSystem.cpp | 40 +++++ .../Scene/System/Particle/ParticleSystem.hpp | 30 ++++ .../Scene/System/Script/ScriptSystem.hpp | 2 +- SandBox/Ethan/Assets/Scene/Menu/Menu.exodia | 12 +- .../Ethan/Client/src/GameScene/MenuScene.cpp | 17 +- SandBox/Ethan/Client/src/Layer/GameLayer.cpp | 2 + SandBox/Ethan/Client/src/Scripts/Particle.hpp | 147 ++++++++++++++++++ 13 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 GameEngine/src/Exodia/Scene/Components/DefaultComponents/ParticleComponent.hpp create mode 100644 GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.cpp create mode 100644 GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.hpp create mode 100644 SandBox/Ethan/Client/src/Scripts/Particle.hpp diff --git a/GameEngine/CMakeLists.txt b/GameEngine/CMakeLists.txt index f513de6f..617b0023 100644 --- a/GameEngine/CMakeLists.txt +++ b/GameEngine/CMakeLists.txt @@ -54,6 +54,7 @@ set(SOURCES_GAME_ENGINE src/Exodia/Scene/System/Script/ScriptSystem.cpp src/Exodia/Scene/System/Physics/GravitySystem.cpp src/Exodia/Scene/System/Physics/MovingSystem.cpp + src/Exodia/Scene/System/Particle/ParticleSystem.cpp src/Exodia/Scene/EventSubscriber/EventHover.cpp src/Exodia/Scene/GameObject/GameObject.cpp src/Exodia/Scene/Prefabs/Prefabs.cpp diff --git a/GameEngine/src/Exodia/Project/Project.cpp b/GameEngine/src/Exodia/Project/Project.cpp index a4d080cc..1fa85874 100644 --- a/GameEngine/src/Exodia/Project/Project.cpp +++ b/GameEngine/src/Exodia/Project/Project.cpp @@ -87,6 +87,10 @@ namespace Exodia { return new ComponentContainer(data); }); + RegisterComponent("ParticleComponent", [](Buffer data) -> IComponentContainer * { + return new ComponentContainer(data); + }); + // -- Registering the script factories -- // // ... diff --git a/GameEngine/src/Exodia/Scene/Components/Component.hpp b/GameEngine/src/Exodia/Scene/Components/Component.hpp index ce6e1ed7..14dff84b 100644 --- a/GameEngine/src/Exodia/Scene/Components/Component.hpp +++ b/GameEngine/src/Exodia/Scene/Components/Component.hpp @@ -27,7 +27,7 @@ namespace Exodia { virtual void Serialize(UNUSED(YAML::Emitter &out)){}; virtual void Deserialize(UNUSED(const YAML::Node &node)){}; - virtual void DrawComponent(){}; + virtual void DrawComponent() {}; virtual Buffer SerializeData() { return Buffer(this, sizeof(*this)); } }; diff --git a/GameEngine/src/Exodia/Scene/Components/Components.hpp b/GameEngine/src/Exodia/Scene/Components/Components.hpp index 09b1a801..39aa4aa6 100644 --- a/GameEngine/src/Exodia/Scene/Components/Components.hpp +++ b/GameEngine/src/Exodia/Scene/Components/Components.hpp @@ -19,5 +19,6 @@ #include "Scene/Components/DefaultComponents/PrefabComponent.hpp" #include "Scene/Components/DefaultComponents/RigidBody2DComponent.hpp" #include "Scene/Components/DefaultComponents/SoundComponent.hpp" +#include "Scene/Components/DefaultComponents/ParticleComponent.hpp" #endif /* !COMPONENTS_HPP_ */ diff --git a/GameEngine/src/Exodia/Scene/Components/DefaultComponents/ParticleComponent.hpp b/GameEngine/src/Exodia/Scene/Components/DefaultComponents/ParticleComponent.hpp new file mode 100644 index 00000000..3c41042f --- /dev/null +++ b/GameEngine/src/Exodia/Scene/Components/DefaultComponents/ParticleComponent.hpp @@ -0,0 +1,33 @@ +/* +** EPITECH PROJECT, 2024 +** R-Type +** File description: +** ParticleComponent +*/ + +#ifndef PARTICLECOMPONENT_HPP_ + #define PARTICLECOMPONENT_HPP_ + + // Exodia ECS includes + #include "Scene/Components/Component.hpp" + + // External includes + #include + +namespace Exodia { + + struct ParticleComponent : public Component { + float LifeTime; + float LifeRemaining; + glm::vec4 ColorBegin; + glm::vec4 ColorEnd; + float SizeBegin; + float SizeEnd; + + ParticleComponent(ParticleComponent const &) = default; + ParticleComponent() = default; + ParticleComponent(float lifeTime, const glm::vec4 &colorBegin, const glm::vec4 &colorEnd, float sizeBegin, float sizeEnd) : LifeTime(lifeTime), LifeRemaining(lifeTime), ColorBegin(colorBegin), ColorEnd(colorEnd), SizeBegin(sizeBegin), SizeEnd(sizeEnd) {}; + }; +}; + +#endif /* !PARTICLECOMPONENT_HPP_ */ diff --git a/GameEngine/src/Exodia/Scene/SceneHeaders.hpp b/GameEngine/src/Exodia/Scene/SceneHeaders.hpp index b4a18d06..75dfe1e1 100644 --- a/GameEngine/src/Exodia/Scene/SceneHeaders.hpp +++ b/GameEngine/src/Exodia/Scene/SceneHeaders.hpp @@ -29,6 +29,7 @@ #include "Exodia/Scene/System/Script/ScriptSystem.hpp" #include "Exodia/Scene/System/Physics/GravitySystem.hpp" #include "Exodia/Scene/System/Physics/MovingSystem.hpp" +#include "Exodia/Scene/System/Particle/ParticleSystem.hpp" // -- Event Subscribers ---------------------------------------------------- diff --git a/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.cpp b/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.cpp new file mode 100644 index 00000000..cf1efbdd --- /dev/null +++ b/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.cpp @@ -0,0 +1,40 @@ +/* +** EPITECH PROJECT, 2024 +** R-Type +** File description: +** ParticleSystem +*/ + +#include "ParticleSystem.hpp" +#include + +namespace Exodia { + + ///////////// + // Methods // + ///////////// + + void ParticleSystem::Update(World *world, Timestep ts) + { + world->ForEach([&](Entity *entity, auto transform, auto rigidBody, auto particle, auto sprite) { + auto &tc = transform.Get(); + auto &rb = rigidBody.Get(); + auto &pc = particle.Get(); + auto &sc = sprite.Get(); + + if (pc.LifeRemaining <= 0.0f) { + world->DestroyEntity(entity); + + return; + } + float life = pc.LifeRemaining / pc.LifeTime; + float size = glm::lerp(pc.SizeEnd, pc.SizeBegin, life); + glm::vec4 color = glm::lerp(pc.ColorEnd, pc.ColorBegin, life); + + pc.LifeRemaining -= ts; + sc.Color.a = color.a * life; + tc.Rotation.z += 0.01f * ts; + tc.Scale = glm::vec3(size); + }); + } +}; diff --git a/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.hpp b/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.hpp new file mode 100644 index 00000000..9a5347af --- /dev/null +++ b/GameEngine/src/Exodia/Scene/System/Particle/ParticleSystem.hpp @@ -0,0 +1,30 @@ +/* +** EPITECH PROJECT, 2024 +** R-Type +** File description: +** ParticleSystem +*/ + +#ifndef PARTICLESYSTEM_HPP_ + #define PARTICLESYSTEM_HPP_ + + // Exodia ECS Interface includes + #include "Exodia-ECS.hpp" + + // Exodia Scene includes + #include "Scene/Components/Components.hpp" + +namespace Exodia { + + class ParticleSystem : public EntitySystem { + + ///////////// + // Methods // + ///////////// + public: + + virtual void Update(World *world, Timestep ts) override; + }; +}; + +#endif /* !PARTICLESYSTEM_HPP_ */ diff --git a/GameEngine/src/Exodia/Scene/System/Script/ScriptSystem.hpp b/GameEngine/src/Exodia/Scene/System/Script/ScriptSystem.hpp index c475cd7d..6cdf99a6 100644 --- a/GameEngine/src/Exodia/Scene/System/Script/ScriptSystem.hpp +++ b/GameEngine/src/Exodia/Scene/System/Script/ScriptSystem.hpp @@ -9,7 +9,7 @@ #define SCRIPTSYSTEM_HPP_ // Exodia ECS Interface includes -#include "Interface/EntitySystem.hpp" +#include "Exodia-ECS.hpp" // Exodia ECS Components includes #include "Scene/Components/Components.hpp" diff --git a/SandBox/Ethan/Assets/Scene/Menu/Menu.exodia b/SandBox/Ethan/Assets/Scene/Menu/Menu.exodia index 88fe1889..c1a773d2 100644 --- a/SandBox/Ethan/Assets/Scene/Menu/Menu.exodia +++ b/SandBox/Ethan/Assets/Scene/Menu/Menu.exodia @@ -113,4 +113,14 @@ Entities: Color: [1, 1, 1, 1] Font: 45121874124124 Kerning: 0 - LineSpacing: 0 \ No newline at end of file + LineSpacing: 0 + + - Entity: 4512011102411212 + TagComponent: + Tag: Particle + TransformComponent: + Translation: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + ScriptComponent: + Name: ParticleController diff --git a/SandBox/Ethan/Client/src/GameScene/MenuScene.cpp b/SandBox/Ethan/Client/src/GameScene/MenuScene.cpp index 5be7d112..8710d466 100644 --- a/SandBox/Ethan/Client/src/GameScene/MenuScene.cpp +++ b/SandBox/Ethan/Client/src/GameScene/MenuScene.cpp @@ -31,6 +31,8 @@ namespace RType { // -- Scene System -- // _Scene->RegisterSystem(new AnimationSystem()); _Scene->RegisterSystem(new FadeSystem()); + _Scene->RegisterSystem(new ParticleSystem()); + _Scene->RegisterSystem(new MovingSystem()); // -- Resizing the viewport -- // _Scene->OnViewportResize(Application::Get().GetWindow().GetWidth(), Application::Get().GetWindow().GetHeight()); @@ -70,7 +72,7 @@ namespace RType { } bool MenuScene::OnKeyPressedEvent(KeyPressedEvent &event) { - GameObject menuHandler = _Scene->GetEntityByName("MenuHandler"); + /*GameObject menuHandler = _Scene->GetEntityByName("MenuHandler"); if (menuHandler.GetEntity()) { auto &script = menuHandler.GetComponent(); @@ -81,6 +83,17 @@ namespace RType { return true; } } - return false; + return false;*/ + + _Scene->GetWorldPtr()->ForEach([&](Entity *entity, auto script) { + auto &sc = script.Get(); // sc = Script Component + + if (sc.Instance != nullptr) + sc.Instance->OnKeyPressed(event.GetKeyCode()); + + (void)entity; + }); + + return true; } }; // namespace RType diff --git a/SandBox/Ethan/Client/src/Layer/GameLayer.cpp b/SandBox/Ethan/Client/src/Layer/GameLayer.cpp index bba9c622..a51444f8 100644 --- a/SandBox/Ethan/Client/src/Layer/GameLayer.cpp +++ b/SandBox/Ethan/Client/src/Layer/GameLayer.cpp @@ -17,6 +17,7 @@ // R-Type Scripts #include "Scripts/Intro.hpp" #include "Scripts/MenuHandler.hpp" +#include "Scripts/Particle.hpp" // R-Type Settings #include "Settings/Config.hpp" @@ -74,6 +75,7 @@ namespace RType { // -- Register Client scripts -- // project->RegisterScript("Intro", []() -> ScriptableEntity * { return new Intro(); }); project->RegisterScript("MenuHandler", []() -> ScriptableEntity * { return new MenuHandler(); }); + project->RegisterScript("ParticleController", []() -> ScriptableEntity * { return new ParticleController(); }); } /////////////////////// diff --git a/SandBox/Ethan/Client/src/Scripts/Particle.hpp b/SandBox/Ethan/Client/src/Scripts/Particle.hpp new file mode 100644 index 00000000..694556bf --- /dev/null +++ b/SandBox/Ethan/Client/src/Scripts/Particle.hpp @@ -0,0 +1,147 @@ +/* +** EPITECH PROJECT, 2024 +** R-Type +** File description: +** Particle +*/ + +#ifndef PARTICLE_HPP_ + #define PARTICLE_HPP_ + + // Exodia includes + #include "Exodia.hpp" + +namespace RType { + + using namespace Exodia; + + class ParticleController : public ScriptableEntity { + + //////////////// + // Structures // + //////////////// + public: + + struct ParticleProps { + glm::vec2 Position; + glm::vec2 Velocity; + glm::vec2 VelocityVariation; + glm::vec4 ColorBegin; + glm::vec4 ColorEnd; + float SizeBegin; + float SizeEnd; + float SizeVariation; + float LifeTime = 1.0f; + + int NumParticles = 1; + }; + + ///////////// + // Methods // + ///////////// + public: + + void OnCreate() override + { + // Smoke Particles + _SmokeParticle.Position = { 0.0f, 0.0f }; + _SmokeParticle.Velocity = { -2.0f, 0.0f }; + _SmokeParticle.VelocityVariation = { 4.0f, 2.0f }; + _SmokeParticle.SizeBegin = 0.35f; + _SmokeParticle.SizeEnd = 0.0f; + _SmokeParticle.SizeVariation = 0.15f; + _SmokeParticle.ColorBegin = { 0.8f, 0.8f, 0.8f, 1.0f }; + _SmokeParticle.ColorEnd = { 0.6f, 0.6f, 0.6f, 1.0f }; + _SmokeParticle.LifeTime = 4.0f; + + // Engine Particles + _EngineParticle.Position = { 0.0f, 0.0f }; + _EngineParticle.Velocity = { -2.0f, 0.0f }; + _EngineParticle.VelocityVariation = { 3.0f, 1.0f }; + _EngineParticle.SizeBegin = 0.5f; + _EngineParticle.SizeEnd = 0.0f; + _EngineParticle.SizeVariation = 0.3f; + _EngineParticle.ColorBegin = { 254 / 255.0f, 109 / 255.0f, 41 / 255.0f, 1.0f }; + _EngineParticle.ColorEnd = { 254 / 255.0f, 212 / 255.0f, 123 / 255.0f, 1.0f }; + _EngineParticle.LifeTime = 1.0f; + _EngineParticle.NumParticles = 999; + } + + void OnUpdate(Timestep ts) override + { + _Time += ts; + + if (_Time > _SmokeNextEmitTime) { + Emit(_SmokeParticle); + + _SmokeNextEmitTime += _SmokeEmitInterval; + } + } + + void OnKeyPressed(int keycode) override + { + if (keycode == Key::SPACE) { + glm::vec2 mousePos = Input::GetMousePosition(); + + _EngineParticle.Position = mousePos; + + Emit(_EngineParticle); + } + } + + private: + + void Emit(ParticleProps &props) + { + std::mt19937 engine; + std::uniform_real_distribution distribution(0.0f, 1.0f); + + for (int i = 0; i < props.NumParticles; i++) { + GameObject particle = HandleEntity.GetScene()->CreateNewEntity("Particle #" + std::to_string(i)); + + TransformComponent &tc = particle.GetComponent(); + + tc.Translation.x = props.Position.x + Input::GetMousePosition().x; + tc.Translation.y = props.Position.y + Input::GetMousePosition().y; + tc.Rotation.z = (float)distribution(engine); + tc.Scale = glm::vec3(props.SizeBegin + props.SizeVariation * ((float)distribution(engine) - 0.5f)); + + SpriteRendererComponent &src = particle.AddComponent(); + + src.Color = props.ColorBegin; + + ParticleComponent &pc = particle.AddComponent(); + + pc.LifeTime = props.LifeTime; + pc.LifeRemaining = props.LifeTime; + pc.ColorBegin = props.ColorBegin; + pc.ColorEnd = props.ColorEnd; + pc.SizeBegin = props.SizeBegin + props.SizeVariation * ((float)distribution(engine) - 0.5f); + pc.SizeEnd = props.SizeEnd; + + RigidBody2DComponent &rbc = particle.AddComponent(); + + rbc.Type = RigidBody2DComponent::BodyType::Dynamic; + rbc.Velocity = props.Velocity; + rbc.Velocity.x += props.VelocityVariation.x * ((float)distribution(engine) - 0.5f); + rbc.Velocity.y += props.VelocityVariation.y * ((float)distribution(engine) - 0.5f); + rbc.GravityScale = 0.0f; + rbc.Mass = 0.0f; + } + } + + /////////////// + // Atributes // + /////////////// + private: + + ParticleProps _SmokeParticle; + ParticleProps _EngineParticle; + + float _Time; + float _SmokeEmitInterval; + float _SmokeNextEmitTime; + }; +}; + +#endif /* !PARTICLE_HPP_ */