Переменная-член перечисления классов C++

У меня есть класс с перечисляемым типом GameStates. В (общедоступном) конструкторе я инициализирую GameStates следующим образом:

GameStates enumGameState = Ready;

Затем в общедоступном методе run() у меня есть такой переключатель:

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

Пока код не выдает ошибки, ни одно из состояний не выполняется. Как мне получить доступ к значению enumGameState?

РЕДАКТИРОВАТЬ: весь код класса.

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

person Stephen Murby    schedule 05.02.2012    source источник
comment
Если вы добавите std::endl к своим отпечаткам, чтобы очистить строку, поможет ли это? std::cout << "Text" << std::endl;   -  person Martin York    schedule 05.02.2012
comment
Нет, в выводе консоли по-прежнему ничего нет. Я только что протестировал key_Space вне коммутатора, и кажется, что нажатие клавиши не читается. Что странно, так как захват клавиши escape работает нормально.   -  person Stephen Murby    schedule 05.02.2012
comment
Извините, я понимаю, что это не во фрагменте выше. Непосредственно перед переключателем у меня есть еще один theGameEngine->Key_Hit() для управляющей клавиши, которая выходит из игры. Отлично работает!   -  person Stephen Murby    schedule 05.02.2012


Ответы (4)


arrow_upward
4
arrow_downward

Если ваш конструктор имеет следующую строку кода, дословно:

GameStates enumGameState = Ready;

Затем вы только что создали local переменную enumGameState в методе конструктора и инициализировали ее. Он выходит из области видимости, как только конструктор завершает работу, и его значение теряется.

Предположительно, у вас также есть переменная member enumGameState, значение которой не инициализировано, поэтому ваш оператор switch выполняется с фиктивными значениями.

Создание локальной переменной с тем же именем, что и у переменной-члена, является примером теневого копирования в C++ и часто указывает на ошибку. По этой причине некоторые компиляторы (например, GCC) могут отображать предупреждение, если вы затеняете переменную; подробности см. в этом ответе.

person Josh Kelley    schedule 05.02.2012
comment
Экземпляр GameStates определяется как enumGameState в верхней части класса, только внутри конструктора устанавливается значение Ready. - person Stephen Murby; 05.02.2012
comment
@Stephen - Тогда я не уверен, в чем проблема. Трудно сказать, не видя реального кода. - person Josh Kelley; 05.02.2012
comment
Массовый сбой, случайно добавил весь код, затем попытался удалить его, отредактировав пост, и в итоге дважды. :( Извините PS. Пожалуйста, мод может удалить лишний код? - person Stephen Murby; 05.02.2012

arrow_upward
1
arrow_downward

Вы должны определить это перечисление, чтобы использовать его:

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

Тогда класс Game мог бы выглядеть так:

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;
};

А вот и main:

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

выход:

Ready
Firing
Contact
Over
person LihO    schedule 05.02.2012
comment
У меня есть общедоступное перечисление GameStates и уже есть его экземпляр. который я назвал enumGameState, я присваиваю ему готовое значение в конструкторе, который также является общедоступным. Я пытаюсь использовать ту же самую переменную класса здесь, в методе. - person Stephen Murby; 05.02.2012
comment
Ну, кажется, ваша реализация была правильной. Но хорошо, что вы решили использовать enum вместо int gameState; ;) - person LihO; 06.02.2012
comment
Я думал, что делаю это правильно, но понятия не имею, почему я не получаю желаемого результата. Мне очень жаль, что я не оставил его за 24 часа до моей руки, чтобы перезапустить свое задание сейчас, хотя отладка старого была намного хуже! - person Stephen Murby; 06.02.2012
comment
Проверьте мой пример в этом ответе. Логика вашего кода остается прежней и работает нормально. - person LihO; 06.02.2012

arrow_upward
1
arrow_downward

Я не верю, что есть какие-либо проблемы с самим классом, я обнаружил, что когда я запускаю игру, main() никогда не вводится, поэтому класс никогда не существует. Это оставляет меня в другом затруднительном положении, так как именно здесь нарисована игровая сцена, которая кажется хорошо отрисованной.

Спасибо за то, что помогли мне отладить код класса Game.

person Stephen Murby    schedule 05.02.2012

arrow_upward
1
arrow_downward

Спасибо за помощь ребята. Проблема была вовсе не в классе или коде вне класса. Это была проблема с визуальной студией, к сожалению, я не уверен, что именно. Когда код был скопирован и добавлен в новый проект, он отлично скомпилировался, и все точки останова, размещенные в main, сработали.

МОРАЛЬ ИСТОРИИ: сначала попробуйте очевидное.

person Stephen Murby    schedule 07.02.2012