State — RexDac Academy

RexDac AcademyNotas técnicas · Ayuda tener algunos conocimientos previos
0%Notas publicadas leídas · en este dispositivo

Principios y arquitectura / Patrones de diseño / De comportamiento

State

Notas originales de SunDiaL · Ver fuente en inglés

State es un patrón muy parecido a Strategy en su implementación, pero tiene una diferencia fundamental: modela una máquina de estados.

  • Una estrategia:
    • Se comunica desde el exterior.
    • No conoce otras estrategias.
    • No cambia una vez elegida.
  • Un estado:
    • Se determina desde el interior y puede comunicarse o no al exterior.
    • Conoce todos los demás estados posibles.
    • Cambia constantemente.
public class Character : IState
{
	private IState currentState = new IdleState(this);
	
	public void Update() { currentState.Update(); }
	public void Jump() { currentState.Jump(); }
	public void Land() { currentState.Land(); }
	
	internal void TransitionTo(IState state)
	{
		this.currentState = state;
	}
}

public interface IState
{
	public void Update();
	public void Jump();
	public void Land();
}

/// <summary>
/// Base class used to provide a default implementation.
/// It's cleaner to override relevant virtual methods than to bloat the code overriding irrelevant abstract methods.
/// </summary>
public abstract class BaseState : IState
{
	private Character character;
	
	public BaseState(Character character)
	{
		this.character = character
	}
	
	public virtual void Update() { /*nothing to do*/ };
	public virtual void Jump() { /*nothing to do*/ };
	public virtual void Land() { /*nothing to do*/ };
}

public class IdleState : BaseState
{
	public override void Update()
	{
		if(Key.IsPressed("spacebar"))
		{
			this.Jump();
		}
	}
	
	public override void Jump()
	{
		character.TransitionTo(new JumpingState(character));
	}
}

public class JumpingState : BaseState
{
	public override Update()
	{
		if(character.TouchedGround())
		{
			this.Land();
		}
	}
	
	public override void Land()
	{
		character.TransitionTo(new IdleState(character));
	}
}