Stephen Murby
Stephen Murby

Reputation: 1467

C++ Class Enumeration Member variable

I have a class with an enumerated type GameStates. In the (public) constructor I initialise GameStates like this:

GameStates enumGameState = Ready;

Then in a public method run() i have a switch like this:

switch(enumGameState)
        {
        case Ready:
            if (theGameEngine->KeyHit(Key_Space))
            {
                enumGameState = Firing;
                cout << "\nGame State moved to Firing";
            }   // End if
            break;
        case Firing:
            if (theGameEngine->KeyHit(Key_Space))
            {
                enumGameState = Contact;
                cout << "\nGame State moved to Contact";
            }   // End if
            break;
        case Contact:
            if (theGameEngine->KeyHit(Key_Space))
            {
                enumGameState = Over;
                cout << "\nGame State moved to Over";
            }   // End if
            break;
        case Over:
            break;
        };  // End of GameState switch

Whilst the code does not error, none of the states are met. How should i be accessing the value of enumGameState?

EDIT: All class code.

class Game
{
private:
    Block* arrBlocks[10][10];   
    //IMesh* objBlockMesh;
    IMesh* objGunMesh;
    IMesh* objDummyMesh;
    Gun* objGun;
    int Game::intSpeed;
    I3DEngine* theGameEngine;
    float fltSkyboxXCo;
    float fltSkyboxYCo;
    float fltSkyboxZCo;
    float fltFloorXCo;
    float fltFloorYCo;
    float fltFloorZCo;

    enum GameStates{Ready,Firing, Contact, Over};
    GameStates enumGameState;

public: 

    Game(I3DEngine* the3dengine)
    {
        Game::theGameEngine = the3dengine;
        theGameEngine->StartWindowed();

        // Add default folder for meshes and other media
        theGameEngine->AddMediaFolder( "C:\\TL-Engine\\Media\\AssigmentTwo\\Media" );

        //intSpeed = 1;

        Game::DrawBasicScene(theGameEngine);
        Game::DrawBlocks();
        Game::CreateAGun();
        Bullet::Bullet(theGameEngine);
        Game::enumGameState = Ready;
    }   // End of Constructor


private:    


    void DrawBlocks()
    {
        float fltBlockOffSet = 12.0f;
        float fltLeftMost = -54.0f;
        float fltBlockZCo = 120.0f;
        float fltBlockYCo = 5.0f;
        float fltCurrentXCo;
        float fltCurrentYCo = 5.0f;
        float fltCurrentZCo = 120.0f;
        // Stick 10 blocks in an array
        // Display them

        for(int i = 0; i < 10; i++)
        {
            if (i == 1) // Once i have created the first row all the other blocks are going to be created in a hidden state
            {
                fltCurrentYCo = -50.0f;
            }
            for(int j = 0; j < 10; j++)
            {
                fltCurrentXCo = ((float)j*fltBlockOffSet) + fltLeftMost;    // Cast j into a float explicitly so that it doesn't it implicitly
                arrBlocks[i][j] = new Block(theGameEngine, fltCurrentXCo, fltCurrentYCo, fltCurrentZCo);
                if(fltCurrentYCo < 0)
                {
                    arrBlocks[i][j]->SetBlockState(Block::Destroyed);
                }   // End if
                else
                {
                    arrBlocks[i][j]->SetBlockState(Block::New);
                }
            }   // End of inner loop

            fltCurrentZCo += fltBlockOffSet;

        }   // End of outer loop

    }

    void CreateAGun()
    {
        // Create a gun
        Gun::Gun(theGameEngine);
    }

public:
    void Game::Run()
    {
        //Start watching input in a while loop
        // The main game loop, repeat until engine is stopped
        while (theGameEngine->IsRunning())
        {
            // Draw the scene
            theGameEngine->DrawScene();
            if (theGameEngine->KeyHit(Key_Escape))
            {
                theGameEngine->Stop();
            }

            if)theGameEngine->KeyHit(Key_Space))
            {
                cout << "\n space";
            }

            GameStates currentGameState = enumGameState;
            switch(enumGameState)
            {
            case Ready:
                if (theGameEngine->KeyHit(Key_Space))
                {
                    enumGameState = Firing;
                    cout << "\nGame State moved to Firing" << endl;
                }   // End if
                break;
            case Firing:
                if (theGameEngine->KeyHit(Key_Space))
                {
                    enumGameState = Contact;
                    cout << "\nGame State moved to Contact" << endl;
                }   // End if
                break;
            case Contact:
                if (theGameEngine->KeyHit(Key_Space))
                {
                    enumGameState = Over;
                    cout << "\nGame State moved to Over" << endl;
                }   // End if
                break;
            case Over:
                break;
            };  // End of GameState switch
        }

    }
};  // End of Game Class

Upvotes: 2

Views: 6783

Answers (4)

Stephen Murby
Stephen Murby

Reputation: 1467

Thanks for your help guys. The issue was not with the class, or code oustide of the class at all. It was an issue with visual studio, i'm not sure what unfortunately. When the code was copied out and added into a new project, it compiled perfectly, and all the break points placed in main were hit.

MORAL OF THE STORY: Try the obvious first.

Upvotes: 1

Stephen Murby
Stephen Murby

Reputation: 1467

I don't believe there is any issue with the class itself at all, I have found that when I run the Game main() is never entered, therefore the class never exists. It leaves me in another predicament all together, as that is where the game scene is drawn which appears to be rendered okay.

Thankyou for your time helping me debug the Game class code all the same.

Upvotes: 1

LihO
LihO

Reputation: 42083

You have to define this enum in order to use it:

enum GameState
{
    Ready,
    Firing,
    Contact,
    Over
};

Then class Game could look like this:

class Game
{
public:
    Game(GameState gs = Ready) : gs(gs) { }
    void update()
    {
        switch (gs)
        {
        case Ready: cout << "Ready\n"; gs = Firing; break;
        case Firing: cout << "Firing\n"; gs = Contact; break;
        case Contact: cout << "Contact\n"; gs = Over; break;
        case Over: cout << "Over\n"; break;
        default: break;
        }
    }
private:
    GameState gs;
};

And here's the main:

int main()
{
    Game g;
    g.update();
    g.update();
    g.update();
    g.update();
    return 0;
}

output:

Ready
Firing
Contact
Over

Upvotes: 1

Josh Kelley
Josh Kelley

Reputation: 58362

If your constructor has the following line of code, verbatim:

GameStates enumGameState = Ready;

Then what you've just done is create a local variable enumGameState within your constructor method and initialized it. It goes out of scope as soon as the constructor is done, and its value is lost.

Presumably you also have a member variable enumGameState whose value is uninitialized, so your switch statement is run with bogus values.

Creating a local variable with the same name as a member variable is an example of shadowing in C++, and it often indicates an error. For this reason, some compilers (like GCC) can display a warning if you shadow a variable; see this answer for details.

Upvotes: 4

Related Questions