Repository navigation
Entities
Genode currently provides 5 interfaces, each representing a particular entity that can be used as a building block to create a complex entity. These interfaces are lightweight and can be used in any setting: You can use them in any part of the Genode layers or even in a simple, plain SFML traditional game loop.
It is highly recommended that you understand how to design an SFML-like entity, which shares the same idea with how you would utilize sf::Drawable class to create an entity.
This interface represents an entity that can be rendered to a render surface (or a render target). Gx::Renderable implements and is equivalent to the sf::Drawable class in SFML.
Unlike the draw function, the Render function expects you to return a Gx::RenderStates. Typically, you return the latest render states after finishing the rendering calls. This could be useful in the SceneGraph implementation, where you may interested in inferring some of the rendering states from the renderable children or sibling nodes.
When you draw a renderable object as asf::Drawable object, the Render function will be called with a temporary Gx::RenderSurface using the adaptor class that is bound to the specified sf::RenderTarget.
Genode uses the Render term rather than draw, but they're essentially the same.
This interface represents an entity that can be updated every frame via Update(const sf::Time& delta). Unlike Render or draw, Update is a mutable (non-const) function. The delta represents the time elapsed since the last frame, expressed in sf::Time.
This interface represents an entity that can receive user input.
This interface represents an entity that possesses a color.
This interface represents an entity that can be presented on top of Gx::Presentable::Parent. For example, this interface can be used to implement UI Dialog/Modal-like behavior. The interface is not tied to graphical details and can also be utilized for other non-graphical implementations.
Similar to how creating an entity works in SFML, you can simply implement one or more interfaces to create your entity. The following code illustrates an entity that can render, update, and listen to user input:
class MyEntity : public sf::Transformable, public Gx::Renderable, public Gx::Updatable, public Gx::Inputable
{
public:
// add functions to play with the entity's geometry / colors / texturing...
private:
void Update(const sf::Time& delta) override
{
// Move entity to the right by 100px every second
m_elapsed += delta;
if (m_elapsed >= sf::seconds(1))
{
move({100, 0}); // move() is defined by sf::Transformable
m_elapsed -= sf::seconds(1); // reset timer duration
}
}
void OnKeyPressed(const sf::Event::KeyPressed& ev) override
{
// Move entity upward by 100px when user press / hold space key
if (ev.code == sf::Keyboard::Key::Space)
{
move(0, -100); // move() is defined by sf::Transformable
}
}
Gx::RenderStates Render(Gx::RenderSurface& target, Gx::RenderStates states) const override
{
// apply the entity's transform -- combine it with the one that was passed by the caller
states.Transform *= getTransform(); // getTransform() is defined by sf::Transformable
// apply the texture
states.texture = &m_texture;
// you may also override states.shader or states.blendMode if you want
// draw the vertex array
target.Render(m_vertices, states);
}
sf::VertexArray m_vertices;
sf::Texture m_texture;
sf::Time m_elapsed;
};You can then use this class as if it were a built-in SFML/Genode class:
MyEntity entity;
sf::Time delta = // compute delta each frame..
// you can transform it
entity.setPosition(10.f, 50.f);
entity.setRotation(45.f);
// you can update it
entity.Update(delta);
// you can let it listen to input events
if (const auto event = window.pollEvent()) {
entity.Input(event.value());
}
// you can draw it via SFML sf::RenderTarget
window.draw(entity);
// .. or render it via Genode Gx::RenderSurface
surface.Render(entity);Copyright © 2024 - CXO2
This open-source library is licensed under the zlib/libpng license.