牧师与恶魔(动作分离版)

前言

之前写的代码中由Controller控制动作,现在我们将其中对动作的控制抽离出来。

Action类

创建一个Action类用来管理所有游戏事物的动作
依据课件设计
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PriestAndDevil;
public class SSAction : ScriptableObject //动作基类          
{

    public bool enable = true;                    
    public bool destroy = false;                  

    public GameObject gameobject{ get; set;}           
    public Transform transform{ get; set;}                   
    public ISSActionCallback callback{get; set;}             

    protected SSAction() {}                        

    public virtual void Start()                    
    {
        throw new System.NotImplementedException();
    }

    public virtual void Update()
    {
        throw new System.NotImplementedException();
    }
}

public class CCMoveToAction : SSAction   //动作实现                     
{
    public Vector3 target;        
    public float speed;          

    public static CCMoveToAction GetSSAction(Vector3 target, float speed)
    {
        CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();
        action.target = target;
        action.speed = speed;
        return action;
    }

    public override void Update()
    {
        this.transform.position = Vector3.MoveTowards(this.transform.position, target, speed * Time.deltaTime);
        if (this.transform.position == target)
        {
            this.destroy = true;
            this.callback.SSActionEvent(this);      
        }
    }

    public override void Start()
    {}
}

public class CCSequenceAction : SSAction, ISSActionCallback //动作组合实现复杂动作
{
    public List<SSAction> sequence;   
    public int repeat = -1;         
    public int start = 0;              

    public static CCSequenceAction GetSSAction(int repeat, int start, List<SSAction> sequence)
    {
        CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction>();
        action.repeat = repeat;
        action.sequence = sequence;
        action.start = start;
        return action;
    }

    public override void Update()
    {
        if (sequence.Count == 0) return;
        if (start < sequence.Count)
        {
            sequence[start].Update();     
        }
    }
    //接口定义
    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,int intParam = 0, string strParam = null, Object objectParam = null)
    {
        source.destroy = false;          
        this.start++;
        if (this.start >= sequence.Count)
        {
            this.start = 0;
            if (repeat > 0) 
                repeat--;
            if (repeat == 0)
            {
                this.destroy = true;               
                this.callback.SSActionEvent(this); 
            }
        }
    }

    public override void Start()
    {
        foreach (SSAction action in sequence)
        {
            action.gameobject = this.gameobject;
            action.transform = this.transform;
            action.callback = this;              
            action.Start();
        }
    }

    void OnDestroy()
    {}
}

public enum SSActionEventType : int { Started, Competeted }

public interface ISSActionCallback
{
    void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,int intParam = 0, string strParam = null, Object objectParam = null);
}

//动作管理器基类
public class SSActionManager : MonoBehaviour, ISSActionCallback                     
{

    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    
    private List<SSAction> waitingAdd = new List<SSAction>();                       
    private List<int> waitingDelete = new List<int>();                                           

    protected void Update()
    {
        foreach (SSAction ac in waitingAdd)
        {
            actions[ac.GetInstanceID()] = ac;                                     
        }
        waitingAdd.Clear();

        foreach (KeyValuePair<int, SSAction> kv in actions)
        {
            SSAction ac = kv.Value;
            if (ac.destroy)
            {
                waitingDelete.Add(ac.GetInstanceID());
            }
            else if (ac.enable)
            {
                ac.Update();
            }
        }

        foreach (int key in waitingDelete)
        {
            SSAction ac = actions[key];
            actions.Remove(key);
            Destroy(ac);
        }
        waitingDelete.Clear();
    }

    public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager)
    {
        action.gameobject = gameobject;
        action.transform = gameobject.transform;
        action.callback = manager;
        waitingAdd.Add(action);
        action.Start();
    }
    protected void Start()
    {

    }
    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null){}
}
//动作管理器实现
public class CCActionManager:SSActionManager
{
    private CCSequenceAction moverole_act;
    private CCMoveToAction moveboat_act;
    public Controller controller;

