Pushing what I have.

This commit is contained in:
2025-01-06 17:06:54 -05:00
parent cf1537c8a8
commit 45ccc88794
19 changed files with 283 additions and 105 deletions

View File

@@ -2,6 +2,7 @@
#include <vector>
#include <Engine/types/InstancedTexture.h>
#include <Engine/types/entity/Entity.h>
#include <Engine/types/entity/Hud.h>
#include <JGL/types/RenderTarget.h>
@@ -10,45 +11,31 @@ namespace Engine {
class Scene;
}
using namespace JGL;
class Engine::Scene {
protected:
std::string name;
Hud* heads_up_display = nullptr;
Camera* active_camera = nullptr;
Entity* entity_list = nullptr;
std::vector<InstancedTexture*> instanced_textures{};
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:
[[nodiscard]] bool EntityListContains(const Entity* entity) const;
[[nodiscard]] Entity* GetEntityList() { return entity_list; }
[[nodiscard]] size_t EntityCount() const;
[[nodiscard]] std::string GetName() const;
[[nodiscard]] Camera* GetActiveCamera() const;
[[nodiscard]] InstancedTexture* GetInstancedTexture(const InstancedSprite* user);
[[nodiscard]] InstancedTexture* GetInstancedAlphaMask(const InstancedSprite* user);
public:
void SetActiveCamera(Camera* camera) { active_camera = camera; };
void DestroyInstancedTexture(const InstancedTexture* itx);
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 Init() {}
virtual void Update();
virtual void Render(RenderTarget* render_target = nullptr);
virtual void Render(JGL::RenderTarget* render_target = nullptr);
public:
explicit Scene(const std::string& name) : name(name) {}
explicit Scene(const std::string& name) : name(name) { entity_list = new Entity(); }
virtual ~Scene();
};

View 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;
};

View File

@@ -9,6 +9,8 @@ namespace Engine {
class Engine::Camera : public Entity, public Movable, public Renderable {
public:
void ShouldRender(bool state) override;
[[nodiscard]] bool ShouldRender() const override;
void Render() override {};
public:
explicit Camera(const Vector2& position) : Renderable(0), Movable(position) {}

View File

@@ -15,14 +15,17 @@ protected:
// Epoch micro-seconds.
long creation_time = 0.0f;
std::vector<Entity*> children{};
void UpdateChildren();
public:
void UpdateChildren();
// Parent child structure.
[[nodiscard]] bool AppendChild(Entity* entity);
void AppendChild(Entity* entity);
void DestroyChild(Entity* entity);
void RemoveChild(Entity* entity);
public:
[[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;
// Microseconds.

View File

@@ -1,12 +1,14 @@
#pragma once
#include <Engine/types/entity/Entity.h>
#include <Engine/types/entity/mixins/Renderable.h>
namespace Engine {
class Hud;
}
class Engine::Hud : public Engine::Renderable {
class Engine::Hud : public Entity, public Renderable {
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;
};

View 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;
};

View File

@@ -9,9 +9,9 @@ class Engine::BoxCollider {
private:
bool enabled = false;
public:
[[nodiscard]] virtual AABB2D GetBounds() = 0;
[[nodiscard]] bool BoxCollides(BoxCollider* rhs);
[[nodiscard]] bool BoxCollides(const Vector2& rhs);
[[nodiscard]] virtual AABB2D GetBounds() const = 0;
[[nodiscard]] bool BoxCollides(BoxCollider* rhs) const;
[[nodiscard]] bool BoxCollides(const Vector2& rhs) const;
public:
void EnableBoxCollision() { enabled = true; }
void DisableBoxCollision() { enabled = false; }

View 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;
};

View File

@@ -1,21 +1,23 @@
#pragma once
#include <Engine/types/entity/Entity.h>
namespace Engine {
class Renderable;
}
class Engine::Renderable {
protected:
// Higher numbers are farther to the back.
private:
unsigned int layer = 0;
bool should_render = true;
public:
[[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:
void SetLayer(unsigned int new_layer) { layer = new_layer; }
virtual void ShouldRender(bool state) { should_render = state; }
// *must* be overridden.
virtual void Render() = 0;
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;
};

View File

@@ -10,5 +10,5 @@ class Game::Box final : public Engine::InstancedSprite {
public:
void Update() final;
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") {}
};

View File

@@ -6,7 +6,7 @@ class LoadingScreen final : public Engine::Scene {
protected:
float elapsed = 0.0f;
float angle = 0.0f;
Texture* RedactedSoftware = nullptr;
JGL::Texture* RedactedSoftware = nullptr;
public:
explicit LoadingScreen(const std::string& name) : Scene(name) {}