A few things
Make child entites work. z-sort entity list before rendering. entites have a creation timestamp.
This commit is contained in:
@@ -22,7 +22,7 @@ CPMAddPackage(
|
|||||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-26.zip
|
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-26.zip
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
|
#set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
|
||||||
|
|
||||||
file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp")
|
file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp")
|
||||||
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp")
|
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp")
|
||||||
|
@@ -9,5 +9,5 @@ class Engine::Camera : public Renderable {
|
|||||||
public:
|
public:
|
||||||
void Render() override {};
|
void Render() override {};
|
||||||
public:
|
public:
|
||||||
explicit Camera(const Vector2& position) : Renderable(position) {}
|
explicit Camera(const Vector2& position) : Renderable(position, 0) {}
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace Engine {
|
namespace Engine {
|
||||||
class Entity;
|
class Entity;
|
||||||
@@ -8,15 +9,21 @@ namespace Engine {
|
|||||||
|
|
||||||
class Engine::Entity {
|
class Engine::Entity {
|
||||||
protected:
|
protected:
|
||||||
|
// nullptr means no parent.
|
||||||
|
Entity* parent = nullptr;
|
||||||
|
|
||||||
|
// Epoch micro-seconds.
|
||||||
|
long creation_time = 0.0f;
|
||||||
std::vector<Entity*> children{};
|
std::vector<Entity*> children{};
|
||||||
Vector2 position = {0, 0};
|
Vector2 position = {0, 0};
|
||||||
// Assuming 0 radians is up.
|
// Assuming 0 radians is up.
|
||||||
float face_angle = 0.0f;
|
float face_angle = 0.0f;
|
||||||
void UpdateChildren();
|
void UpdateChildren();
|
||||||
public:
|
public:
|
||||||
// Movements independent of the rotation.
|
// Movements independent of the face_angle.
|
||||||
void MoveX(float speed);
|
void MoveX(float speed);
|
||||||
void MoveY(float speed);
|
void MoveY(float speed);
|
||||||
|
void Move(float angle_rad, float speed);
|
||||||
|
|
||||||
// Movements dependent on face angle.
|
// Movements dependent on face angle.
|
||||||
void MoveForward(float speed);
|
void MoveForward(float speed);
|
||||||
@@ -24,20 +31,29 @@ public:
|
|||||||
void MoveLeft(float speed);
|
void MoveLeft(float speed);
|
||||||
void MoveRight(float speed);
|
void MoveRight(float speed);
|
||||||
|
|
||||||
void Move(float angle_rad, float speed);
|
|
||||||
|
|
||||||
void Rotate(float speed);
|
void Rotate(float speed);
|
||||||
void SetRotation(float new_rotation);
|
void SetRotation(float new_rotation);
|
||||||
|
|
||||||
|
// Parent child structure.
|
||||||
[[nodiscard]] bool AppendChild(Entity* entity);
|
[[nodiscard]] bool 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]] Entity* GetParent() const;
|
||||||
|
|
||||||
|
// Microseconds.
|
||||||
|
[[nodiscard]] long GetCreationTime() const;
|
||||||
|
[[nodiscard]] long GetAge() const;
|
||||||
|
|
||||||
[[nodiscard]] float GetRotation() const;
|
[[nodiscard]] float GetRotation() const;
|
||||||
[[nodiscard]] Vector2 GetPosition() const;
|
[[nodiscard]] Vector2 GetPosition() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void Update() {}
|
virtual void Update() {}
|
||||||
public:
|
public:
|
||||||
explicit Entity(const Vector2& position, float rotation = 0.0f) : position(position), face_angle(rotation) {}
|
|
||||||
virtual ~Entity();
|
virtual ~Entity();
|
||||||
|
explicit Entity(const Vector2& position, float rotation = 0.0f) :
|
||||||
|
creation_time(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()),
|
||||||
|
position(position), face_angle(rotation) {}
|
||||||
};
|
};
|
@@ -7,5 +7,5 @@ namespace Engine {
|
|||||||
|
|
||||||
class Engine::Hud : public Engine::Renderable {
|
class Engine::Hud : public Engine::Renderable {
|
||||||
public:
|
public:
|
||||||
Hud() : Renderable({0, 0}, 0) {};
|
Hud() : Renderable({0, 0}, 0, 0) {};
|
||||||
};
|
};
|
||||||
|
@@ -8,9 +8,15 @@ namespace Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Engine::Renderable : public Entity {
|
class Engine::Renderable : public Entity {
|
||||||
|
protected:
|
||||||
|
// Higher numbers are farther to the back.
|
||||||
|
unsigned int depth = 0;
|
||||||
|
public:
|
||||||
|
[[nodiscard]] unsigned int GetDepth() const { return depth; }
|
||||||
|
void SetDepth(unsigned int new_depth) { depth = new_depth; }
|
||||||
public:
|
public:
|
||||||
// *must* be overridden.
|
// *must* be overridden.
|
||||||
virtual void Render() = 0;
|
virtual void Render() = 0;
|
||||||
public:
|
public:
|
||||||
explicit Renderable(const Vector2& position, float rotation = 0.0f) : Entity(position, rotation) {}
|
explicit Renderable(const Vector2& position, unsigned int depth = 0, float rotation = 0.0f) : Entity(position, rotation), depth(depth) {}
|
||||||
};
|
};
|
@@ -25,6 +25,6 @@ public:
|
|||||||
void Render() override;
|
void Render() override;
|
||||||
public:
|
public:
|
||||||
~Sprite() override;
|
~Sprite() override;
|
||||||
explicit Sprite(const Vector2& pos, const float face_angle = 0.0f, const Color4& base_color = Colors::White, Texture* texture = nullptr,
|
explicit Sprite(const Vector2& pos, unsigned int depth = 0, const float face_angle = 0.0f, const Color4& base_color = Colors::White, Texture* texture = nullptr,
|
||||||
Texture* alpha_mask = nullptr) : Renderable(pos, face_angle), texture(texture), alpha_mask(alpha_mask), base_color(base_color) {}
|
Texture* alpha_mask = nullptr) : Renderable(pos, depth,face_angle), texture(texture), alpha_mask(alpha_mask), base_color(base_color) {}
|
||||||
};
|
};
|
@@ -18,6 +18,8 @@ protected:
|
|||||||
Camera* active_camera = nullptr;
|
Camera* active_camera = nullptr;
|
||||||
std::vector<Fixed*> fixed_list{};
|
std::vector<Fixed*> fixed_list{};
|
||||||
std::vector<Entity*> entity_list{};
|
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]] bool EntityListContains(const Entity* entity) const;
|
||||||
[[nodiscard]] bool FixedListContains(const Fixed* fixed) const;
|
[[nodiscard]] bool FixedListContains(const Fixed* fixed) const;
|
||||||
|
@@ -12,5 +12,5 @@ public:
|
|||||||
void Render() final;
|
void Render() final;
|
||||||
void Update() final;
|
void Update() final;
|
||||||
public:
|
public:
|
||||||
explicit Box(const Vector2& position, float rotation = 0.0f) : Renderable(position, rotation) {}
|
explicit Box(const Vector2& position, unsigned int depth = 0, float rotation = 0.0f) : Renderable(position, depth, rotation) {}
|
||||||
};
|
};
|
@@ -59,8 +59,11 @@ Vector2 Engine::Entity::GetPosition() const {
|
|||||||
|
|
||||||
bool Engine::Entity::AppendChild(Entity* entity) {
|
bool Engine::Entity::AppendChild(Entity* entity) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (!Globals::CurrentScene->EntityListContains(entity))
|
if (!Globals::CurrentScene->EntityListContains(entity)) {
|
||||||
children.push_back(entity), success = true;
|
entity->parent = this;
|
||||||
|
children.push_back(entity);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,3 +91,19 @@ void Engine::Entity::RemoveChild(Entity* entity) {
|
|||||||
if (it != children.end())
|
if (it != children.end())
|
||||||
children.erase(it);
|
children.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long Engine::Entity::GetCreationTime() const {
|
||||||
|
return creation_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
long Engine::Entity::GetAge() const {
|
||||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - creation_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::Entity* Engine::Entity::GetParent() const {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Engine::Entity*> Engine::Entity::GetChildren() const {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
#include <Engine/Level/Scene.h>
|
#include <Engine/Level/Scene.h>
|
||||||
#include <Engine/Entity/Camera.h>
|
#include <Engine/Entity/Camera.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
bool Engine::Scene::EntityListContains(const Entity* entity) const {
|
bool Engine::Scene::EntityListContains(const Entity* entity) const {
|
||||||
for (auto* e : entity_list)
|
for (auto* e : entity_list)
|
||||||
@@ -20,7 +21,7 @@ size_t Engine::Scene::FixedCount() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Engine::Scene::EntityCount() const {
|
size_t Engine::Scene::EntityCount() const {
|
||||||
return entity_list.size();
|
return GetFlatEntityList(entity_list).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::Scene::Update() {
|
void Engine::Scene::Update() {
|
||||||
@@ -33,24 +34,33 @@ void Engine::Scene::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::Scene::Render(RenderTarget* render_target) {
|
void Engine::Scene::Render(RenderTarget* render_target) {
|
||||||
for (auto& f : fixed_list)
|
// The Camera and the HUD are ignored here because they're special cases.
|
||||||
if (f->Enabled())
|
std::vector<Renderable*> display_list{};
|
||||||
f->Render();
|
for (auto* e : GetFlatEntityList(entity_list))
|
||||||
|
if (auto* r = dynamic_cast<Renderable*>(e))
|
||||||
|
if (auto* c = dynamic_cast<Camera*>(r); c == nullptr)
|
||||||
|
if (auto* h = dynamic_cast<Hud*>(c); h == nullptr)
|
||||||
|
display_list.push_back(r);
|
||||||
|
|
||||||
// TODO Render order. In this system it's not possible for child entities to be rendered before the parent.
|
std::sort(display_list.begin(), display_list.end(), [](Renderable* a, Renderable* b) {
|
||||||
|
return a->GetDepth() > b->GetDepth();
|
||||||
|
});
|
||||||
|
|
||||||
J2D::Begin(render_target, true);
|
J2D::Begin( render_target, true);
|
||||||
|
|
||||||
if (active_camera)
|
if (active_camera)
|
||||||
active_camera->Render();
|
active_camera->Render();
|
||||||
|
|
||||||
for (auto& e : entity_list)
|
for (auto& f : fixed_list)
|
||||||
if (auto* r = dynamic_cast<Renderable*>(e))
|
if (f->Enabled())
|
||||||
if (auto* c = dynamic_cast<Camera*>(r); c == nullptr)
|
f->Render();
|
||||||
|
|
||||||
|
for (auto& r : display_list)
|
||||||
r->Render();
|
r->Render();
|
||||||
|
|
||||||
if (heads_up_display)
|
if (heads_up_display)
|
||||||
heads_up_display->Render();
|
heads_up_display->Render();
|
||||||
|
|
||||||
J2D::End();
|
J2D::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,3 +128,15 @@ Engine::Camera* Engine::Scene::GetActiveCamera() const {
|
|||||||
return active_camera;
|
return active_camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Engine::Entity*> Engine::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
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});
|
||||||
heads_up_display = hud;
|
|
||||||
AppendEntity(b);
|
AppendEntity(b);
|
||||||
|
heads_up_display = hud;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user