0
public abstract class State<T>
{
    public virtual Enter(T item)
    {
            // an empty method
    }
}

public class ChaseState : State<FieldPlayer>
{
    public override Enter(Player pl)
    {
        // ...
        pl.Fsm.CurrentState = ChaseState.Instance;
        //...
    }
}

public class TendGoal : State<Goalkeeper>
{
   public override Enter(Goalkeeper gk)
   {
       // ...implementation
       gk.Fsm.CurrentState = TendGoal.Instance;
       // ...implementation
   }
}

public class DefendState : State<Team>
{
    public override Enter(Team team)
    {
        // ....    
        team.Fsm.CurrentState = DefendState.Instance;
        //.....
    }
}

“Goalkeeper”和“FieldPlayer”继承自一个抽象类“Player”,而“Team”继承自另一个类。

public class FSM
{
    public /*some type*/ owner;         // PROBLEM 1
                                        // OWNER CAN BE TEAM, GOALKEEPEEPER
                                        // OR FIELD PLAYER
    public /*some type*/ globalState;
    public /*some type*/ currentState;
    public /*some type*/ previousState;
    public void Update()
    {
        if (globalState != null)
        {
            globalState.Execute(owner);  // PROBLEM 2
                                         // IF GLOBAL STATE'S TYPE
                                         // IS AN OBJECT, CANT CALL EXECUTE
                                         // OBJECTS TYPE WILL BE KNOWN ONLY
                                         // DURING RUNTIME
        }
     }
}

“Goalkeeper”、“FieldPlayer”和“Team”类型的每个对象都有一个状态机实例。问题是..泛型不能是属性。

我应该怎么办 ?

4

2 回答 2

0

在阅读了您的代码之后,这里不需要抽象类。您应该将 State 转换为接口,例如:IState 并从中删除通用签名。那么你的 FSM 对象中的属性都可以是 public IState globalState 等。

于 2013-03-25T15:19:33.057 回答
0

如果您将 State 设为普通接口,而不是通用接口,并让其 Enter 方法采用您的球队、守门员、球员等都实现的另一个接口(它甚至可以是空的),它应该可以工作。

public interface IOwner {}

public interface IState
{
    void Enter(IOwner item);
}
public class ChaseState : IState
{
    public void Enter(IOwner pl)
    {
        // ...
        //...
    }
}
public class Player :IOwner { }
public class Something {
    IOwner owner = new Team();
    IState globalState = new ChaseState();
    IState currentState = new DefendState();

    public void Update()
    {
        if (globalState != null)
        {
            globalState.Enter(owner); 
        }
        else if (currentState != null)
        {
            currentState.Enter(owner);
        }
     }
}
于 2013-03-25T15:35:41.247 回答