Skip to content

Commit

Permalink
Impact particle effects
Browse files Browse the repository at this point in the history
  • Loading branch information
justindriggers committed Dec 24, 2023
1 parent fb08296 commit bf66f8a
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 5 deletions.
2 changes: 2 additions & 0 deletions linguine/src/components/Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ struct Emitter {
std::function<void()> particleFactory;
float frequency = 1.0f;
float elapsed = 0.0f;
float totalLifetime = 0.0f;
float elapsedLifetime = 0.0f;
};

} // namespace linguine
1 change: 1 addition & 0 deletions linguine/src/components/Particle.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace linguine {
struct Particle {
float duration = 1.0f;
float elapsed = 0.0f;
float scalePerSecond = -0.25f;
};

} // namespace linguine
4 changes: 3 additions & 1 deletion linguine/src/scenes/InfiniteRunnerScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class InfiniteRunnerScene : public Scene {

// Scene-specific
registerSystem(std::make_unique<SpawnSystem>(getEntityManager(), serviceLocator.get<Renderer>()));
registerSystem(std::make_unique<ScoringSystem>(getEntityManager(), *_spellDatabase));
registerSystem(std::make_unique<ScoringSystem>(getEntityManager(), *_spellDatabase, serviceLocator.get<Renderer>()));

registerSystem(std::make_unique<TransformationSystem>(getEntityManager()));
registerSystem(std::make_unique<CameraSystem>(getEntityManager(), serviceLocator.get<Renderer>()));
Expand Down Expand Up @@ -197,6 +197,7 @@ class InfiniteRunnerScene : public Scene {

auto cockpitTransform = cockpitEntity->add<Transform>();
cockpitTransform->scale = transform->scale;
cockpitTransform->position.z = 0.05f;

cockpitEntity->add<PhysicalState>();

Expand All @@ -218,6 +219,7 @@ class InfiniteRunnerScene : public Scene {

auto boosterTransform = boosterEntity->add<Transform>();
boosterTransform->scale = transform->scale;
boosterTransform->position.z = 0.05f;

boosterEntity->add<PhysicalState>();

Expand Down
9 changes: 7 additions & 2 deletions linguine/src/systems/ParticleSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@
namespace linguine {

void ParticleSystem::update(float deltaTime) {
findEntities<Emitter>()->each([deltaTime](const Entity& entity) {
findEntities<Emitter>()->each([deltaTime](Entity& entity) {
auto emitter = entity.get<Emitter>();

emitter->elapsed += deltaTime;
emitter->elapsedLifetime += deltaTime;

if (emitter->elapsed >= emitter->frequency) {
emitter->elapsed -= emitter->frequency;
emitter->particleFactory();
}

if (emitter->totalLifetime > 0.0f && emitter->elapsedLifetime >= emitter->totalLifetime) {
entity.destroy();
}
});

findEntities<Particle, Transform>()->each([deltaTime](Entity& entity) {
Expand All @@ -26,7 +31,7 @@ void ParticleSystem::update(float deltaTime) {
particle->elapsed += deltaTime;

auto transform = entity.get<Transform>();
transform->scale = glm::max(transform->scale - glm::vec3(0.25f) * deltaTime, glm::vec3(0.0f));
transform->scale = glm::max(transform->scale + glm::vec3(particle->scalePerSecond) * deltaTime, glm::vec3(0.0f));

if (particle->elapsed >= particle->duration || glm::length2(transform->scale) <= 0.0f) {
entity.destroy();
Expand Down
122 changes: 122 additions & 0 deletions linguine/src/systems/ScoringSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
#include "components/Alive.h"
#include "components/Asteroid.h"
#include "components/Bomb.h"
#include "components/Circle.h"
#include "components/Emitter.h"
#include "components/Health.h"
#include "components/Hit.h"
#include "components/Particle.h"
#include "components/PhysicalState.h"
#include "components/Player.h"
#include "components/PowerUp.h"
#include "components/Score.h"
#include "components/Text.h"
#include "components/Transform.h"
#include "components/Velocity.h"

namespace linguine {

Expand Down Expand Up @@ -44,19 +50,135 @@ void ScoringSystem::fixedUpdate(float fixedDeltaTime) {
auto health = partyMember->get<Health>();
health->current = glm::clamp(health->current - 50 * asteroid->points, 0, health->max);

auto asteroidTransform = hitEntity->get<Transform>();

auto randomScale = std::uniform_real_distribution(0.1f, 0.25f);
auto randomDirection = std::uniform_real_distribution(0.0f, glm::two_pi<float>());

for (auto i = 0; i < 10; ++i) {
auto particleEntity = createEntity();

auto particle = particleEntity->add<Particle>();
particle->duration = 0.5f;

auto transform = particleEntity->add<Transform>();
transform->scale = glm::vec3(randomScale(_random));
transform->position = asteroidTransform->position;

particleEntity->add<PhysicalState>(transform->position, 0.0f);

auto velocity = particleEntity->add<Velocity>();
velocity->velocity = glm::angleAxis(randomDirection(_random), glm::vec3(0.0f, 0.0f, 1.0f)) * glm::vec3(1.0f, 0.0f, 0.0f) * 10.0f;

auto circle = particleEntity->add<Circle>();
circle->feature = new CircleFeature();
circle->feature->color = { 0.97345f, 0.36625f, 0.00561f };
circle->renderable = _renderer.create(std::unique_ptr<CircleFeature>(circle->feature));
circle.setRemovalListener([circle](const Entity e) {
circle->renderable->destroy();
});
}

hitEntity->destroy();
} else if (hitEntity->has<PowerUp>()) {
auto powerUp = hitEntity->get<PowerUp>();

switch (powerUp->type) {
case PowerUp::MassHeal:
_spellDatabase.getSpellById(2).action->execute(playerEntity);

auto powerUpTransform = hitEntity->get<Transform>();

auto count = 10;

for (auto i = 0; i < count; ++i) {
auto particleEntity = createEntity();

auto particle = particleEntity->add<Particle>();
particle->duration = 5.0f;

auto transform = particleEntity->add<Transform>();
transform->scale = glm::vec3(0.5f);
transform->position = powerUpTransform->position;

particleEntity->add<PhysicalState>(transform->position, 0.0f);

auto velocity = particleEntity->add<Velocity>();
velocity->velocity = glm::angleAxis(glm::two_pi<float>() / static_cast<float>(count) * static_cast<float>(i), glm::vec3(0.0f, 0.0f, 1.0f)) * glm::vec3(1.0f, 0.0f, 0.0f) * 2.5f;

auto circle = particleEntity->add<Circle>();
circle->feature = new CircleFeature();
circle->feature->color = { 0.0f, 1.0f, 0.0f };
circle->renderable = _renderer.create(std::unique_ptr<CircleFeature>(circle->feature));
circle.setRemovalListener([circle](const Entity e) {
circle->renderable->destroy();
});
}
break;
}

hitEntity->destroy();
} else if (hitEntity->has<Bomb>()) {
_spellDatabase.getSpellById(3).action->execute(playerEntity);

auto bombTransform = hitEntity->get<Transform>();

auto emitterEntity = createEntity();
auto emitterEntityId = emitterEntity->getId();

auto emitterTransform = emitterEntity->add<Transform>();
emitterTransform->position = bombTransform->position;
emitterTransform->position.z = 0.0f;

auto emitter = emitterEntity->add<Emitter>([this, emitterEntityId]() {
auto emitterEntity = getEntityById(emitterEntityId);
auto emitterTransform = emitterEntity->get<Transform>();

auto randomScale = std::uniform_real_distribution(0.5f, 0.75f);
auto randomDirection = std::uniform_real_distribution(0.0f, glm::two_pi<float>());
auto randomSpeed = std::uniform_real_distribution(3.5f, 4.0f);
auto randomColor = std::uniform_int_distribution(0, 3);

auto particleEntity = createEntity();

auto particle = particleEntity->add<Particle>();
particle->duration = 2.0f;
particle->scalePerSecond = -0.5f;

auto transform = particleEntity->add<Transform>();
transform->scale = glm::vec3(randomScale(_random));
transform->position = emitterTransform->position;

particleEntity->add<PhysicalState>(transform->position, 0.0f);

auto velocity = particleEntity->add<Velocity>();
velocity->velocity = glm::angleAxis(randomDirection(_random), glm::vec3(0.0f, 0.0f, 1.0f)) * glm::vec3(1.0f, 0.0f, 0.0f) * randomSpeed(_random);

auto circle = particleEntity->add<Circle>();
circle->feature = new CircleFeature();

switch (randomColor(_random)) {
case 0:
circle->feature->color = { 1.0f, 0.0f, 0.0f };
particle->scalePerSecond = -2.0f;
break;
case 1:
circle->feature->color = { 0.97345f, 0.36625f, 0.00561f };
particle->scalePerSecond = -2.0f;
break;
case 2:
circle->feature->color = { 0.78354f, 0.78354f, 0.78354f };
break;
}

circle->renderable = _renderer.create(std::unique_ptr<CircleFeature>(circle->feature));
circle.setRemovalListener([circle](const Entity e) {
circle->renderable->destroy();
});
});
emitter->frequency = 0.02f;
emitter->totalLifetime = 0.5f;

hitEntity->destroy();
}
}
Expand Down
7 changes: 5 additions & 2 deletions linguine/src/systems/ScoringSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace linguine {
class ScoringSystem : public System {
public:
explicit ScoringSystem(EntityManager& entityManager,
SpellDatabase& spellDatabase)
: System(entityManager), _spellDatabase(spellDatabase) {}
SpellDatabase& spellDatabase,
Renderer& renderer)
: System(entityManager), _spellDatabase(spellDatabase),
_renderer(renderer) {}

void update(float deltaTime) override;

Expand All @@ -22,6 +24,7 @@ class ScoringSystem : public System {
std::random_device _random;

SpellDatabase& _spellDatabase;
Renderer& _renderer;
};

} // namespace linguine

0 comments on commit bf66f8a

Please sign in to comment.