Reply to topic  [ 1 post ] 
 State Machines 
Author Message
Level 38
Level 38
User avatar

Cash on hand:
435.45

Bank:
2,750,364.30
Posts: 10364
Joined: Sun Oct 26, 2008 5:47 am
Group: Dev Team
 State Machines
Hello there, my lovely little berry cunts!
Today I'm teaching you about State Machines.


What is a state machine?

Basically, it is a set of predetermined values to choose from as a selected state.
For example, let's say you want to make a player character for a 2D platformer, and he has different statuses or states that he can be in.
Some typical states a player can find himself in platformers are Idle, Walking, Running, Jumping, Dead. A state machine lets you choose one active state at a time.
If your player is running, he is not idle, jumping, walking nor being dead.

Imagine if you had to keep track of all that shit with booleans.
You're walking. Oh, hold on, let's set all those other booleans as false. That shit is tedious, and gets worse, the more different things you want your player be capable of.


How to make a state machine

In languages like C#, java, etc, there are things called enumerations or enums. an enumeration is basically just a number with a name.
Here is an example of what an enumeration looks like in C#:
Code:
public enum MovieCommand
    {
        Play,
        Stop,
        Pause,
        Resume,
        Exit
    }

the MovieCommand enumeration has five different items, all accessable by either their name, or the number in which their order is.
For example. If you make a MovieCommand object and want it to have a certain state like "play" you can just set it as
Code:
movieCommand = MovieCommand.Play;

or
Code:
movieCommand = 0;
(since "Play" is on the 0th spot.)

you can also check with if statements or switch cases to see if an enumeration has a certain value.
for example:
Code:
if(movieCommand == MovieCommand.Pause)

or
Code:
if(movieCommand == 2)



Using States in Flash

Flash does not support enumerations, so in order to set a predetermined set of values to names, one needs to create several variables. one for each state.
This also means that there does not need to be an enumeration object or definition.

So, how do you do it?
Here is how! You create your states one by one. First, let's create a public static variable with a name and of the type Integer.
Code:
public static var PLAYER_STATE_IDLE:int = 0;

as you can see, the name is in all capital letters. This is just a design choice I make in order to spot variables that I don't want changed in values.
the variable is public in order to let you have access to it from anywhere, and it is static so that there is only one instance of it. By one instance, I mean that if your variable is inside a class, all objects of said class will share that variable's value, and if you change it from one instance of the class, it is changed everywhere.
Because of it being static, it is also accessed differently. For example, a normal variable is accessed by calling the object's name, add a dot, and then the variable.
If your class is named PenisBush, which has one dynamic variable called health, and a static variable called maxHealth
and you have 3 PenisBush objects, all called penis,bush, and obama, you access their normal dynamic values by calling for example obama.health
but for static variables, you call the variable using the class name, that is PenisBush.maxHealth.
So, anyway...
The variables are integers so that you can access them by their names and indices. PLAYER_STATE_IDLE was earlier defined to be the number 0. Let's make some more states.
Code:
public static var PLAYER_STATE_IDLE:int = 0;
public static var PLAYER_STATE_RUNNING:int = 1;
public static var PLAYER_STATE_JUMPING:int = 2;
public static var PLAYER_STATE_DEAD:int = 3;


you now have 4 different player states. idle is on place 0, running on place 1, and so on.
You now want to make a normal dynamic variable that will be your selected state.
Code:
var playerState:int;

this playerState will be the variable you access to get and set the state of your player.
let's set the player state to running!

Code:
playerState = PLAYER_STATE_RUNNING;

your playerState will now have the value 1;
let's make an if statement where if the player is dead, we remove one extra life (extra guy, 1up, life, you get it)
Code:
if(playerState == PLAYER_STATE_DEAD)
{
     extraLife--;
}

alternatively you can just use the number, even if your playerState was assigned using a state definition
Code:
if(playerState == 3)
{
     extraLife--;
}


Here's one of the most common uses of the states. The switch case state machine.

Code:
switch(playerState)
{
     case PLAYER_STATE_IDLE:
     {
            //do stuff
            break;
     }
     case PLAYER_STATE_RUNNING:
     {
            //do stuff
            break;
     }
     case PLAYER_STATE_JUMPING:
     {
            //do stuff
            break;
     }
     case PLAYER_STATE_DEAD:
     {
            //do stuff
            break;
     }
}

You have now split up your player logic into four different states. If you're dead, you do the stuff inside the dead case.
This allows you to structure your code in a manner that makes it easy to read and understand.


The ups and downs of using states


states are extremely easy to get for coders who are not familiar with your code.
states are simple and very useful for simple designs.

states help you separate your logic code into different places. so you don't have to keep track of running stuff when you're dead.

You can only be one of the states for each instance you make.
That means that your player cannot be dead and running at the same time. But what if you're dead and still running, like an ostrich that was decapitated a second ago?
One way of dealing with this is making a second level state machine inside your dead state, that is, you give death different states as well. Another way is just adding a dead_and_running state.
The more states you have, the more complex does your state machine get.
If many states are similar, one could argue whether or not those states should be the same state and instead have another level of states where if you're dead
, you then choose from three more states within being dead, like for example rotting, swollen, bones. This is where you might want to move away from states and use something else.

Extra Stuff

In many cases, you might want to add a size counter for your states, that is, add a state called size, or something that returns the amount of different states.
That way you can more easily check if you're outside the range of available states. This is how I usually define states with a size counter.
Code:
public static var BLOCK_STATE_SIZE:int      = 0; //to keep track of the amount of states (size is now 0)
public static var BLOCK_STATE_IDLE:int      = BLOCK_STATE_SIZE++; //dis block aint movin' (size is now 1, idle is now 0)
public static var BLOCK_STATE_PUSHED:int   = BLOCK_STATE_SIZE++; //this block is moving to the right or left (size is now 2, pushed is now 1)
public static var BLOCK_STATE_FALLING:int   = BLOCK_STATE_SIZE++; //this block is falling down (size is now 3, falling is now 2)

As you can see, I created the size first, then just add to the size for each new state. All new states get their representative numbers.


Got any questions regarding states or alternatives to states? feel free to ask or add anything in this thread.
I hope this tutorial helped you become the ultimate pokemon trainer! :monja

_________________
My Pixiv
Image
Spoiler: show
OLD VERSION, BITCHES!
Image


Sun Aug 03, 2014 6:50 pm
Profile E-mail
Display posts from previous:  Sort by  
Reply to topic   [ 1 post ] 
 

Similar topics

 
State of the Union Address 2015
Forum: ./Announcements
Author: Pantsman
Replies: 25
State of the Union Address 2018
Forum: ./Announcements
Author: Pantsman
Replies: 4
The State of Gen Serious
Forum: ./General No Spam
Author: Rem
Replies: 39
State of the Union address 2016.
Forum: ./Announcements
Author: Pantsman
Replies: 22
Top


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Mods Database :: Imprint :: Crawler Feeds :: Reset blocks
Designed by STSoftware for PTF.

Portal XL 5.0 ~ Premod 0.3 phpBB SEO