Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Don't forget to read Tuesday's email newsletter for your chance to win a free copy of Construct 2!


Game States


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 Silgen   Members   -  Reputation: 178

Like
0Likes
Like

Posted 22 November 2012 - 11:36 AM

Going back to basics and writing really simple games (tic-tac-toe, currently) but trying to use a good, clean OO structure. All states are derived from a base class cState:

[source lang="cpp"]class cState {public: virtual void enter() = 0; virtual void update() = 0; virtual void leave() = 0;};[/source]
The code below is for the state manager
[source lang="cpp"]void cGame::changeState(cState* targetState) { currentState->leave(); currentState = targetState; currentState->enter();}[/source]

I was thinking of putting each state in its own file, but this means I will need to pass a pointer to the state manager (so that the state manager knows when to switch states) and also an inclusion for all of the header files for the states that it can transition to. This sounds messy. Is there a better way of doing it?

Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9628

Like
1Likes
Like

Posted 22 November 2012 - 12:05 PM

I usually use state classes that use the run and return successor pattern. Basically every function called on a state object returns a smart pointer to the state that the system should be in now. This can be a pointer to the original state. This avoids needing states to know anything about what holds the states. There may not even be an explicit state manager class. Example source for this kind of system is in this thread.

#3 molehill mountaineer   Members   -  Reputation: 595

Like
0Likes
Like

Posted 22 November 2012 - 12:09 PM

Going back to basics and writing really simple games (tic-tac-toe, currently) but trying to use a good, clean OO structure. All states are derived from a base class cState:

[source lang="cpp"]class cState {public: virtual void enter() = 0; virtual void update() = 0; virtual void leave() = 0;};[/source]
The code below is for the state manager
[source lang="cpp"]void cGame::changeState(cState* targetState) { currentState->leave(); currentState = targetState; currentState->enter();}[/source]

I was thinking of putting each state in its own file, but this means I will need to pass a pointer to the state manager (so that the state manager knows when to switch states) and also an inclusion for all of the header files for the states that it can transition to. This sounds messy. Is there a better way of doing it?


I've haven't programmed stateful behaviour yet, but it was my understanding that the states themself manage the transition. (stateA->leave() returns stateB, alternatively leave() sets the next state itself). A state will include the states that it can transition to. Because of polymorphism you can then just store a pointer to the base class.

#4 Yrjö P.   Crossbones+   -  Reputation: 1412

Like
3Likes
Like

Posted 22 November 2012 - 12:24 PM

1) What do these states actually represent?
2) Who calls changeState? Can't the states' own logic trigger a switch to other states?
3) If the concrete states form an intimately related system, unique to your particular game, I'd put them in the same .cpp file. Is there any real reason to spread them around? If they grew so huge compilation started being a problem, which file they reside in would be the least of your problems.

#5 Goran Milovanovic   Members   -  Reputation: 1104

Like
0Likes
Like

Posted 23 November 2012 - 11:36 AM

1) What do these states actually represent?
2) Who calls changeState? Can't the states' own logic trigger a switch to other states?
3) If the concrete states form an intimately related system, unique to your particular game, I'd put them in the same .cpp file. Is there any real reason to spread them around? If they grew so huge compilation started being a problem, which file they reside in would be the least of your problems.


This is the right mindset, in my opinion.

Know your needs, and keep it simple.

+---------------------------------------------------------------------+

| Game Dev video tutorials  ->   http://www.youtube.com/goranmilovano |
+---------------------------------------------------------------------+

#6 Silgen   Members   -  Reputation: 178

Like
0Likes
Like

Posted 24 November 2012 - 07:01 AM

Thankyou for all of your replies.

I've tried to take into consideration the points raised in the responses, and I've written a simple program to test this out. I was hoping you guys could give me some feedback - or some general pointers etc.

Extract from cState.h
[source lang="cpp"]class cState {private: static cState* currentState; static bool isRunning;public: virtual void enter() = 0; virtual void update() = 0; virtual void leave() = 0; void setCurrentState(cState*); void updateCurrentState(); void exit();};class cStateA : public cState {public: cStateA(cState*); ~cStateA(); void enter(); void update(); void leave();};[/source]
Extract from cState.cpp

[source lang="cpp"]#include "cState.h"//---cState* cState::currentState;bool cState::isRunning = true;void cState::setCurrentState(cState* target) { currentState = target;}void cState::updateCurrentState() { while(isRunning) { currentState->update(); }}void cState::exit() { isRunning = false;}//---cStateA::cStateA(cState* caller) { //Clean up after the caller state and initialise the current one if(caller) caller->leave(); setCurrentState(this); enter();}cStateA::~cStateA() { std::cout << ">> Destructor called for A" << std::endl;}void cStateA::enter() { std::cout << ">> Entering State A" << std::endl;}void cStateA::update() { std::cout << "Enter desired state: "; if(getch() == 'b') { setCurrentState(new cStateB(this)); }}void cStateA::leave() { std::cout << std::endl << ">> Leaving State A" << std::endl; delete this;}[/source]

Edited by Silgen, 24 November 2012 - 07:20 AM.





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