State模式之卡通农场(HayDay)

本文介绍卡通农场HayDay游戏中的状态机设计原理及实现方式。通过状态模式的应用,详细解析了游戏内各类元素(如动物、植物、机器等)的状态变化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
        }
    }
}

 

欢迎拍砖

 

转载于:https://www.cnblogs.com/ptowin/p/3875730.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值