Переменная-член перечисления классов C++
У меня есть класс с перечислимым типом GameStates. В конструкторе (public) я инициализирую 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?
EDIT: весь код класса.
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
4 ответа:
Если ваш конструктор имеет следующую строку кода, дословно:
GameStates enumGameState = Ready;
Затем вы только что создали локальную переменную
enumGameState
в методе конструктора и инициализировали ее. Он выходит из области видимости, как только конструктор выполнен, и его значение теряется.Предположительно у вас также естьчлен переменная
enumGameState
, значение которой неинициализировано, поэтому ваш операторswitch
выполняется с фиктивными значениями.Создание локальной переменной с тем же именем, что и переменная-член является примером затенения в C++, и она часто указывает на ошибку. По этой причине некоторые компиляторы (например, GCC) могут отображать предупреждение, если вы затеняете переменную; Подробнее см. этот ответ.
Вы должны определить это перечисление, чтобы использовать его:
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
Я не думаю, что есть какие-либо проблемы с самим классом вообще, я обнаружил, что при запуске игры main() никогда не вводится, поэтому класс никогда не существует. Это оставляет меня в другом затруднительном положении все вместе, так как именно там нарисована игровая сцена, которая, кажется, хорошо визуализируется.
Спасибо, что уделили мне время и помогли отладить код класса игры.
Спасибо за вашу помощь, ребята. Проблема была не с классом или кодом oustide класса вообще. Это была проблема с visual studio, я не уверен, что к сожалению. Когда код был скопирован и добавлен в новый проект, он скомпилировался идеально, и все точки останова, помещенные в main, были поражены.
Мораль этой истории: сначала попробуйте очевидное.