0

Hey Im trying to implement state machine for my game and I wanted to test some things out. So right now my machine has 2 states Pause and Menu each one of them prints one texture and if I press mouse it should change to other state. That should be simple and I think I implemented it right, but I am having 40 bugs and I think its connetcted to include's. Here is how my code looks:

Game.h

#pragma once
#include <SFML/Graphics.hpp>
#include "GameState.h"
#include "Menu.h"
#include "Pause.h"
class Game
{
public:
    sf::RenderWindow* window;
    sf::Event evnt;
    GameState *state;  // current state

    sf::Texture text1;
    sf::Texture text2;

    sf::Sprite sText1;
    sf::Sprite sText2;

    void start();  // Main loop
    void print1(); // Prints one graphic
    void print2(); // Prints second one
    void update();// Prints based on current state

    void handleInput();  // check for input
    Game();
};

Game.cpp

void Game::start()
{
    while (window->isOpen())
    {
        handleInput();
        update();
        window->clear();
        window->display();
    }
}

Game::Game()
{
    window= new sf::RenderWindow(sf::VideoMode(1900, 1080), "SFML works!");
    text1.loadFromFile("Test.png");
    sText1.setTexture(text1);
    text2.loadFromFile("background.png");
    sText2.setTexture(text1);

    state = new Menu();

}

void Game::print1()
{
    window->draw(sText1);
}

void Game::update()
{
    state->Update(*this);
}

void Game::print2()
{
    window->draw(sText2);
}

void Game::handleInput()
{
    while (window->pollEvent(evnt))
    {
        GameState* tmp = state->handleInput(evnt);
        if (tmp != NULL)
        {
            delete state;
            state = tmp;
        }

    }
}

GameState.h

#pragma once
#include "Game.h"

class GameState
{
protected:

public:

    virtual void Update(Game &gra )=0;
    virtual GameState* handleInput(sf::Event evnt)=0;

};

Pause.h


#pragma once
#include "GameState.h"
#include "Menu.h"
class Pause:public GameState
{
public:

     void Update(Game& gra);
     GameState* handleInput(sf::Event evnt);
};

Pause.cpp


#include "Pause.h"

void Pause::Update(Game& gra)
{
    gra.print1();
}

GameState* Pause::handleInput(sf::Event evnt)
{

    if (evnt.type == sf::Event::MouseButtonPressed)
    {
        return new Menu();
    }
    else
    {
        return NULL;
    }
}

Menu class works the same, just returns Pause class

Here are the errors, doubt that they will help

Severity    Code    Description Project File    Line    Suppression State
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\GameState.h    11  
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    9   
Error   C2660   'GameState::Update': function does not take 1 arguments sfml    C:\Programowanie\Nauka\sfml\sfml\Game.cpp   52  
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 9   
Error   C2504   'GameState': base class undefined   sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    6   
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    9   
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C2504   'GameState': base class undefined   sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 6   
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 9   
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2504   'GameState': base class undefined   sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    6   
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    9   
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    10  
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2440   'return': cannot convert from 'Pause *' to 'GameState *'    sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.cpp   15  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2504   'GameState': base class undefined   sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 6   
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 9   
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 10  
Error   C2143   syntax error: missing ';' before '*'    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C4430   missing type specifier - int assumed. Note: C++ does not support default-int    sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2238   unexpected token(s) preceding ';'   sfml    C:\Programowanie\Nauka\sfml\sfml\Game.h 11  
Error   C2440   'return': cannot convert from 'Menu *' to 'GameState *' sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.cpp  14  
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\GameState.h    11  
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Pause.h    9   
Error   C2061   syntax error: identifier 'Game' sfml    C:\Programowanie\Nauka\sfml\sfml\Menu.h 9   


thomas1413
  • 67
  • 8
  • I was updating my post, as you were typing your comment. – thomas1413 Apr 05 '21 at 19:53
  • 3
    I think you have a circular include path loop. Related: [https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) – drescherjm Apr 05 '21 at 19:54
  • 1
    Relevant [question](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) about circular dependencies here. In this case you can probably forward-declare `GameState` in `Game.h` instead of `#include "GameState.h"` – Nathan Pierson Apr 05 '21 at 19:55
  • There's a few other things you can do along these lines, like forward-declaring `Game` in `GameState.hpp`, or not including `Menu.h` or `Pause.h` in `Game.h` and just including `Menu.h` in `Game.cpp`. In this case it doesn't necessarily make a huge difference, but it can be good to think about how much detail is needed in which spots. You don't need a complete class definition to declare variables of pointer type or to declare function signatures. – Nathan Pierson Apr 05 '21 at 20:14

1 Answers1

2

You have a circular dependency where Game.h includes Gamestate.h and vice versa. In the former you can replace your full include

#pragma once
#include <SFML/Graphics.hpp>
#include "GameState.h"         // full include
#include "Menu.h"
#include "Pause.h"
class Game
{
    ...

with a forward declaration instead

#pragma once
#include <SFML/Graphics.hpp>
#include "Menu.h"
#include "Pause.h"

class GameState;    // forward declaration

class Game
{
    ...

Then you can #include "GameState.h" within your Game.cpp file instead

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218