Help Docs for wiki writers: |
Help /
LessonThreeLesson 3:First GameIn this lesson we are going to create a simple text game. Below is the code for the game it may look like a lot but it is a lot simpler than it looks. Explanation of code
std::string TranslateOppToString(unsigned int _opp)
{
switch(_opp)
{
case 0:
return "+";
break;
case 1:
return "-";
break;
case 2:
return "*";
break;
}
return "+";
}
int EvaluateQuestions(int _var1,int _var2,unsigned int _opp)
{
switch(_opp)
{
case 0:
return _var1+_var2;
break;
case 1:
return _var1-_var2;
break;
case 2:
return _var1*_var2;
break;
}
return _var1+_var2;
}
enum State
{
Restart=0,
DisplayQuestion,
WaitForAnwser,
EvaluateAnwser,
CheckForMoreQuestions,
Done
};
This code should be familiar from the previous lessons. I chose 15 for the frame rate because we do not want to eat up all cpu cycles of the user's computer. This program will be running in a window and is not intend to hold the user attention all the time. So, eating up all the cpu cycle will annoy the end user. Also 15 FPS is fast enough for our game logic as well. Any FPS from 15 to 30 will work. int main (int argc, char *argv[])
{
EpeeEngine GraphicsEngine;
GraphicsEngine.SetUp(800,600,false,"Math Questions",false,15,32);
EpeeEngine GraphicsEngine;
GraphicsEngine.SetUp(800,600,false,"Math Questions",false,15,32);
textBox * pMessage=GraphicsEngine.CreateTextBox("message",100,50,5,"1234","Current",-1,-1,"ARIAL.TTF",18,255,255,255,"C:\\WINDOWS\\Fonts\\");
textBox * pVar1=GraphicsEngine.CreateTextBox("var1",100,100,5,"1234","Current",-1,-1,"ARIAL.TTF",18,255,255,255,"C:\\WINDOWS\\Fonts\\");
textBox * pVar2=GraphicsEngine.CreateTextBox("var2",200,100,5,"1234","Current",-1,-1,"ARIAL.TTF",18,255,255,255,"C:\\WINDOWS\\Fonts\\");
textBox * pOperatorText=GraphicsEngine.CreateTextBox("operator",150,100,5,"-","Current",-1,-1,"ARIAL.TTF",25,255,0,0,"C:\\WINDOWS\\Fonts\\");
textBox * pAnwser=GraphicsEngine.CreateTextBox("Anwser",120,150,3,"Click and Type Answer Here","Current",-1,-1,"ARIAL.TTF",18,255,255,255,"C:\\WINDOWS\\Fonts\\");
if(!(pVar1 && pVar2 && pOperatorText && pAnswer && pMessage))
{
cerr<<"could not create textbox see stderr for details"<<endl;
return 0;
}
srand ( time(NULL) );
pAnwser->SetBackGroundColor(0,255,0);
pAnwser->SetColorChangedOnClick(true);
pAnwser->SetQuality(FONT_QUALITY_SHADED);
pAnwser->SetSelectBackGroundColor(255,0,0);
pVar1->SetQuality(FONT_QUALITY_HIGH);
pVar1->SetTextJustification(TEXT_RIGHT_JUSTIFIED);
pVar2->SetQuality(FONT_QUALITY_HIGH);
pVar2->SetTextJustification(TEXT_LEFT_JUSTIFIED);
pOperatorText->SetQuality(FONT_QUALITY_HIGH);
pOperatorText->SetTextJustification(TEXT_CENTER_JUSTIFIED);
pMessage->SetQuality(FONT_QUALITY_HIGH);
pAnwser->SetNumbersOnly(true);
unsigned int uiCurrentQuestion=1;
unsigned int uiNumberCorrect=0;
State CurrentState=DisplayQuestion;
int iLeftSide=0;
int iRightSide=0;
unsigned int uiOpp=0;
int iAnwser=0;
std::string message=" ";
std::string temp="";
SDL_Event event;
while (1)
{
while(GraphicsEngine.GetEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
return 0;
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
return 0;
break;
case SDLK_KP_ENTER:
case SDLK_RETURN:
pAnwser->SetEditable(false);
CurrentState=EvaluateAnwser;
break;
case SDLK_r:
if(CurrentState==Done)
{
CurrentState=Restart;
}
break;
}
break;
}//end of switch(event.type)
}//end of while(GraphicsEngine.GetEvent(&event))
Next we will look at the state flow of the game. Below is a switch statement that we are going to use to handle a small state flow. Each case is a diffrent state and thus runs code specific to that game state. we start our game out in DisplayQuestion with the following line from above: State CurrentState=DisplayQuestion. The game will flow through the states as followsDisplayQuestion WaitForAnwser EvaluateAnwser CheckForMoreQuestions Done or DisplayQuestion Restart DisplayQuestion
switch (CurrentState)
{
case Restart:
uiNumberCorrect=0;
uiCurrentQuestion=1;
CurrentState=DisplayQuestion;
break;
case DisplayQuestion: iLeftSide=rand()%LeftNumberMax; iRightSide=rand()%RightNumberMax; uiOpp=rand()%3; pVar1->SetTextFromInt(iLeftSide); pVar2->SetTextFromInt(iRightSide); pOperatorText->SetText(TranslateOppToString(uiOpp)); CurrentState=WaitForAnwser; break;
Once the user has enter an answer and pressed enter we will be in the EvaluateAnswer state.We first get the text from the answer text box and covet it to an integer.iAnwser=pAnwser->GetTextToInt(); Then we check to make sure the converting of the text to an integer was succesfull.if(pAnwser->GetLastError().m_iErrorCode!=TEXTBOX_CONVERION_ERROR) If it was successfully we then check to see if the answer was correctif(EvaluateQuestions(iLeftSide,iRightSide,uiOpp)==iAnwser)) If it is we tell the user they are correct and increment the correct answers counter.pMessage->SetText("That is Correct");uiNumberCorrect++;Other wise we tell the user they are incorrectpMessage->SetText("That is Incorrect"); Then since the text from the answer text box converted correctly we then go to the CheckForMoreQuestions stateCurrentState=CheckForMoreQuestions; If the text from the answer text box does not covert correctly we then tell the user and go back to the WaitForAnswer state.pAnwser->SetText("Invalid input");
CurrentState=WaitForAnwser;
case EvaluateAnwser:
iAnwser=pAnwser->GetTextToInt();
if(pAnwser->GetLastError().m_iErrorCode!=TEXTBOX_CONVERION_ERROR)
{
if(EvaluateQuestions(iLeftSide,iRightSide,uiOpp)==iAnwser)
{
pMessage->SetText("That is Correct");
uiNumberCorrect++;
}
else
{
pMessage->SetText("That is Incorrect");
}
CurrentState=CheckForMoreQuestions;
}
else
{
pAnwser->SetText("Invalid input");
CurrentState=WaitForAnwser;
}
break;
In CheckForMoreQuestion we sleep for a second(1000 milliseconds) so the user can read whether or not he got the answer correct.SDL_Delay (1000);This is really not the best way to do this since sleeping will stop our rendering of the screen.The correct way is with timer which is a more advance topic out side the scope of this lesson,but we will save that for the next lesson.Next we Check to see if they have answer 10 questions yetif(uiCurrentQuestion>9)Then we convert the integer number to a string and tell the user how many they got correct.if(EpeeUtility::StringFromNumericData(temp,uiNumberCorrect))
{
message="You Got "+temp+" Out of "+"10 "+"Correct";
}
else
{
uiCurrentQuestion++;
CurrentState=DisplayQuestion;
}
case CheckForMoreQuestions:
SDL_Delay(1000);
if(uiCurrentQuestion>9)
{
temp="";
if(EpeeUtility::StringFromNumericData(temp,uiNumberCorrect))
{
message="You Got "+temp+" Out of "+"10 "+"Correct";
}
pMessage->SetText(message);
CurrentState=Done;
}
else
{
uiCurrentQuestion++;
CurrentState=DisplayQuestion;
}
break;
case Done: break;
That is the end of our game loop. See the screen shot for what it should look like when it runs. Like always if you have problems check the stdout.txt and stderr.txt files first and if you still have problems PM or e-mail me on the forum I would be happy to answer any questions |