Refactor components
parent
773329605b
commit
728f84325c
|
|
@ -112,6 +112,8 @@ struct NullZoneComponent : public Component {
|
||||||
|
|
||||||
struct ColliderComponent : public Component {
|
struct ColliderComponent : public Component {
|
||||||
float radius = 8.0f;
|
float radius = 8.0f;
|
||||||
|
bool monitoring = false;
|
||||||
|
bool monitorable = true;
|
||||||
std::vector<std::function<void(Entity &)>> onCollision;
|
std::vector<std::function<void(Entity &)>> onCollision;
|
||||||
void Setup() override {}
|
void Setup() override {}
|
||||||
|
|
||||||
|
|
@ -125,7 +127,35 @@ struct ColliderComponent : public Component {
|
||||||
onCollision.push_back(std::move(callback));
|
onCollision.push_back(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(float) override {}
|
void Update(float) override {
|
||||||
|
if (!monitoring || !context || !context->entities || entity->queuedForFree) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto selfTransform = entity->GetComponent<TransformComponent>();
|
||||||
|
if (!selfTransform) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &other : *context->entities) {
|
||||||
|
if (!other || other.get() == entity || other->queuedForFree) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto otherCollider = other->GetComponent<ColliderComponent>();
|
||||||
|
auto otherTransform = other->GetComponent<TransformComponent>();
|
||||||
|
if (!otherCollider || !otherTransform || !otherCollider->get().monitorable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float dx = selfTransform->get().x - otherTransform->get().x;
|
||||||
|
const float dy = selfTransform->get().y - otherTransform->get().y;
|
||||||
|
const float r = radius + otherCollider->get().radius;
|
||||||
|
if ((dx * dx + dy * dy) <= (r * r)) {
|
||||||
|
EmitCollision(*other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void Cleanup() override {}
|
void Cleanup() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -166,22 +196,35 @@ struct ProjectionComponent : public Component {
|
||||||
void Cleanup() override {}
|
void Cleanup() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CollectibleComponent : public Component {
|
struct LifetimeComponent : public Component {
|
||||||
bool collected = false;
|
float remaining = 0.0f;
|
||||||
|
void Setup() override {}
|
||||||
|
void Update(float dt) override {
|
||||||
|
remaining -= dt;
|
||||||
|
if (remaining <= 0.0f) {
|
||||||
|
entity->QueueFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Cleanup() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CollectibleComponent : public Component {
|
||||||
void Setup() override {
|
void Setup() override {
|
||||||
auto selfCollider = entity->GetComponent<ColliderComponent>();
|
auto selfCollider = entity->GetComponent<ColliderComponent>();
|
||||||
if (!selfCollider) {
|
if (!selfCollider) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selfCollider->get().monitoring = true;
|
||||||
|
|
||||||
selfCollider->get().AddCollisionListener([this](Entity &other) {
|
selfCollider->get().AddCollisionListener([this](Entity &other) {
|
||||||
if (collected || !context || !context->probeEntity || &other != context->probeEntity) {
|
if (entity->queuedForFree || !context || !context->probeEntity ||
|
||||||
|
&other != context->probeEntity) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
collected = true;
|
|
||||||
context->EmitCollectiblePicked(*entity);
|
context->EmitCollectiblePicked(*entity);
|
||||||
|
entity->QueueFree();
|
||||||
|
|
||||||
if (!context->hudEntity) {
|
if (!context->hudEntity) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -208,6 +251,8 @@ struct HazardComponent : public Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selfCollider->get().monitoring = true;
|
||||||
|
|
||||||
selfCollider->get().AddCollisionListener([this](Entity &other) {
|
selfCollider->get().AddCollisionListener([this](Entity &other) {
|
||||||
if (!context || !context->probeEntity || &other != context->probeEntity) {
|
if (!context || !context->probeEntity || &other != context->probeEntity) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ std::shared_ptr<Entity> CreateProbe() {
|
||||||
|
|
||||||
auto &collider = e->AddComponent<ColliderComponent>();
|
auto &collider = e->AddComponent<ColliderComponent>();
|
||||||
collider.radius = 7.0f;
|
collider.radius = 7.0f;
|
||||||
|
collider.monitorable = true;
|
||||||
|
|
||||||
auto &probeState = e->AddComponent<ProbeStateComponent>();
|
auto &probeState = e->AddComponent<ProbeStateComponent>();
|
||||||
probeState.spawnX = 96.0f;
|
probeState.spawnX = 96.0f;
|
||||||
|
|
@ -107,6 +108,32 @@ std::shared_ptr<Entity> CreateAsteroid(float x, float y) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Entity> CreateDebris(float x, float y, float vx, float vy, float ttl = 1.25f) {
|
||||||
|
auto e = std::make_shared<Entity>();
|
||||||
|
auto &t = e->AddComponent<TransformComponent>();
|
||||||
|
t.x = x;
|
||||||
|
t.y = y;
|
||||||
|
|
||||||
|
auto &physics = e->AddComponent<PhysicsComponent>();
|
||||||
|
physics.vx = vx;
|
||||||
|
physics.vy = vy;
|
||||||
|
physics.speedCap = 260.0f;
|
||||||
|
|
||||||
|
auto &lifetime = e->AddComponent<LifetimeComponent>();
|
||||||
|
lifetime.remaining = ttl;
|
||||||
|
|
||||||
|
auto &render = e->AddComponent<RenderComponent>();
|
||||||
|
render.draw = [e]() {
|
||||||
|
auto transform = e->GetComponent<TransformComponent>();
|
||||||
|
if (!transform) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DrawCircleV({transform->get().x, transform->get().y}, 3.0f, Color{245, 196, 104, 220});
|
||||||
|
};
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<Entity> CreateNullZone(float x, float width) {
|
std::shared_ptr<Entity> CreateNullZone(float x, float width) {
|
||||||
auto e = std::make_shared<Entity>();
|
auto e = std::make_shared<Entity>();
|
||||||
auto &t = e->AddComponent<TransformComponent>();
|
auto &t = e->AddComponent<TransformComponent>();
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,19 @@ inline void GameplayScene::Enter() {
|
||||||
meterValue = 60.0f;
|
meterValue = 60.0f;
|
||||||
|
|
||||||
context.onPlayerDeath = [this]() { wantsDeathScene = true; };
|
context.onPlayerDeath = [this]() { wantsDeathScene = true; };
|
||||||
context.AddCollectiblePickedListener([this](Entity &) { ++collectedCount; });
|
context.AddCollectiblePickedListener([this](Entity &collectible) {
|
||||||
|
++collectedCount;
|
||||||
|
|
||||||
|
auto transform = collectible.GetComponent<TransformComponent>();
|
||||||
|
if (!transform || !context.entities) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.entities->push_back(
|
||||||
|
CreateDebris(transform->get().x - 4.0f, transform->get().y, -22.0f, -36.0f));
|
||||||
|
context.entities->push_back(
|
||||||
|
CreateDebris(transform->get().x + 4.0f, transform->get().y, 24.0f, -28.0f));
|
||||||
|
});
|
||||||
context.AddMeterChangedListener([this](float, float newValue) { meterValue = newValue; });
|
context.AddMeterChangedListener([this](float, float newValue) { meterValue = newValue; });
|
||||||
|
|
||||||
entities.push_back(CreateWorld());
|
entities.push_back(CreateWorld());
|
||||||
|
|
@ -164,10 +176,29 @@ inline void GameplayScene::Enter() {
|
||||||
if (auto meter = entities.back()->GetComponent<MeterComponent>()) {
|
if (auto meter = entities.back()->GetComponent<MeterComponent>()) {
|
||||||
meterValue = meter->get().value;
|
meterValue = meter->get().value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.entities = &entities;
|
||||||
|
context.worldEntity = (entities.size() > 0 && entities[0]) ? entities[0].get() : nullptr;
|
||||||
|
context.wellEntity = (entities.size() > 1 && entities[1]) ? entities[1].get() : nullptr;
|
||||||
|
context.probeEntity = (entities.size() > 2 && entities[2]) ? entities[2].get() : nullptr;
|
||||||
|
context.hudEntity = (!entities.empty() && entities.back()) ? entities.back().get() : nullptr;
|
||||||
|
|
||||||
|
for (auto &entity : entities) {
|
||||||
|
if (!entity) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entity->SetContext(&context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GameplayScene::Update(float dt) {
|
inline void GameplayScene::Update(float dt) {
|
||||||
UpdateAllSystems(entities, context, dt);
|
UpdateAllSystems(entities, dt);
|
||||||
|
|
||||||
|
context.worldEntity = (entities.size() > 0 && entities[0]) ? entities[0].get() : nullptr;
|
||||||
|
context.wellEntity = (entities.size() > 1 && entities[1]) ? entities[1].get() : nullptr;
|
||||||
|
context.probeEntity = (entities.size() > 2 && entities[2]) ? entities[2].get() : nullptr;
|
||||||
|
context.hudEntity = (!entities.empty() && entities.back()) ? entities.back().get() : nullptr;
|
||||||
|
|
||||||
if (wantsDeathScene) {
|
if (wantsDeathScene) {
|
||||||
manager.QueueSceneChange<DeathScene>();
|
manager.QueueSceneChange<DeathScene>();
|
||||||
}
|
}
|
||||||
|
|
@ -195,12 +226,7 @@ inline void GameplayScene::Draw() {
|
||||||
DrawText(TextFormat("stars: %i", collectedCount), 14, 100, 16, Color{255, 223, 86, 255});
|
DrawText(TextFormat("stars: %i", collectedCount), 14, 100, 16, Color{255, 223, 86, 255});
|
||||||
|
|
||||||
for (auto &entity : entities) {
|
for (auto &entity : entities) {
|
||||||
if (!entity) {
|
if (!entity || entity->queuedForFree) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto collectible = entity->GetComponent<CollectibleComponent>();
|
|
||||||
if (collectible && collectible->get().collected) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Components.hpp"
|
|
||||||
#include "Entity.hpp"
|
#include "Entity.hpp"
|
||||||
#include "GameContext.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
void UpdateAllSystems(std::vector<std::shared_ptr<Entity>> &entities, GameContext &context,
|
void UpdateAllSystems(std::vector<std::shared_ptr<Entity>> &entities, float deltaTime) {
|
||||||
float deltaTime) {
|
|
||||||
context.entities = &entities;
|
|
||||||
context.worldEntity = (entities.size() > 0 && entities[0]) ? entities[0].get() : nullptr;
|
|
||||||
context.wellEntity = (entities.size() > 1 && entities[1]) ? entities[1].get() : nullptr;
|
|
||||||
context.probeEntity = (entities.size() > 2 && entities[2]) ? entities[2].get() : nullptr;
|
|
||||||
context.hudEntity = (!entities.empty() && entities.back()) ? entities.back().get() : nullptr;
|
|
||||||
|
|
||||||
for (auto &entity : entities) {
|
for (auto &entity : entities) {
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->context != &context) {
|
|
||||||
entity->SetContext(&context);
|
|
||||||
}
|
|
||||||
|
|
||||||
entity->Update(deltaTime);
|
entity->Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < entities.size(); ++i) {
|
|
||||||
auto &a = entities[i];
|
|
||||||
if (!a) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto aTransform = a->GetComponent<TransformComponent>();
|
|
||||||
auto aCollider = a->GetComponent<ColliderComponent>();
|
|
||||||
if (!aTransform || !aCollider) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t j = i + 1; j < entities.size(); ++j) {
|
|
||||||
auto &b = entities[j];
|
|
||||||
if (!b) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto bTransform = b->GetComponent<TransformComponent>();
|
|
||||||
auto bCollider = b->GetComponent<ColliderComponent>();
|
|
||||||
if (!bTransform || !bCollider) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float dx = aTransform->get().x - bTransform->get().x;
|
|
||||||
const float dy = aTransform->get().y - bTransform->get().y;
|
|
||||||
const float r = aCollider->get().radius + bCollider->get().radius;
|
|
||||||
if ((dx * dx + dy * dy) <= (r * r)) {
|
|
||||||
aCollider->get().EmitCollision(*b);
|
|
||||||
bCollider->get().EmitCollision(*a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto remover = [](const std::shared_ptr<Entity> &entity) {
|
auto remover = [](const std::shared_ptr<Entity> &entity) {
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue