Peoplemon  0.1.0
Peoplemon 3 game source documentation
Render.cpp
Go to the documentation of this file.
2 
3 #include <Core/Properties.hpp>
5 
6 namespace core
7 {
8 namespace system
9 {
11 : owner(o)
12 , mainRenderTarget(nullptr)
13 , pool(owner.engine().ecs().getAllComponents<component::Renderable>())
14 , transformPool(owner.engine().ecs().getAllComponents<bl::com::Transform2D>()) {}
15 
16 void Render::update(std::mutex&, float, float, float, float) {
17  if (!mainRenderTarget) { mainRenderTarget = &owner.engine().renderer().getObserver(); }
18  for (const auto& epair : stopRm) {
19  component::Renderable* rc = pool.get(epair.first);
20  if (rc) { rc->notifyMoveState(epair.second, false, false); }
21  }
22  stopRm.clear();
23 
24  for (const bl::ecs::Entity shadow : shadowsToRemove) {
25  owner.engine().ecs().destroyEntity(shadow);
26  }
27  shadowsToRemove.clear();
28 }
29 
30 void Render::init(bl::engine::Engine&) { bl::event::Dispatcher::subscribe(this); }
31 
32 void Render::notifyFrameStart() { std::swap(stopAdd, stopRm); }
33 
34 void Render::observe(const event::EntityMoved& event) {
35  component::Renderable* rc = pool.get(event.entity);
36  if (rc) {
37  rc->notifyMoveState(event.position.direction, true, event.running);
38  std::erase_if(stopRm, [&event](auto& pair) { return pair.first == event.entity; });
39  std::erase_if(stopAdd, [&event](auto& pair) { return pair.first == event.entity; });
40  }
41 
42  bl::com::Transform2D* transform = transformPool.get(event.entity);
43  if (transform) {
44  transform->setDepth(owner.world().activeMap().getDepthForPosition(
45  event.position.level, event.position.position.y));
46  }
47 }
48 
49 void Render::observe(const event::EntityMoveFinished& event) {
50  stopAdd.emplace_back(event.entity, event.position.direction);
51 }
52 
53 void Render::observe(const event::EntityRotated& event) {
54  component::Renderable* rc = pool.get(event.entity);
55  if (rc) { rc->notifyMoveState(event.faceDir, false, false); }
56 }
57 
58 void Render::updateShadow(bl::ecs::Entity entity, float distance, float radius) {
59  component::Renderable* rc = pool.get(entity);
60  if (!rc) {
61  BL_LOG_WARN << "Cannot update shadow of entity, missing Renderable component: " << entity;
62  return;
63  }
64 
65  constexpr float Radius = 100.f;
66 
67  bl::gfx::Circle* shadow = nullptr;
68  if (rc->shadow != bl::ecs::InvalidEntity) {
69  shadow = owner.engine().ecs().getComponent<bl::gfx::Circle>(rc->shadow);
70  if (!shadow) {
71  BL_LOG_ERROR << "Entity is missing shadow but one was expected, re-creating";
72  owner.engine().ecs().destroyEntity(rc->shadow);
73  }
74  }
75  if (!shadow) {
76  rc->shadow = owner.engine().ecs().createEntity(bl::ecs::Flags::WorldObject);
77  owner.engine().ecs().setEntityParent(rc->shadow, entity);
78  shadow = owner.engine().ecs().emplaceComponent<bl::gfx::Circle>(rc->shadow);
79  shadow->create(owner.engine(), rc->shadow, Radius);
80  shadow->deleteEntityOnDestroy(false);
81  shadow->getTransform().setOrigin(Radius, Radius);
82  shadow->getTransform().setDepth(0.5f); // just below parent
83  shadow->setFillColor(sf::Color(0, 0, 0, 145));
84  shadow->addToScene(owner.world().activeMap().getScene(), bl::rc::UpdateSpeed::Dynamic);
85  }
86 
87  bl::com::Transform2D* parentTransform =
88  owner.engine().ecs().getComponent<bl::com::Transform2D>(entity);
89  const glm::vec2 parentOrigin =
90  parentTransform ? parentTransform->getOrigin() : glm::vec2{16.f, 32.f};
91 
92  shadow->scaleToSize({radius * 2.f, radius * 2.f});
93  shadow->getTransform().setPosition(parentOrigin.x + Properties::PixelsPerTile() / 2,
94  parentOrigin.y + distance + Properties::PixelsPerTile() / 2);
95 }
96 
97 void Render::removeShadow(bl::ecs::Entity entity) {
98  component::Renderable* rc = pool.get(entity);
99  if (rc && rc->shadow != bl::ecs::InvalidEntity) {
100  shadowsToRemove.emplace_back(rc->shadow);
101  rc->shadow = bl::ecs::InvalidEntity;
102  }
103 }
104 
105 void Render::setMainRenderTarget(bl::rc::RenderTarget& rt) { mainRenderTarget = &rt; }
106 
107 } // namespace system
108 } // namespace core
Core classes and functionality for both the editor and game.
Adding this component to an entity will allow it to be rendered.
Definition: Renderable.hpp:28
void notifyMoveState(bl::tmap::Direction dir, bool moving, bool running)
Call when the entity starts or stops moving or changes direction.
Definition: Renderable.cpp:130
float getDepthForPosition(unsigned int level, unsigned int y, int layer=-1) const
Computes the depth to use at the given y position, taking into account the map size,...
Definition: Map.cpp:741
bl::rc::SceneRef getScene()
Returns the scene for this map.
Definition: Map.hpp:280
static int PixelsPerTile()
Definition: Properties.cpp:279
Render(Systems &owner)
Creates the render system.
Definition: Render.cpp:10
void setMainRenderTarget(bl::rc::RenderTarget &target)
Sets the main render target. Used by the editor.
Definition: Render.cpp:105
void removeShadow(bl::ecs::Entity entity)
Removes the shadow from the given entity.
Definition: Render.cpp:97
void updateShadow(bl::ecs::Entity entity, float distance, float radius)
Adds or updates the shadow of the given entity.
Definition: Render.cpp:58
Owns all primary systems and a reference to the engine.
Definition: Systems.hpp:47
const bl::engine::Engine & engine() const
Const accessor for the Engine.
Definition: Systems.cpp:35
World & world()
Modifiable accessor for the world system.
Definition: Systems.cpp:43
map::Map & activeMap()
Returns a reference to the active map.
Definition: World.cpp:84