State Machine problems?

gurglovt

Member
I have a player character consisting of 2 objects (oPlayer and oArms) and while states work for oPlayer, oArms seems to not respond to them:

Controller object Create event:
GML:
enum states
{
    idle,
    walk,
    attack,
    parry
}
oPlayer step event:
Code:
if (state == states.idle)
{
    #region Idle
       
    //Function
    if moving = true
    {
        state = states.walk;
    }
   
    if key_attack
    {
        state = states.attack;
    }
   
    if key_parry
    {
        state = states.parry;
    }
   
    //Sprites
    sprite_index = sPlayer_Idle;
   
    #endregion
}

else if (state == states.walk)
{
    #region Walk
   
    //Function
    if moving = false
    {
        state = states.idle;
    }
   
    if key_attack
    {
        state = states.attack;
    }
   
    if key_parry
    {
        state = states.parry;
    }
   
    //Sprites
    sprite_index = sPlayer_Walk;
   
    #endregion
}

else if (state == states.attack)
{
    #region Attack
   
    //Function
    global.attacking = true;
   
    if global.attacking = false
    {
        state = states.idle;
    }
   
    //Sprites
    sprite_index = sPlayer_Idle;
   
    #endregion
}
oArms Step event:
Code:
x = oPlayer.x;
y = oPlayer.y;

image_angle = point_direction(x,y,mouse_x,mouse_y);

if (state == states.idle)
{
    #region Idle
   
    //Sprites
    sprite_index = sPlayer_Arms_Idle;
   
    #endregion
}

else if (state == states.walk)
{
    #region Walk
   
    //Sprites
    //currently set to an animated sprite to see if state changes when just walking
    sprite_index = sPlayer_Arms_Parry;
    image_speed = 1;
   
    #endregion
}

else if (state == states.attack)
{
    #region Attack
   
    //Function
    sprite_index = sPlayer_Arms_Attack;
   
    if image_index >= 3
    {
        with (instance_create_depth(x,y,1,oArrow))
        {
            move_towards_point(mouse_x,mouse_y,oArrow.spd);
        }
        global.attacking = false;
    }
   
    //Sprites
    sprite_index = sPlayer_Arms_Attack;
   
    #endregion
}
Any ideas? thanks in advance!
 
Last edited:

Roldy

Member
Both scripts for the two objects step event reference a variable 'state.'

Is that an object variable or is it local? Do they each have a state variable? If so when do they get set to be the same?

Also pay attention to this global.attacking.

The following is pointless code:

GML:
    #region Attack
 
    //Function
    global.attacking = true;
 
    if global.attacking = false
    {
        state = states.idle;
    }
 
Last edited:

gurglovt

Member
the global.attacking thing was just an idea of mine to work around having to have two objects acting as one, so I set an "attacking" variable that triggers an animation and shoots an arrow on oArms and then sets attacking to false on Player. I set it to global because I wasn't sure it was working across both objects

I've tried using switch statements before, I didn't fully understand them, I wanted to just make something, but I will dabble with converting the code to switch statements. I didn't understand how to reference the correct object in an external script
 

Nidoking

Member
I set it to global because I wasn't sure it was working across both objects
It's not.

Neither is state.

Nor is any other variable you've defined in this way. Learn to use dot notation, or make absolutely everything global. Those are your options.
 

gurglovt

Member
Thanks, I'll try that, but I don't understand how oPlayer responds to an enumerator on a separate control object if I haven't used global.state before?
 

gurglovt

Member
By setting the "state" variable to "oPlayer.state" on oArms, it all works perfectly, I think that oController only works with oPlayer because the conditions to change state work for oPlayer but not for oArms.

In any case thanks everyone for their input and help, it's greatly appreciated!
 
Top