• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
BambooCatfish

Question about using "Game States"

11 posts in this topic

Ok so lets say I have this:

 


enum GameState
{
   load, pause, idle, movePlayer, etc...
}

 

how is a good way to handle being in different states? The only way I know would be to use conditional branches in the update loop. ie:



privave void update()
{
     if (gameState == GameState.something)
              updateGameStateSomething();
     else if (gameState == GameState.somethingElse)
              updateGameStateSomethingElse();
     
     //etc...


}

 

A better way?

 

Thanks

Nick

 

 

0

Share this post


Link to post
Share on other sites

Right on, thank you guys for this info!

 

I actually had the L Spiro one saved in my bookmarks byt forgot about it (wayy to many folders/nesting :-/ ). I read through them both a couple of times and am still tryin to wrap my head around it.

 

So in the L Spiro one each state is a class/object inherited from a base class "GameState" or something and the information is passed from a instance/pointer of the Game class/object, with each state grabbing what it needs? I like this approach if thats the case.

 

The other one is alot to read and I have to read it a few times to get more of a understanding from it.

 

A follow up question... I am using scenes right now, similar to the states TitleScene, GameScene, OptionsScene, etc. I had thought the scenes would handle the states internally but from these approaches I should ditch scenes and make each scene a state? Would that mean its better to keep all my data inside the main game class instead of some sort of scene Object?

 

Right now i have something that looks like this ( in general)

 

class MainGame()
{
   
     SceneObject scene;

   public MainGame(){} //constructor

    pubic void init(){} // init method.
 

    public void update()
   {
     scene.update();
   }

   public  void draw()
  {
       scene.draw();
   }

   
  void changeScene(SceneObject newScene){}

}

 

class GameScene: SceneObject
{
      List<Enemies> enemies;
      PlayerObject playerObject;
     TIleMap map;
 
     public SceneObject() {} // constuctor

     public void init() {}   // init method.
      
     pubic void update(){}   //update stuff
     
     public void draw() {}   //daw stuff.
}

 

If this doesnt make sense let me know and I will try to explain better.

Edited by BambooCatfish
0

Share this post


Link to post
Share on other sites

Sorry double post.... I had a thought.

 

I may have asked the wrong question or got my terminology wrong (still got some good info though!).

 

The project I am working on is (going to be) a simple turn based game where the player can move X number of sqares on a tile map and attack once per turn, then the enemies do the same. I am currently working on one thing at a time and right now the move action is what I am working on. I was thinking about states for this perticualar action:

 

1) pre-move state :  checks what tiles are available to potentially move to. any tiles that are bad are displayed red.

2.) get user input:    lets user use keyboard/mouse to select tile to move to.

3.) perform move:    if tile is good for moving, move player there.

4.) clean up:             reset whatever variables are needed.

 

Thats what I was thinking about when talking about states... handled the same way? Then if i have an attack action:

 

1.) check what is close enough to attack.

2.) let user to select from list of potential targets.

3.) attack target, deal damage, add effects, etc.

4.) check for death, clean up, etc.

 

i dont know how to handle that modularly.

Edited by BambooCatfish
0

Share this post


Link to post
Share on other sites
The scene is like a mini-program. It's a unit of exchangeable logic that can be plugged in to the main loop. You can (and probably will) have some sub-states within a scene, but if you get enough that things get cluttered then you should probably look at modifying your scene structure some, or using an internal dispatcher for a specific scene, since it looks like that's what we're going to be discussing here.
1) pre-move state : checks what tiles are available to potentially move to. any tiles that are bad are displayed red.
2.) get user input: lets user use keyboard/mouse to select tile to move to.
3.) perform move: if tile is good for moving, move player there.
4.) clean up: reset whatever variables are needed.

In cases like this it doesn't make sense to have multiple scenes (since we'd just end up hauling a huge amount of state from scene to scene in a big circle), but we definitely want specific stages to the repeating logic within the scene itself, and a small and simple finite state machine can make that happen for us.

First thing to do is to make room for all of the state within the scene to live comfortably. That means let everything have its own state variable that exists even when that specific variable isn't being altered by the current state. This way we can have the option of 'backing up' to the previous state and still having sensible values from when we left it.

Second thing, use bigLongFunctionNamesThatAreVeryExplicitEvenThoughTheyLookFunny() to handle each state branch in the series.

Finally, set up the scene's update function to implement the state machine and just switch on the current state.
 
int update() {
  switch(m_phase) {
    case START_TURN: doPhaseStartTurn(); break;
    case PLAYER_INPUT_MOVEMENT: doPhasePlayerInputMovement(); break;
    case OTHER_CRAP: doPhaseOtherCrap(); break;
    default: x /= 0;
  }
}

Alternatively you can put function pointers in an array or container and call by index based on the phase.

Now that will work up to a pretty good degree of complexity, but if things get too crazy for that kind of architecture then you can implement a state-stack, which would be a situation where instead of there being a single active state that's updated by the main loop there's a state in the main loop which can contain a state that can contain a state, and so on. That takes up more resources since each active state in the stack has all of its resources loaded even if they're not being used by the member state, but it also means that each state can have access to the resources of the states that are below it on the stack.

