Jump to content
  • Advertisement
Sign in to follow this  
Shayel

Simple, game structuring problem

This topic is 1846 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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)?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

.

.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!