    protected new void Start()
    {
        controller = SSDirector.GetInstance().CurrentScenceController as Controller;
        controller.action_manager = this;
    }
    public void MoveBoat(GameObject boat,Vector3 target,float speed)
    {
        moveboat_act = CCMoveToAction.GetSSAction(target,speed);
        this.RunAction(boat,moveboat_act,this);
    }
    public void MoveRole(GameObject role,Vector3 middle,Vector3 end,float speed)
    {
        SSAction move_to_middle = CCMoveToAction.GetSSAction(middle,speed);
        SSAction move_to_end = CCMoveToAction.GetSSAction(end,speed);
        List<SSAction> act_list = new List<SSAction> {move_to_middle,move_to_end};
        moverole_act = CCSequenceAction.GetSSAction(1,0,act_list);
        this.RunAction(role,moverole_act,this);
    }
}

Controller

Controller更改如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PriestAndDevil;
public class Controller : MonoBehaviour,ISceneController,IUserAction
{
    public Side left_side;//左岸为起点起点
    public Side right_side;//终点
    public Boat boat;
    public GameObject river;
    private List<Role> role_array;
    UserGUI gui;
    public Judge judge;
    public CCActionManager action_manager;
    void Start()
    {
        SSDirector director = SSDirector.GetInstance();
        director.CurrentScenceController = this;
        gui = gameObject.AddComponent<UserGUI>() as UserGUI;
        LoadResources();
    }
    public void LoadResources()
    {
        left_side = new Side("left");
        right_side = new Side("right");
        boat = new Boat();
        role_array = new List<Role>();
        river = Instantiate(Resources.Load("Prefabs/Water",typeof(GameObject)),new Vector3(0, -0.5F, -0.49F), Quaternion.identity) as GameObject;
        judge = new Judge();
        action_manager = gameObject.AddComponent<CCActionManager>() as CCActionManager;  
        
        for (int i = 0; i < 3; i++)
        {
            Role role = new Role("priest");
            role.SetName("priest" + i);
            role.SetPosition(left_side.GetEmptyPosition());
            role.GoSide(left_side);
            left_side.AddRole(role);
            role_array.Add(role);
        }
        for (int i = 0; i < 3; i++)
        {
            Role role = new Role("devil");
            role.SetName("devil" + i);
            role.SetPosition(left_side.GetEmptyPosition());
            role.GoSide(left_side);
            left_side.AddRole(role);
            role_array.Add(role);
        }
    }
    public void MoveBoat()
    {
         if (boat.IsEmpty() || gui.sign != 0)
            return;
        action_manager.MoveBoat(boat.GetBoat(),boat.GetTargetPos(),boat.speed);
        gui.sign = judge.Check();
    }
    public void MoveRole(Role role)
    {
        if (gui.sign != 0) 
            return;
        if (role.IsOnBoat())
        {
            Side Side;
            if (boat.GetBoatSign() == 1)
                Side = left_side;
            else
                Side = right_side;
            boat.DeleteRoleByName(role.GetName());
            Vector3 end = Side.GetEmptyPosition(); 
            Vector3 middle = new Vector3(role.GetRole().transform.position.x, end.y, end.z); 
            action_manager.MoveRole(role.GetRole(),middle,end,role.speed);
            role.GoSide(Side);
            Side.AddRole(role);
        }
        else
        {                                
            Side Side = role.GetSide();
            if (boat.GetEmptyNumber() == -1 || Side.GetSideFlag() != boat.GetBoatSign()) 
                return;   

            Side.DeleteRoleByName(role.GetName());
            Vector3 end = boat.GetEmptyPosition();
            Vector3 middle = new Vector3(end.x,role.GetRole().transform.position.y,end.z);
            action_manager.MoveRole(role.GetRole(),middle,end,role.speed);
            role.GoBoat(boat);
            boat.AddRole(role);
        }
        gui.sign = judge.Check();
        if (gui.sign == 1)
        {
        
        }
    }
    public void Restart()
    {
        left_side.Reset();
        right_side.Reset();
        boat.Reset();
        for (int i = 0; i < role_array.Count; i++)
        {
            role_array[i].Reset();
        }
        if (gui.sign == 1)
        {
        }
    }
    public int Check()
    {
        return 1;
    }
}

其余保持基本不变,效果和之前一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值