Miałem problem z pętlą #include, dlatego zamknąłem klasy GameState i App w jednym pliku (a właściwie dwóch - App.cpp i App.hpp). Istnieje również klasa pochodna od GameState. Przy kompilacji kompilator wyrzuca dużo razy: "first defined here" odnoszący się do App.cpp linia 13.
main.cpp
#include "App.hpp"
int main()
{
App app;
app.loop();
return 0;
}
App.hpp
#ifndef APP_HPP_INCLUDED
#define APP_HPP_INCLUDED
#include <stack>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
class GameState;
class App
{
private:
std::stack <GameState *> gameStatesStack;
public:
sf::RenderWindow window;
sf::Event event;
void pushState(GameState* state);
void popState();
void changeState(GameState* state);
GameState* getState();
void loop();
App();
~App();
};
class GameState
{
protected:
App* app;
int tickCounter;
public:
void updateTickCounter() { tickCounter = (tickCounter > 35999 ? 0 : tickCounter+1); };
virtual void regularUpdate() = 0;
virtual void handleInput(const float dt) = 0;
virtual void irregularUpdate(const float dt) = 0;
virtual void draw(const float dt) = 0;
GameState(App* app_p) : app(app_p), tickCounter(0) {};
virtual ~GameState() {};
};
#endif // APP_HPP_INCLUDED
App.cpp
#include <iostream>
#include <stack>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include "App.hpp"
#include "global.hpp"
#include "GameState.hpp"
void App::pushState(GameState* state)
{
gameStatesStack.push(state);
}
void App::popState()
{
delete gameStatesStack.top();
gameStatesStack.pop();
}
void App::changeState(GameState* state)
{
this->popState();
this->pushState(state);
}
GameState* App::getState()
{
if (!gameStatesStack.empty())
return gameStatesStack.top();
return nullptr;
}
void App::loop()
{
float TICK_TIME_IN_MS = 1000 / GLOBAL::CONFIG["TICKS_PER_SEC"];
sf::Clock tick_clock;
sf::Clock dt_clock;
float dt = 0;
while(window.isOpen())
{
tick_clock.restart();
this->getState()->regularUpdate();
do
{
dt = dt_clock.getElapsedTime().asSeconds();
dt_clock.restart();
this->getState()->handleInput(dt);
this->getState()->irregularUpdate(dt);
this->getState()->draw(dt);
window.display();
}
while (tick_clock.getElapsedTime().asMilliseconds() + dt < TICK_TIME_IN_MS);
this->getState()->updateTickCounter();
}
}
App::App()
{
window.create(sf::VideoMode(GLOBAL::CONFIG["WINDOW_X"], GLOBAL::CONFIG["WINDOW_Y"]), "Dark Maze v0.1", sf::Style::Titlebar | sf::Style::Close );
window.setVerticalSyncEnabled((bool) GLOBAL::CONFIG["VSYNC"]);
}
App::~App()
{
while (! gameStatesStack.empty() )
this->popState();
}
GameStatePlay.hpp
#ifndef GAMESTATEPLAY_HPP_INCLUDED
#define GAMESTATEPLAY_HPP_INCLUDED
#include "App.hpp"
#include "MapManager.hpp"
#include "Player.hpp"
class GameStatePlay: public GameState
{
private:
MapManager map_manager;
Player player;
public:
void regularUpdate();
void handleInput(const float dt);
void irregularUpdate(const float dt);
void draw(const float dt);
GameStatePlay(App* app_p);
~GameStatePlay();
};
#endif // GAMESTATEPLAY_HPP_INCLUDED
GameStatePlay.cpp (skrócony)
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include "GameStatePlay.hpp"
#include "global.hpp"
void GameStatePlay::regularUpdate()
{
if(tickCounter % 6 == 0)
player.changeAnimationStage();
}
void GameStatePlay::handleInput(const float dt)
{
//...
}
void GameStatePlay::irregularUpdate(const float dt)
{
}
void GameStatePlay::draw(const float dt)
{
this->app->window.clear();
map_manager.render(this->app->window);
player.render(this->app->window);
}
GameStatePlay::GameStatePlay(App* app_p) :
GameState::GameState(app_p),
map_manager("map1")
{
}
GameStatePlay::~GameStatePlay()
{
}
Macie jakieś pomysły jak to rozwiązać?
EDIT
Wkleiłem całą zawartość pliku App.cpp