Tengo una máquina de estados organizadas de esta forma:
//---------------------------------------------------
// Clase para controlar el personaje
//---------------------------------------------------
public class Personaje : Enemy
{
public IdleState idleState;
public RunState runState;
public JumpingState jumpingState;
private RunStateData runStateData;
public NoStateData noStateData;
public override void Start()
{
base.Start();
runState = new RunState(this, stateMachine, "run", runStateData); //correr
idleState = new IdleState(this, stateMachine, "idle", noStateData); //reposo
jumpingState = new JumpingState(this, stateMachine, "jump", noStateData); //saltar
stateMachine.Initialize(runState);
}
}
//---------------------------------------------------
// Clase para controlar los cambios de estado mientras salta
//---------------------------------------------------
public class JumpingState : GenericState<Personaje, NoStateData>
{
public NoStateData noStateData;
public SaltarObstaculo saltarObstaculo;
public SaltarPlataforma saltarPlataforma;
public BajarDeEncimaDelPlayer bajarDeEncimaDelPlayer;
public JumpingState(Entity entity, FiniteStateMachine stateMachine, string animationName, NoStateData stateData) :
base(entity, stateMachine, animationName, stateData)
{
//cosas que se hacen siempre independientemente de la posición del player
saltarObstaculo = new SaltarObstaculo(entity, stateMachine, animationName, noStateData);
//si el player está arriba
saltarPlataforma = new SaltarPlataforma(entity, stateMachine, animationName, noStateData);
//Si el player está abajo
bajarDeEncimaDelPlayer = new BajarDeEncimaDelPlayer(entity, stateMachine, animationName, noStateData);
}
}
//---------------------------------------------------
// Clase para controlar los cambios de estado mientras corre
//---------------------------------------------------
public class RunState : GenericState<Personaje, RunStateData>
{
public NoStateData noStateData;
public BuscarCaminoParaSubir buscarCaminoParaSubir;
public BuscarCaminoParaSubir buscarCaminoParaBajar;
public Perseguir perseguir;
public Atacar atacar;
public OtrasCosas otrasCosas;
public RunState(Entity entity, FiniteStateMachine stateMachine, string animationName, RunStateData stateData) :
base(entity, stateMachine, animationName, stateData)
{
//si el player está arriba
buscarCaminoParaSubir = new BuscarCaminoParaSubir(entity, stateMachine, animationName, noStateData);
//si el player está abajo
buscarCaminoParaBajar = new BuscarCaminoParaBajar(entity, stateMachine, animationName, noStateData);
//si player está en el mismo nivel level
perseguir = new Perseguir(entity, stateMachine, animationName, noStateData);
atacar = new Atacar(entity, stateMachine, animationName, noStateData);
//cosas que se hacen siempre independientemente de la posición del player
otrasCosas= new OtrasCosas(entity, stateMachine, animationName, noStateData);
}
//si por ejemplo estoy corriendo y me encuentro un obstaculo salgo del estado correr
//y voy al estado saltar de la siguiente forma
public override void LogicUpdate()
{
base.LogicUpdate();
if(HayUnObstaculo)
{
stateMachine.ChangeState(personaje.jumpingState.saltarObstaculo);
}
}
}
¿Cual es el problema con todo esto?
Bueno pues a pesar de que todo funciona bien tengo la sensación de que no está bien organizado.
-Lo primero que noto es que lo único que tienen en común los subestados es en nombre de la animación “animationName”.
-Lo segundo es que casi nunca se usan los miembros de esa clase dentro de los métodos de esa misma clase (como el ejemplo de saltar obtaculo).
-Y lo tercero es que veo que en cada clase se hacen cosas dependiendo si el player está arriba, abajo, o en el mismo nivel… y siento una necesidad imperiosa de organizar y enclapsular esos métodos en función de eso y no veo la forma de hacerlo sin estropearlo todo…
Y la preunta es ¿Cómo organizar mejor esta máquina de estados?
Ideas, propuestas, opiniones serán bienvenidas.
Muchas graicas!!