首页 > 代码库 > State模式之卡通农场(HayDay)

State模式之卡通农场(HayDay)

supercell最近处的卡通农场也叫HayDay异常火爆,这里我也来写一下游戏的主要框架。

此游戏的核心较为简单,就是一个状态机在不停的运作,这里考虑使用状态模式来实现,为什么要选择状态机呢,因为游戏中的绝大多数的角色都是状态在改变行为,所以使用状态机是在合适不过了。

首先分析一下游戏中的元素,要做到分类准确,大致如下图

 

 diablebuildingfreebakingmaturehungrygain 
圈养类/放养类        
植物        
鱼类        
机器类(虾,机器,矿石,火车站)        
消费者(卡车,购买者)        
装饰类(石头,宝箱,装饰树,其他装饰物,地摊)        
果实类        

可能不同的设计者在分类的出发点不同,我是从状态的个数和种类上分类的。

 

using UnityEngine;using System.Collections;public abstract class AbsState {    //当前状态的名字    public string strStateName_;    //当前状态对应的模型    public GameObject curStateModel_;    //当前状态对应的动画片段    public AnimationClip curStateClip_;    //状态持续时间    public long lDuration_;    //切换状态    public abstract void SwitchState(Unit unit); }
using UnityEngine;using System.Collections;//单位对应的时期。比如树 有第一代,第二代,第三代,第四代(第四代是被好友拯救的一代)public enum EnAge{    EN_AGE_1,    EN_AGE_2,    EN_AGE_3,    EN_AGE_4,}//参与状态机的单位public abstract class Unit {    //当前的状态    public AbsState curState_;    //多任务的单位示范完成所有的任务,比如机器可能有多个格子在生产东西,那么必须等到所有的格子都完成了任务才会去切换状态    public bool bFinishTask_;    //单位所在的位置    public Vector2 position_;    //单位所在的时代    public EnAge age_;}

以上是主要的抽象体,一个是负责状态的,一个是辅助单位的 这里也符合了状态模式的设计要求,Unit里面有了对虚拟状态的关联

接下来就是对各个具体的单位和状态进行处理了

 

using UnityEngine;using System.Collections;public class CAnimal : Unit{}
/// <summary>/// Disable state./// 未被激活状态/// </summary>using UnityEngine;using System.Collections;public class DisableState : AbsState{    public override void SwitchState (Unit unit)    {        if(unit is CMachine)        {            Debug.Log("DisableState -> BuildingState");            unit.curState_ = new BuildingState();        }        else        {            Debug.Log("DisableState -> FreeState");            unit.curState_ = new FreeState();        }        }}

 

using UnityEngine;using System.Collections;public class FreeState : AbsState{    public override void SwitchState (Unit unit)    {        if(unit is CMachine)        {            Debug.Log("free -> BakingState");            unit.curState_ = new BakingState();        }        else if(unit is CProduct)        {            unit.curState_ = new GainState();            Debug.Log("free-> GainState");        }        else        {            Debug.Log("free -> matrue");            unit.curState_ = new MatureState();        }    }}

此处省略了所有状态和所有具体单位的代码,都类似的。

最后客户端调用

using UnityEngine;using System.Collections;public class Client : MonoBehaviour {    Unit unit;    // Use this for initialization    void Start () {        //初始化一个动物        unit = new CAnimal();        //动物的初始状体是不被激活的        unit.curState_ = new DisableState();        }        // Update is called once per frame    void Update () {      //测试:抬起space键进行状态切换      //游戏中大部分是通过倒计时的方式进行切换,这不进行说明每种切换的方式,点到为止      if(Input.GetKeyUp(KeyCode.Space))        {            unit.curState_.SwitchState(unit);        }    }}

 

欢迎拍砖