Skip to content

State Inheritance

Sohom Sahaun edited this page Nov 12, 2021 · 18 revisions

State inheritance is a powerful tool to organize the states in a state machine. You can use this feature to create common behavior for states and have other states inherit the behavior.

The methods dealing with state inheritance can be found here.

The following concepts have been discussed:

 

Basics

The concept of state inheritance is similar to GameMaker's object inheritance.

You can inherit all the events from the parent state. The inherited events can be overridden. Obviously, the parent state needs to be declared before the child state.

Example:

/// Create
fsm = new SnowState("walk_child");
fsm
  .add("walk", {
    enter: function() {
      sprite_index = sWalk;
      spd = 3;
    },
    step: function() {
      move_and_collide(spd);
    }
  })
  .add_child("walk", "walk_child", {});

/// Step
fsm.step();

This creates two states, where "walk_child" state is the child of "walk" state; and hence, inherits all the events of "walk" state. In the Step event, the step event of "walk_child" state is called.

 

Overriding Events

Obviously, the above example does nothing. As a better example, we can create a walk state where the character's speed is increased. Everything else remains the same. To do that, we would only change a speed variable in the enter event of the child state.

Example:

fsm = new SnowState("walk_faster");
fsm
  .add("walk", {
    enter: function() {
      spd = 3;
      sprite_index = sWalk;
    },
    step: function() {
      move_and_collide(spd);
    }
  })
  .add_child("walk", "walk_faster", {
    enter: function() {
      fsm.inherit();
      spd = 5;  // Changing the speed for "walk_faster" state
    }
  });

This creates two states, where "walk_faster" state is the child of "walk" state; and hence, inherits all the events of "walk" state. The enter event of the "walk_faster" state has been overridden.

 

Multilevel Inheritance

SnowState supports multilevel inheritance, which means that child states can have child states too. Go bonkers!

Example:

fsm
  .add("attack", { /* Events */ })
    .add_child("attack", "groundAttack", { /* Events */ })
      .add_child("groundAttack", "groundAttack1", { /* Events */ })
      .add_child("groundAttack", "groundAttack2", { /* Events */ })
      .add_child("groundAttack", "groundAttack3", { /* Events */ })
    .add_child("attack", "airAttack", { /* Events */ })
      .add_child("airAttack", "airAttack1", { /* Events */ })
      .add_child("airAttack", "airAttack2", { /* Events */ })

This structure is from oPlayer in the demo project. Events are not included to keep the code shorter.