Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualKhatharr

Posted 06 January 2013 - 11:31 PM

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?

#2Khatharr

Posted 06 January 2013 - 11:31 PM

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

#1Khatharr

Posted 06 January 2013 - 11:31 PM

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.<br />&nbsp;<blockquote class="ipsBlockquote"><p>1) pre-move state :&nbsp; checks what tiles are available to potentially move to. any tiles that are bad are displayed red.<br />2.) get user input:&nbsp;&nbsp;&nbsp; lets user use keyboard/mouse to select tile to move to.<br />3.) perform move:&nbsp;&nbsp;&nbsp; if tile is good for moving, move player there.<br />4.) clean up:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reset whatever variables are needed.</p></blockquote><br />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.<br /><br />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.<br /><br />Second thing, use bigLongFunctionNamesThatAreVeryExplicitEvenThoughTheyLookFunny() to handle each state branch in the series.<br /><br />Finally, set up the scene's update function to implement the state machine and just switch on the current state.<br /><pre class="_prettyXprint _lang-code _linenums:NaN">int update() {
switch(m_phase) {
case START_TURN: doPhaseStartTurn(); break;
case PLAYER_INPUT_MOVEMENT: doPhasePlayerInputMovement(); break;
case OTHER_CRAP: doPhaseOtherCrap(); break;
default: x /= 0;
}
}</pre><br />Alternatively you can put functors in an array or container and call by index based on the phase.<br /><br />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.<br /><br />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.<br /><br />I don't know if I explained that clearly. Did it make sense?

PARTNERS