For instance if you have your main menu at the bottom of the stack, then your world map on top of that, then your item menu on top of that then you can proc the world map's draw() function from your item menu scene. You could draw the world map, apply a blur filter, then draw the menus on top of that for some nice effects and better immersion. When you're done with the item menu then you just signal its destruction to the world map that owns it and then on the next frame the world map can destroy the menu scene and resume normal execution. If you want to return to the main menu then the world map signals to the man menu state that it's done and then the main menu destroys the world map scene and takes control of execution on the next frame, etc.

I don't know if I explained that clearly. Did it make sense? Edited by Khatharr
1

Share this post


Link to post
Share on other sites

Thanks it makes sense. That's how I was doing things. I guess I'll just keep doing that until it becomes to complex and I need to change.

0

Share this post


Link to post
Share on other sites

I know people have already given some pretty good answers, but I'll throw in my two cents.

Just giving you the .hpp file, I have a GameStateManager and a GameStateObject (the intention of the latter is to be extended by classes that are a game state - such as main menu, playing level, editing level, etc.)

 

Both are in one .hpp:

 






#ifndef GAME_STATE_MANAGER_HPP
#define GAME_STATE_MANAGER_HPP

#include "Graphics.hpp"
#include "GlobalDefines.hpp"
#include <stack>

class GameStateManager;

class GameStateObject
{
public:
/* Passed in parameter is the game state name. Can be left blank for an auto-generated game state name
* If a non-empty string is passed in, it must not begin with _ (underscore) - if it does, the auto-generated name is used
*
* gameStateManager MUST NOT be null - otherwise you cannot use this as a valid game state object
*
* If you want multiple instances of an object to be allowed as separate states, then leave the string blank
* If you only want 1 instance of the object to be allowed as a state, specify your own name here
*/
GameStateObject (GameStateManager *gameStateManager, std::string gameStateName = "");

~GameStateObject ();

// called every time this state becomes active
virtual void OnEnterState () { }

// called right before this state is left
virtual void OnLeaveState () { }

// a game state object should at least draw something
virtual void Draw2d () = 0;

virtual void Update (double dTime) { }

virtual void MouseClick(sf::Mouse::Button button, sf::MouseState state, int x, int y) { }

virtual void MouseMoved(int x, int y, int dx, int dy) { }

virtual void MouseDragged(int x, int y, int dx, int dy) { }

virtual void MouseWheel(int dir) { }

virtual void KeysDown(sf::Event::KeyEvent key) { }

virtual void KeysUp(sf::Event::KeyEvent key) { }

virtual void TextEntered(char ch) { }

virtual void Resize(int w, int h) { }

virtual void FocusChanged(bool gained) { }

std::string GetName ();

private:
std::string m_gameStateName;

GameStateManager *m_gameStateManager;

static std::string GetUniqueName ();

};

class GameStateManager
{
public:
GameStateManager();

/* Push a new state on the state stack.
* stateName must be a valid name of a state object that has already been added through AddState
* Returns true if the state was found in the pool of states, false otherwise
*/
bool PushState ( std::string stateName );

/* Pops the current top-of-the-stack state off the stack, and returns control to the previously pushed state
* This function does not remove the state from the pool at all
*/
std::string PopState ();

GameStateObject* GetCurrentState ();

// the update functions

void Draw2d (); // a game state object should at least draw something

void Update ( double dTime );

void MouseClick ( sf::Mouse::Button button, sf::MouseState state, int x, int y );

void MouseMoved ( int x, int y, int dx, int dy );

void MouseDragged ( int x, int y, int dx, int dy );

void MouseWheel ( int dir );

void KeysDown ( sf::Event::KeyEvent key );

void KeysUp ( sf::Event::KeyEvent key );

void TextEntered ( char ch );

void Resize ( int w, int h );

void FocusChanged ( bool gained );

private:
// The following two functions are private, because they're only called by the GameStateObject constructor

/* Adds a state to the pool of states.
* This function does not make the newly added state active, it only allows it to be made active later on.
* stateName MUST be a non-empty string
* If a state with the specified stateName already exists, return is false, otherwise it's true
*/
bool AddState ( GameStateObject *stateObject ); // stateName must be a non-empty string, and must not repeat with a previous state

/* Removes a state from the pool of states.
* If the state to be removed is currently the active one (on top of the stack), then it's popped off before being removed from the pool.
* Returns true if state is found, false otherwise
*/
bool RemoveState ( std::string stateName );

std::stack <GameStateObject*> m_statesStack;

std::vector<GameStateObject*> m_states;

class EmptyState : public GameStateObject
{
public:
EmptyState (GameStateManager *gsm) : GameStateObject(gsm, "") { }
void Draw2d () { }
};

GameStateObject *m_emptyState; // to avoid having lots of 'if' 'else' comparisons

bool m_needToPopTop;

friend GameStateObject;
};

#endif

The startup code pushes a MainMenu class that extends the GameStateObject.

The thing that works fairly well with this is that a state doesn't need to know what it's parent state is, all it has to call is GameStateObject::PopState() to return full control to the previous state. Seems to have worked fairly well for me so far.

1

Share this post


Link to post
Share on other sites
I'm not a big fan of game state manager classes. I usually use run and return successor with my game states where things like the update() method return a smart pointer to the state the system should be in (which can be a pointer to self). Example code can be seen in this thread.
1

Share this post


Link to post
Share on other sites

Thanks guys you all gave me a lot of options and a bunch to think about. I have to read through it all and decide what is going to work best for me, I'll be back when I have more questions.

 

-Nick

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0