Hello everyone. I finished my game engine's prototype today and I decided to test it by making a rectangle and moving it by the arrow keys. Unfortunately the rendering lags noticeably. I believe this is a result of my engine's pipeline so I may have to explain how it works:
-GameObjects are containers of Components and hold a pointer to the Engine.
-Components are containers for data. Each component holds different types of data.
-The Engine is a container of Systems.
-Systems are containers of GameObjects.
Now every time we add a Component to the GameObject, it checks the requirements for the different systems and registers to them.
Each System has an update() function where the logic is kept. The pipeline goes through all the Systems consequently and calls their update() function.
For my example I do:
void World::run()
{
sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");
Engine engine;
auto PIS = engine.addSystem<PlayerInputSystem>();
PIS->window = &window;
engine.addSystem<MovementSystem>();
auto RS = engine.addSystem<RenderingSystem>();
RS->window = &window;
GameObject player(engine);
player.addComponent<PlayerInputComponent>();
player.addComponent<MovementComponent>();
player.addComponent<VelocityComponent>();
auto GC = player.addComponent<GraphicsComponent>();
GC->sprite.setSize(sf::Vector2f(100,10));
GC->sprite.setPosition(sf::Vector2f(0,0));
sf::Clock clock;
float elapsed;
while (window.isOpen())
{
elapsed += clock.restart().asSeconds();
while (elapsed > 1/60.f)
{
engine.update(1/60.f);
elapsed -= 1/60.f;
}
RS->update();
}
}
Here are the Components:
class VelocityComponent : public Component
{
public:
sf::Vector2f velocity;
};
class MovementComponent : public Component
{
public:
sf::Vector2f movement;
};
class PlayerInputComponent : public Component
{
/* No need to add anything here */
};
class GraphicsComponent : public Component
{
public:
sf::RectangleShape sprite;
};
And here are the Systems:
class PlayerInputSystem : public System
{
public:
bool registration_condition(GameObject*);
void update(float);
sf::RenderWindow* window;
};
bool PlayerInputSystem::registration_condition(GameObject* object)
{
return (object->hasComponent<PlayerInputComponent>().first &&
object->hasComponent<VelocityComponent>().first );
}
void PlayerInputSystem::update(float dt = 0)
{
for (auto &object : registered_objects)
{
auto velocity = object->getComponent<VelocityComponent>();
velocity->velocity.x = 0;
velocity->velocity.y = 0;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
velocity->velocity.x = -500;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
velocity->velocity.x = 500;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
velocity->velocity.y = -500;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
velocity->velocity.y = 500;
}
}
}
//*****************************************************************************************************
class MovementSystem : public System
{
public:
bool registration_condition(GameObject*);
void update(float);
};
bool MovementSystem::registration_condition(GameObject* object)
{
return (object->hasComponent<MovementComponent>().first &&
object->hasComponent<VelocityComponent>().first );
}
void MovementSystem::update(float dt = 0)
{
for (auto &object : registered_objects)
{
auto velocity = object->getComponent<VelocityComponent>();
auto delta = object->getComponent<MovementComponent>();
delta->movement.x = velocity->velocity.x * dt;
delta->movement.y = velocity->velocity.y * dt;
}
}
//******************************************************************************************************
class RenderingSystem : public System
{
public:
bool registration_condition(GameObject*);
void update(float);
sf::RenderWindow* window;
};
bool RenderingSystem::registration_condition(GameObject* object)
{
return (object->hasComponent<MovementComponent>().first &&
object->hasComponent<GraphicsComponent>().first );
}
void RenderingSystem::update(float dt = 0)
{
window->clear();
for (auto &object : registered_objects)
{
auto delta = object->getComponent<MovementComponent>();
auto graphics = object->getComponent<GraphicsComponent>();
graphics->sprite.move(delta->movement);
window->draw(graphics->sprite);
}
window->display();
}
The engine is by no means finished. It pretty much works with pointers everywhere and I would like to add Systems that don't take part in the pipeline. I hope I am doing something wrong with the game loop or else I may have to do way more work than I can handle atm.
EDIT: Wrong forum section again. Can this be moved to the help section?