Hello,
I have been learning how to use entitiyx to convert my OOP game into an ECS game. I have gotten the basic components working, and created some entities and placed them in the game "world".
I am at part where I want to add my tile map in. I have three different tile maps (saved as csv txt files), created in tiled. I have map loading and rendering working in my OOP design but would like some advice on how to get this going in an ECS engine.
I have been reading a bit online and there seems to be no general consensus as to how to do this.
In my game (a 2d scrolling plane shooter) there will be no interactions with the ground at this stage. So I think I could put my tileMap in pretty much as I have it in the OOP design. It seems to me overly complicated and "expensive" to tag tiles with components.
The part I am stuck at is the organization of this code. Right now the games update() and render() functions work as follows:
void Game::update()
{
m_systemManager.update<LevelSystem>(frameTime);
m_systemManager.update<PlayerControlSystem>(frameTime);
m_systemManager.update<MovementSystem>(frameTime);
}
void Game::render()
{
graphics.beginScene();
graphics.spriteBegin();
m_systemManager.update<RenderSystem>(frameTime);
m_systemManager.update<MenuSystem>(frameTime);
graphics.spriteEnd();
graphics.showBackbuffer();
}
The way I got tiles working in my OOP design was by adding the tiles directly to the class which inherits from Game e.g.
class TileMapExample : public Game
{
private:
mgeTexture tileTextures;
mgeSprite tile;
where an mgeSprite has a draw command that goes to my graphics class. So in my old game render loop it would loop through the tiles [row] and [col] calling draw e.g. tile.draw(UINT(tileMap[row][col]));
But in my new ECS game design there is nothing to do with actual in game entities in the Game class, that stuff is all taken care off via components and my entitiyCreator. The Game calss is as follows:
class Game : public entityx::Receiver<Game>
{
private:
Graphics graphics;
GameManager m_gameManager;
Input m_keyHandler;
HWND hwnd;
entityx::EventManager m_eventManager;
entityx::EntityManager m_entityManager;
entityx::SystemManager m_systemManager;
void createSystems();
void update();
void render();
// Frame rate code
LARGE_INTEGER timeStart; // Performance Counter start value
LARGE_INTEGER timeEnd; // Performance Counter end value
LARGE_INTEGER timerFreq; // Performance Counter frequency
float frameTime;
DWORD sleepTime;
float fps;
So this is where I ask for some assistance. Do I just cram my tile map stuff into this game Class, and update and render it separately in Game::update() and Game::Render() so e.g. Render() would look like this
void Game::render()
{
graphics.beginScene();
graphics.spriteBegin();
////////added this stuff for the tile map rendering///////
for(int row=0; row<MAP_HEIGHT; row++)
{
for(int col=0; col<MAP_WIDTH; col++)
{
etc etc loop through and draw tiles}
////////added this stuff for the tile map rendering///////
m_systemManager.update<RenderSystem>(frameTime);
m_systemManager.update<MenuSystem>(frameTime);
graphics.spriteEnd();
graphics.showBackbuffer();
}
Or is there a more elegant solution, that somehow still lets me use components and systems but not tagging the tiles as entities? It just seems the tile map render code should go into m_systemManager.update<RenderSystem>(frameTime);
which looks as:
void RenderSystem::update(entityx::EntityManager &entities, entityx::EventManager &events, double dt)
{
Position::Handle position;
Display::Handle display;
for (entityx::Entity entity : entities.entities_with_components(position, display))
{
spriteData.setTextureRect(display->coord);
spriteData.setPosition(position->position);
m_graphics->drawSprite(spriteData);
}
}
But if I had my tile drawing here and didn't have my tiles as entities..., I cant figure out how I would pass in all the tile information in, since it gets sprite info from entities which I have given position and display components.
Thanks for any input.