Jump to content

  • Log In with Google      Sign In   
  • Create Account


Simple, game structuring problem


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 Shayel   Members   -  Reputation: 248

Like
0Likes
Like

Posted 30 May 2013 - 07:47 AM

Hello

I have my abstract CGameState class, which has 3 virtual functions: Logic, Events and Render. Then I have my CGame class, that contains the CGameState* object, the screen object and methods that change the state.

The main loop is like:

CurrentState->Events();

CurrentState->Logic();

CurrentState->Render();

Now, if during the application there is a need to change the state, I am using ChangeState method, which basically deletes the old CGameState* and creates the proper new one. For example:

void ChangeState(STATE_MENU)

{

delete CurrentState;

CurrentState=new CMenu;

}

 

And the CMenu inherites from the CGameState, to use its own Logic, Events, and Render methods. 

 

Here goes the problem:

When there is a need to change the state, I have no access to the (Cgame game) object, because it contains the CurrentState object.. So I cannot use the ChangeState method :/ How can I do it?



Sponsor:

#2 Hodgman   Moderators   -  Reputation: 27590

Like
0Likes
Like

Posted 30 May 2013 - 09:10 AM

I have my "Logic" (equivalent) function return a value that indicates whether the state should be changed or not. So the game calls "state->Logic" and then maybe calls "ChangeState" depending on the return value.

#3 FLeBlanc   Crossbones+   -  Reputation: 3081

Like
1Likes
Like

Posted 30 May 2013 - 09:11 AM

Have Logic() return a pointer to the game state that should execute next, rather than calling ChangeState directly. I usually structure my code something like this:
 
class GameState
{
public:
	virtual void event()=0;
	virtual GameState *logic()=0;
	virtual void render()=0;
};


void MainLoop::run(GameState *startstate)
{
	currentstate_=startstate;
	
	while(isRunning())
	{
		currentstate_->event();
		GameState *nextstate=currentstate_->logic();
		currentstate_->render();
		
		if(nextstate)
		{
			delete currentstate_;
			currentstate_=nextstate;
		}
	}
}
Note that you should always follow the format of not actually changing the current operating state until you are outside of your input/logic/render functions. If you were to call your Cgame::ChangeState method from inside CGameState::Logic(), then this would delete the object owning the Logic() method you are currently inside, potentially causing all sorts of problems. Instead, you should indicate that a state change is to be made as soon as it is safe to do so, and returning a pointer to the state to execute next is one way of doing so.

#4 Shayel   Members   -  Reputation: 248

Like
0Likes
Like

Posted 31 May 2013 - 07:22 AM

Thanks for the replies

I will change the ChangeState, so it is called outside the Render, Logic and Event functions. But now there is another question. What if the state could be set in both event section (player X'ed out, set to EXIT_STATE) and in the Logic section (player walked through the door, load next room)?



#5 FLeBlanc   Crossbones+   -  Reputation: 3081

Like
0Likes
Like

Posted 31 May 2013 - 09:12 AM

Then have either function return a pointer to the new state, and do some extra conditional checking to check both results and handle edge cases such as both methods returning a different pointer, for whatever reason.



#6 Shayel   Members   -  Reputation: 248

Like
0Likes
Like

Posted 31 May 2013 - 12:36 PM

I was thinking about creating the exit flag, so when user wants to exit(in the event part), the "exit" flag is set to true. Then on the beginning of the logic part, the flag is checked

if(exit) return STATE_EXIT;

.

.//rest of the logic part

.

.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS