Pushing what I have.
This commit is contained in:
@@ -14,7 +14,7 @@ include (cmake/CPM.cmake)
|
|||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME JGL
|
NAME JGL
|
||||||
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-45.zip
|
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-46.zip
|
||||||
)
|
)
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Engine/types/InstancedTexture.h>
|
#include <Engine/types/InstancedTexture.h>
|
||||||
|
#include <Engine/types/entity/Entity.h>
|
||||||
#include <Engine/types/entity/Hud.h>
|
#include <Engine/types/entity/Hud.h>
|
||||||
#include <JGL/types/RenderTarget.h>
|
#include <JGL/types/RenderTarget.h>
|
||||||
|
|
||||||
@@ -10,45 +11,31 @@ namespace Engine {
|
|||||||
class Scene;
|
class Scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace JGL;
|
|
||||||
|
|
||||||
class Engine::Scene {
|
class Engine::Scene {
|
||||||
protected:
|
protected:
|
||||||
std::string name;
|
std::string name;
|
||||||
Hud* heads_up_display = nullptr;
|
|
||||||
Camera* active_camera = nullptr;
|
Camera* active_camera = nullptr;
|
||||||
|
Entity* entity_list = nullptr;
|
||||||
|
|
||||||
std::vector<InstancedTexture*> instanced_textures{};
|
std::vector<InstancedTexture*> instanced_textures{};
|
||||||
std::vector<InstancedTexture*> instanced_alpha_masks{};
|
std::vector<InstancedTexture*> instanced_alpha_masks{};
|
||||||
|
|
||||||
std::vector<RenderTarget*> layers{};
|
|
||||||
std::vector<Entity*> entity_list{};
|
|
||||||
protected:
|
|
||||||
[[nodiscard]] std::vector<Entity*> GetFlatEntityList(const std::vector<Entity*>& entity_list) const;
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] bool EntityListContains(const Entity* entity) const;
|
[[nodiscard]] Entity* GetEntityList() { return entity_list; }
|
||||||
[[nodiscard]] size_t EntityCount() const;
|
[[nodiscard]] size_t EntityCount() const;
|
||||||
[[nodiscard]] std::string GetName() const;
|
[[nodiscard]] std::string GetName() const;
|
||||||
[[nodiscard]] Camera* GetActiveCamera() const;
|
[[nodiscard]] Camera* GetActiveCamera() const;
|
||||||
[[nodiscard]] InstancedTexture* GetInstancedTexture(const InstancedSprite* user);
|
[[nodiscard]] InstancedTexture* GetInstancedTexture(const InstancedSprite* user);
|
||||||
[[nodiscard]] InstancedTexture* GetInstancedAlphaMask(const InstancedSprite* user);
|
[[nodiscard]] InstancedTexture* GetInstancedAlphaMask(const InstancedSprite* user);
|
||||||
|
public:
|
||||||
|
void SetActiveCamera(Camera* camera) { active_camera = camera; };
|
||||||
void DestroyInstancedTexture(const InstancedTexture* itx);
|
void DestroyInstancedTexture(const InstancedTexture* itx);
|
||||||
void DestroyInstancedAlphaMask(const InstancedTexture* alpha_mask);
|
void DestroyInstancedAlphaMask(const InstancedTexture* alpha_mask);
|
||||||
|
|
||||||
public:
|
|
||||||
void AppendEntity(Entity* entity);
|
|
||||||
|
|
||||||
// Removes and deallocates.
|
|
||||||
void DestroyEntity(Entity* entity);
|
|
||||||
|
|
||||||
// Only removes from the list.
|
|
||||||
void RemoveEntity(Entity* entity);
|
|
||||||
|
|
||||||
virtual void Unload();
|
virtual void Unload();
|
||||||
virtual void Init() {}
|
virtual void Init() {}
|
||||||
virtual void Update();
|
virtual void Update();
|
||||||
virtual void Render(RenderTarget* render_target = nullptr);
|
virtual void Render(JGL::RenderTarget* render_target = nullptr);
|
||||||
public:
|
public:
|
||||||
explicit Scene(const std::string& name) : name(name) {}
|
explicit Scene(const std::string& name) : name(name) { entity_list = new Entity(); }
|
||||||
virtual ~Scene();
|
virtual ~Scene();
|
||||||
};
|
};
|
||||||
|
32
include/Engine/types/Track.h
Normal file
32
include/Engine/types/Track.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Engine/types/entity/Entity.h>
|
||||||
|
#include <Engine/types/entity/mixins/Living.h>
|
||||||
|
#include <Engine/types/entity/mixins/Renderable.h>
|
||||||
|
|
||||||
|
namespace Engine {
|
||||||
|
class BoxCollider;
|
||||||
|
class Movable;
|
||||||
|
class Track;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I would expect you to set up such that the direct children would be made to perfectly
|
||||||
|
* follow the track. The children of those children would be offset by the parents
|
||||||
|
* movement every frame. This way, by default, Things could move on a train on the track. - Redacted. */
|
||||||
|
class Engine::Track : public Entity, public Renderable, public Living {
|
||||||
|
private:
|
||||||
|
std::vector<Vector2> nodes{};
|
||||||
|
std::vector<unsigned int> child_node_position{};
|
||||||
|
void TranslateChild(Entity* entity);
|
||||||
|
protected:
|
||||||
|
Vector2 GetNextNode(const Movable* movable);
|
||||||
|
public:
|
||||||
|
// Returns whether the track forms a perfect loop *the first node and last node are the same*
|
||||||
|
[[nodiscard]] bool Loops() const { return !nodes.empty() && nodes.front() == nodes.back(); }
|
||||||
|
/// @returns The nearest node to a given entity.
|
||||||
|
Vector2 ClosestNodeTo(const Movable* movable) const;
|
||||||
|
Vector2 ClosestNodeTo(const BoxCollider* box_collider) const;
|
||||||
|
|
||||||
|
void Render() override;
|
||||||
|
void Update() override;
|
||||||
|
};
|
@@ -9,6 +9,8 @@ namespace Engine {
|
|||||||
|
|
||||||
class Engine::Camera : public Entity, public Movable, public Renderable {
|
class Engine::Camera : public Entity, public Movable, public Renderable {
|
||||||
public:
|
public:
|
||||||
|
void ShouldRender(bool state) override;
|
||||||
|
[[nodiscard]] bool ShouldRender() const override;
|
||||||
void Render() override {};
|
void Render() override {};
|
||||||
public:
|
public:
|
||||||
explicit Camera(const Vector2& position) : Renderable(0), Movable(position) {}
|
explicit Camera(const Vector2& position) : Renderable(0), Movable(position) {}
|
||||||
|
@@ -15,14 +15,17 @@ protected:
|
|||||||
// Epoch micro-seconds.
|
// Epoch micro-seconds.
|
||||||
long creation_time = 0.0f;
|
long creation_time = 0.0f;
|
||||||
std::vector<Entity*> children{};
|
std::vector<Entity*> children{};
|
||||||
void UpdateChildren();
|
|
||||||
public:
|
public:
|
||||||
|
void UpdateChildren();
|
||||||
// Parent child structure.
|
// Parent child structure.
|
||||||
[[nodiscard]] bool AppendChild(Entity* entity);
|
void AppendChild(Entity* entity);
|
||||||
void DestroyChild(Entity* entity);
|
void DestroyChild(Entity* entity);
|
||||||
void RemoveChild(Entity* entity);
|
void RemoveChild(Entity* entity);
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] std::vector<Entity*> GetChildren() const;
|
[[nodiscard]] std::vector<Entity*> GetChildren() const;
|
||||||
|
[[nodiscard]] static std::vector<Entity*> GetAllDescendents(const Entity* entity);
|
||||||
|
[[nodiscard]] bool HasChildren() const { return !children.empty(); }
|
||||||
|
[[nodiscard]] bool HasParent() const { return parent; }
|
||||||
[[nodiscard]] Entity* GetParent() const;
|
[[nodiscard]] Entity* GetParent() const;
|
||||||
|
|
||||||
// Microseconds.
|
// Microseconds.
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <Engine/types/entity/Entity.h>
|
||||||
#include <Engine/types/entity/mixins/Renderable.h>
|
#include <Engine/types/entity/mixins/Renderable.h>
|
||||||
|
|
||||||
namespace Engine {
|
namespace Engine {
|
||||||
class Hud;
|
class Hud;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Engine::Hud : public Engine::Renderable {
|
class Engine::Hud : public Entity, public Renderable {
|
||||||
public:
|
public:
|
||||||
Hud() : Renderable(0) {};
|
/// You want these to be rendered last.
|
||||||
|
explicit Hud(const unsigned int layer = std::numeric_limits<unsigned int>::min()) : Renderable(layer) {};
|
||||||
~Hud() override = default;
|
~Hud() override = default;
|
||||||
};
|
};
|
||||||
|
51
include/Engine/types/entity/Trigger.h
Normal file
51
include/Engine/types/entity/Trigger.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <Engine/types/entity/Entity.h>
|
||||||
|
#include <Engine/types/entity/mixins/BoxCollider.h>
|
||||||
|
#include <Engine/types/entity/mixins/Movable.h>
|
||||||
|
#include <Engine/types/entity/mixins/Renderable.h>
|
||||||
|
#include <Engine/types/entity/mixins/Living.h>
|
||||||
|
|
||||||
|
namespace Engine {
|
||||||
|
class Trigger;
|
||||||
|
class DynamicTrigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inheribable trigger.
|
||||||
|
class Engine::Trigger : public Entity, public Living, public BoxCollider, public Movable, public Renderable {
|
||||||
|
protected:
|
||||||
|
Vector2 size;
|
||||||
|
public:
|
||||||
|
[[nodiscard]] AABB2D GetBounds() const override;
|
||||||
|
void Render() override;
|
||||||
|
void SetSize(const Vector2& new_size) { size = new_size; }
|
||||||
|
public:
|
||||||
|
explicit Trigger(const Vector2& position, const Vector2& size, bool enabled = true) :
|
||||||
|
size(size), Entity(), Living(enabled), BoxCollider(enabled), Movable(position), Renderable(0, false) {}
|
||||||
|
|
||||||
|
~Trigger() override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Engine::DynamicTrigger final : public Trigger {
|
||||||
|
private:
|
||||||
|
void RunActions();
|
||||||
|
std::function<bool()> condition = nullptr;
|
||||||
|
std::vector<std::function<void()>> actions{};
|
||||||
|
public:
|
||||||
|
void Update() final;
|
||||||
|
void SetCondition(const std::function<bool()>& condition);
|
||||||
|
void AddAction(const std::function<void()>& action);
|
||||||
|
void ClearActions();
|
||||||
|
public:
|
||||||
|
explicit DynamicTrigger(const Vector2& position, const Vector2& size, bool enabled = true) : Trigger(position, size, enabled) {};
|
||||||
|
|
||||||
|
DynamicTrigger(const Vector2& position, const Vector2& size, bool enabled, const std::function<bool()>& condition, const std::vector<std::function<void()>>& actions)
|
||||||
|
: condition(condition), actions(actions), Trigger(position, size, enabled) {}
|
||||||
|
|
||||||
|
DynamicTrigger(const Vector2& position, const Vector2& size, bool enabled, const std::function<bool()>& condition, const std::function<void()>& action) :
|
||||||
|
Trigger(position, size, enabled) , condition(condition) { actions.push_back(action); }
|
||||||
|
|
||||||
|
~DynamicTrigger() final = default;
|
||||||
|
};
|
@@ -9,9 +9,9 @@ class Engine::BoxCollider {
|
|||||||
private:
|
private:
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] virtual AABB2D GetBounds() = 0;
|
[[nodiscard]] virtual AABB2D GetBounds() const = 0;
|
||||||
[[nodiscard]] bool BoxCollides(BoxCollider* rhs);
|
[[nodiscard]] bool BoxCollides(BoxCollider* rhs) const;
|
||||||
[[nodiscard]] bool BoxCollides(const Vector2& rhs);
|
[[nodiscard]] bool BoxCollides(const Vector2& rhs) const;
|
||||||
public:
|
public:
|
||||||
void EnableBoxCollision() { enabled = true; }
|
void EnableBoxCollision() { enabled = true; }
|
||||||
void DisableBoxCollision() { enabled = false; }
|
void DisableBoxCollision() { enabled = false; }
|
||||||
|
16
include/Engine/types/entity/mixins/Living.h
Normal file
16
include/Engine/types/entity/mixins/Living.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Engine {
|
||||||
|
class Living;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Engine::Living {
|
||||||
|
protected:
|
||||||
|
bool alive = true;
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool IsAlive() { return alive; }
|
||||||
|
void SetAlive(bool state) { alive = state; }
|
||||||
|
public:
|
||||||
|
explicit Living(bool alive = true) : alive(alive) {}
|
||||||
|
virtual ~Living() = default;
|
||||||
|
};
|
@@ -1,21 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Engine/types/entity/Entity.h>
|
|
||||||
|
|
||||||
namespace Engine {
|
namespace Engine {
|
||||||
class Renderable;
|
class Renderable;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Engine::Renderable {
|
class Engine::Renderable {
|
||||||
protected:
|
private:
|
||||||
// Higher numbers are farther to the back.
|
|
||||||
unsigned int layer = 0;
|
unsigned int layer = 0;
|
||||||
|
bool should_render = true;
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] unsigned int GetLayer() const { return layer; }
|
[[nodiscard]] unsigned int GetLayer() const { return layer; }
|
||||||
void SetLayer(unsigned int new_layer) { layer = new_layer; }
|
[[nodiscard]] virtual bool ShouldRender() const { return should_render; };
|
||||||
public:
|
public:
|
||||||
|
void SetLayer(unsigned int new_layer) { layer = new_layer; }
|
||||||
|
virtual void ShouldRender(bool state) { should_render = state; }
|
||||||
// *must* be overridden.
|
// *must* be overridden.
|
||||||
virtual void Render() = 0;
|
virtual void Render() = 0;
|
||||||
public:
|
public:
|
||||||
explicit Renderable(unsigned int layer) : layer(layer) {}
|
// The default layer is 1 because zero would almost always be the HUD / score / some kind of overlay.
|
||||||
|
explicit Renderable(unsigned int layer = 1, bool should_render = true) : should_render(should_render), layer(layer) {}
|
||||||
virtual ~Renderable() = default;
|
virtual ~Renderable() = default;
|
||||||
};
|
};
|
@@ -10,5 +10,5 @@ class Game::Box final : public Engine::InstancedSprite {
|
|||||||
public:
|
public:
|
||||||
void Update() final;
|
void Update() final;
|
||||||
public:
|
public:
|
||||||
explicit Box(const Vector2& position, unsigned int depth = 0, float rad_rotation = 0.0f) : Engine::InstancedSprite(position, depth, "assets/sprites/Re3D.png", rad_rotation, Colors::White, nullptr, "assets/sprites/alpha_mask.png") {}
|
explicit Box(const Vector2& position, unsigned int layer = 1, float rad_rotation = 0.0f) : Engine::InstancedSprite(position, layer, "assets/sprites/Re3D.png", rad_rotation, Colors::White, nullptr, "assets/sprites/alpha_mask.png") {}
|
||||||
};
|
};
|
@@ -6,7 +6,7 @@ class LoadingScreen final : public Engine::Scene {
|
|||||||
protected:
|
protected:
|
||||||
float elapsed = 0.0f;
|
float elapsed = 0.0f;
|
||||||
float angle = 0.0f;
|
float angle = 0.0f;
|
||||||
Texture* RedactedSoftware = nullptr;
|
JGL::Texture* RedactedSoftware = nullptr;
|
||||||
public:
|
public:
|
||||||
explicit LoadingScreen(const std::string& name) : Scene(name) {}
|
explicit LoadingScreen(const std::string& name) : Scene(name) {}
|
||||||
|
|
||||||
|
@@ -5,36 +5,21 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace Engine;
|
using namespace Engine;
|
||||||
bool Scene::EntityListContains(const Entity* entity) const {
|
|
||||||
auto flat = GetFlatEntityList(entity_list);
|
|
||||||
|
|
||||||
for (auto* e : flat)
|
|
||||||
if (e == entity)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Scene::EntityCount() const {
|
size_t Scene::EntityCount() const {
|
||||||
return GetFlatEntityList(entity_list).size();
|
return Entity::GetAllDescendents(entity_list).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::Update() {
|
void Scene::Update() {
|
||||||
if (active_camera)
|
entity_list->UpdateChildren();
|
||||||
active_camera->Update();
|
|
||||||
|
|
||||||
for (auto& e : entity_list)
|
|
||||||
if (auto* c = dynamic_cast<Camera*>(e); c == nullptr)
|
|
||||||
e->Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::Render(RenderTarget* render_target) {
|
void Scene::Render(RenderTarget* render_target) {
|
||||||
// The Camera and the HUD are ignored here because they're special cases.
|
// The Camera and the HUD are ignored here because they're special cases.
|
||||||
std::vector<Renderable*> display_list{};
|
std::vector<Renderable*> display_list{};
|
||||||
for (auto* e : GetFlatEntityList(entity_list))
|
for (auto* e : Entity::GetAllDescendents(entity_list))
|
||||||
if (auto* r = dynamic_cast<Renderable*>(e))
|
if (auto* r = dynamic_cast<Renderable*>(e))
|
||||||
if (auto* c = dynamic_cast<Camera*>(r); c == nullptr)
|
if (r->ShouldRender())
|
||||||
if (auto* h = dynamic_cast<Hud*>(c); h == nullptr)
|
display_list.push_back(r);
|
||||||
display_list.push_back(r);
|
|
||||||
|
|
||||||
std::sort(display_list.begin(), display_list.end(), [](Renderable* a, Renderable* b) {
|
std::sort(display_list.begin(), display_list.end(), [](Renderable* a, Renderable* b) {
|
||||||
return a->GetLayer() > b->GetLayer();
|
return a->GetLayer() > b->GetLayer();
|
||||||
@@ -46,50 +31,32 @@ void Scene::Render(RenderTarget* render_target) {
|
|||||||
active_camera->Render();
|
active_camera->Render();
|
||||||
|
|
||||||
for (auto& r : display_list)
|
for (auto& r : display_list)
|
||||||
r->Render();
|
if (r->ShouldRender())
|
||||||
|
r->Render();
|
||||||
if (heads_up_display)
|
|
||||||
heads_up_display->Render();
|
|
||||||
|
|
||||||
J2D::End();
|
J2D::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
for (auto* e : entity_list)
|
|
||||||
delete e;
|
|
||||||
|
|
||||||
for (auto* itx : instanced_textures)
|
for (auto* itx : instanced_textures)
|
||||||
delete itx;
|
delete itx;
|
||||||
|
|
||||||
for (auto* a : instanced_alpha_masks)
|
for (auto* a : instanced_alpha_masks)
|
||||||
delete a;
|
delete a;
|
||||||
|
|
||||||
delete heads_up_display;
|
delete entity_list;;
|
||||||
delete active_camera;
|
delete active_camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::Unload() {
|
void Scene::Unload() {
|
||||||
for (auto* e : entity_list)
|
for (auto* itx : instanced_textures)
|
||||||
delete e;
|
delete itx;
|
||||||
|
|
||||||
delete heads_up_display;
|
for (auto* a : instanced_alpha_masks)
|
||||||
}
|
delete a;
|
||||||
|
|
||||||
void Scene::AppendEntity(Entity* entity) {
|
delete entity_list;
|
||||||
if (!EntityListContains(entity))
|
delete active_camera;
|
||||||
entity_list.push_back(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::DestroyEntity(Entity *entity) {
|
|
||||||
auto it = std::find(entity_list.begin(), entity_list.end(), entity);
|
|
||||||
if (it != entity_list.end())
|
|
||||||
delete *it, entity_list.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::RemoveEntity(Entity* entity) {
|
|
||||||
auto it = std::find(entity_list.begin(), entity_list.end(), entity);
|
|
||||||
if (it != entity_list.end())
|
|
||||||
entity_list.erase(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Scene::GetName() const {
|
std::string Scene::GetName() const {
|
||||||
@@ -100,18 +67,6 @@ Camera* Scene::GetActiveCamera() const {
|
|||||||
return active_camera;
|
return active_camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Entity*> Scene::GetFlatEntityList(const std::vector<Entity*>& ent_list) const {
|
|
||||||
std::vector<Entity*> result{};
|
|
||||||
|
|
||||||
for (auto* e : ent_list) {
|
|
||||||
auto children = GetFlatEntityList(e->GetChildren());
|
|
||||||
for (auto* c : children)
|
|
||||||
result.push_back(c);
|
|
||||||
result.push_back(e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
InstancedTexture* Scene::GetInstancedTexture(const InstancedSprite* user) {
|
InstancedTexture* Scene::GetInstancedTexture(const InstancedSprite* user) {
|
||||||
for (auto* itx : instanced_textures)
|
for (auto* itx : instanced_textures)
|
||||||
if (itx->InUseBy(user))
|
if (itx->InUseBy(user))
|
||||||
|
62
src/Engine/types/Track.cpp
Normal file
62
src/Engine/types/Track.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#include <Engine/types/Track.h>
|
||||||
|
#include <Engine/types/entity/mixins/Movable.h>
|
||||||
|
#include <Engine/types/entity/mixins/BoxCollider.h>
|
||||||
|
#include <JGL/JGL.h>
|
||||||
|
|
||||||
|
using namespace Engine;
|
||||||
|
void Track::Render() {
|
||||||
|
if (!nodes.empty())
|
||||||
|
J2D::DrawLines(Colors::Purples::DarkViolet, nodes.data(), nodes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Track::ClosestNodeTo(const Movable* movable) const {
|
||||||
|
if (nodes.empty())
|
||||||
|
throw std::runtime_error("Getting the closest node to a given movable but there is no nodes?");
|
||||||
|
|
||||||
|
Vector2 result;
|
||||||
|
float minimum = std::numeric_limits<float>::max();
|
||||||
|
for (const auto& n : nodes) {
|
||||||
|
float distance_sq = Vector2::DistanceSq(n, movable->GetPosition());
|
||||||
|
if (distance_sq < minimum)
|
||||||
|
minimum = distance_sq, result = n;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Track::ClosestNodeTo(const BoxCollider* box_collider) const {
|
||||||
|
if (nodes.empty())
|
||||||
|
throw std::runtime_error("Getting the closest node to a given box_collider but there is no nodes?");
|
||||||
|
|
||||||
|
Vector2 result;
|
||||||
|
float minimum = std::numeric_limits<float>::max();
|
||||||
|
auto aabb_minimum = box_collider->GetBounds().minPoint;
|
||||||
|
auto aabb_maximum = box_collider->GetBounds().maxPoint;
|
||||||
|
|
||||||
|
for (const auto& n : nodes) {
|
||||||
|
Vector2 closest_aabb_point_to_current_node = { std::max(aabb_minimum.x, std::min(n.x, aabb_maximum.x)), std::max(aabb_minimum.y, std::min(n.y, aabb_maximum.y)) };
|
||||||
|
float distance_squared = Vector2::DistanceSq(n, closest_aabb_point_to_current_node);
|
||||||
|
|
||||||
|
if (distance_squared < minimum)
|
||||||
|
minimum = distance_squared, result = n;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Track::Update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Track::TranslateChild(Entity* entity) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (auto* m = dynamic_cast<Movable*>(entity))
|
||||||
|
m->Move()
|
||||||
|
auto m_pos = movable->GetPosition();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 Track::GetNextNode(const Movable* movable) {
|
||||||
|
auto m_pos = movable->GetPosition();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
11
src/Engine/types/entity/Camera.cpp
Normal file
11
src/Engine/types/entity/Camera.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <Engine/types/entity/Camera.h>
|
||||||
|
#include <Engine/Globals.h>
|
||||||
|
|
||||||
|
void Engine::Camera::ShouldRender(bool state) {
|
||||||
|
if (state)
|
||||||
|
Globals::CurrentScene->SetActiveCamera(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Engine::Camera::ShouldRender() const {
|
||||||
|
return Globals::CurrentScene->GetActiveCamera() == this;
|
||||||
|
}
|
@@ -2,13 +2,12 @@
|
|||||||
#include <Engine/types/entity/Entity.h>
|
#include <Engine/types/entity/Entity.h>
|
||||||
#include <Engine/Globals.h>
|
#include <Engine/Globals.h>
|
||||||
|
|
||||||
bool Engine::Entity::AppendChild(Entity* entity) {
|
void Engine::Entity::AppendChild(Entity* entity) {
|
||||||
if (!Globals::CurrentScene->EntityListContains(entity)) {
|
if (entity->parent)
|
||||||
entity->parent = this;
|
entity->parent->RemoveChild(entity);
|
||||||
children.push_back(entity);
|
|
||||||
return true;
|
entity->parent = this;
|
||||||
}
|
children.push_back(entity);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::Entity::~Entity() {
|
Engine::Entity::~Entity() {
|
||||||
@@ -34,6 +33,7 @@ void Engine::Entity::RemoveChild(Entity* entity) {
|
|||||||
auto it = std::find(children.begin(), children.end(), entity);
|
auto it = std::find(children.begin(), children.end(), entity);
|
||||||
if (it != children.end())
|
if (it != children.end())
|
||||||
children.erase(it);
|
children.erase(it);
|
||||||
|
entity->parent = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
long Engine::Entity::GetCreationTime() const {
|
long Engine::Entity::GetCreationTime() const {
|
||||||
@@ -51,3 +51,16 @@ Engine::Entity* Engine::Entity::GetParent() const {
|
|||||||
std::vector<Engine::Entity*> Engine::Entity::GetChildren() const {
|
std::vector<Engine::Entity*> Engine::Entity::GetChildren() const {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Engine::Entity*> Engine::Entity::GetAllDescendents(const Engine::Entity* entity) {
|
||||||
|
std::vector<Engine::Entity*> result = entity->GetChildren();
|
||||||
|
|
||||||
|
if (result.empty())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
for (auto* c : entity->GetChildren()) {
|
||||||
|
auto descendants = Entity::GetAllDescendents(c);
|
||||||
|
result.insert(result.end(), descendants.begin(), descendants.end());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
42
src/Engine/types/entity/Trigger.cpp
Normal file
42
src/Engine/types/entity/Trigger.cpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include <Engine/types/entity/Trigger.h>
|
||||||
|
#include <JGL/JGL.h>
|
||||||
|
|
||||||
|
using namespace Engine;
|
||||||
|
|
||||||
|
void Trigger::Render() {
|
||||||
|
if (ShouldRender()) {
|
||||||
|
auto size = GetBounds().maxPoint - GetBounds().minPoint;
|
||||||
|
J2D::OutlineRect(Colors::Red, position, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AABB2D Trigger::GetBounds() const {
|
||||||
|
return { position, position + size };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DynamicTrigger::AddAction(const std::function<void()>& action) {
|
||||||
|
actions.push_back(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicTrigger::Update() {
|
||||||
|
bool success = false;
|
||||||
|
if (condition)
|
||||||
|
success = condition();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
RunActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicTrigger::RunActions() {
|
||||||
|
for (const auto& a : actions)
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicTrigger::ClearActions() {
|
||||||
|
actions = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicTrigger::SetCondition(const std::function<bool()> & c) {
|
||||||
|
condition = c;
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
#include <Engine/types/entity/mixins/BoxCollider.h>
|
#include <Engine/types/entity/mixins/BoxCollider.h>
|
||||||
|
|
||||||
using namespace Engine;
|
using namespace Engine;
|
||||||
bool BoxCollider::BoxCollides(BoxCollider* rhs) {
|
bool BoxCollider::BoxCollides(BoxCollider* rhs) const {
|
||||||
if (GetBounds().Intersects(rhs->GetBounds()))
|
if (GetBounds().Intersects(rhs->GetBounds()))
|
||||||
return true;
|
return true;
|
||||||
if (GetBounds().Contains(rhs->GetBounds()))
|
if (GetBounds().Contains(rhs->GetBounds()))
|
||||||
@@ -9,6 +9,6 @@ bool BoxCollider::BoxCollides(BoxCollider* rhs) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BoxCollider::BoxCollides(const Vector2& rhs) {
|
bool BoxCollider::BoxCollides(const Vector2& rhs) const {
|
||||||
return GetBounds().Contains(rhs);
|
return GetBounds().Contains(rhs);
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,6 @@
|
|||||||
void ControllableBox::Init() {
|
void ControllableBox::Init() {
|
||||||
auto* hud = new Game::DemoGameHud();
|
auto* hud = new Game::DemoGameHud();
|
||||||
auto *b = new Game::Box({0, 0});
|
auto *b = new Game::Box({0, 0});
|
||||||
AppendEntity(b);
|
entity_list->AppendChild(b);
|
||||||
heads_up_display = hud;
|
entity_list->AppendChild(hud);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user