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

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

在这里插入图片描述

说明

这次游戏是基于上一次的牧师与魔鬼游戏,不同之处主要有两点。其一是将FirstController中的判断游戏结束代码逻辑分离,放到Judge裁判类中;其二是用CCActionManagement动作管理器,对所有游戏对象的动作进行管理,替换原本的move和moveCtrl。

裁判类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Judge : MonoBehaviour
{
    private FirstController sceneController;
    public bool gameOver = false;//是否结束
    public bool gameWin = false;//是否胜利
    int r_a = 0, r_d = 0;
    int l_a = 3, l_d = 3;

    void Start()
    {
        sceneController = (FirstController)SSDirector.getInstance().currentSceneController;
        sceneController.gameJudge = this;

    }

    void Update()
    {
        //左右天使与魔鬼的数量
        l_d = sceneController.leftD;
        r_d = sceneController.rightD;
        l_a = sceneController.leftA;
        r_a = sceneController.rightA;
        check();
    }

    void check()
    {
        if (l_a > 0 && l_a < l_d || r_a > 0 && r_a < r_d) 
        {
            gameOver = true;
            gameWin = false;
            sceneController.GameOver();
        }
        else if (r_a == 3 && r_d == 3) 
        {
            gameOver = true;
            gameWin = true;
            sceneController.GameOver();
        }
    }
}

start()函数用于初始化,获取场景控制器实例(有裁判对象),用于传递游戏结束和游戏胜利标志(gameOver和gameWin)
每次Update更新,左右河岸牧师与魔鬼的数量,裁判类judge根据这四个变量进行判断

动作管理相关类

在这里插入图片描述
SSAction是各种动作的父类,其子类CCSequenceAction和CCMoveToAction分别对应顺序组合动作和单个移动动作。
GetSSAction用于定义动作,例如,CCMoveToAction中,设置移动的目的地坐标、移动速度,而在CCSequenceAction中,设置动作组合顺序、重复次数、开始动作。

SSActionManager是动作管理器的父类,主要是管理动作何时执行和销毁。CCActionManger继承实现,主要用于场景控制器通信。
RunAction将动作绑定到游戏对象,并指定动作管理器。UpDate用于执行和销毁动作。

具体代码

SSAction类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SSAction : ScriptableObject {

	public bool enable = true;
	public bool destory = false;

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

	protected SSAction () {}

	// Use this for initialization
	public virtual void Start () {
		throw new System.NotImplementedException ();
	}
	
	// Update is called once per frame
	public virtual void Update () {
		throw new System.NotImplementedException ();
	}
		
}

CCSequenceAction类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CCSequenceAction : SSAction, ISSActionCallback
{
	public List<SSAction> sequence;
	public int repeat = -1; //repeat forever,循环执行次数
	public int start = 0;

	public static CCSequenceAction GetSSAction(int repeat, int start , List<SSAction> sequence){
        //非持久化,该对象只存在于内存中,可以被GC垃圾回收,调用一次就创建一次。
        CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction> ();
		action.repeat = repeat;
		action.sequence= sequence;
		action.start = start;
		return action;
	}
		
	// Update is called once per frame
	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.destory = false;
		this.start++;
		if (this.start >= sequence.Count) {
			this.start = 0;
			if (repeat > 0) repeat--;
			if (repeat == 0) { this.destory = true; this.callback.SSActionEvent (this); }
		}
	}

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

	void OnDestory() {
		//TODO: something
	}
}

CCMoveToAction类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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) {
			//waiting for destroy
			this.destory = true;  
			this.callback.SSActionEvent (this);
		}
	}

	public override void Start () {
	}
}

SSActionManager类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SSActionManager : MonoBehaviour {

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

	// Update is called once per frame
	protected void Update () {
		//添加动作到管理器
        //GetInstanceID是对象Object的id
        foreach (SSAction ac in waitingAdd) actions [ac.GetInstanceID ()] = ac;
		waitingAdd.Clear ();
		//等待销毁or执行动作
		foreach (KeyValuePair <int, SSAction> kv in actions) {
			SSAction ac = kv.Value;
			if (ac.destory) { 
				waitingDelete.Add(ac.GetInstanceID()); // release action
			} else if (ac.enable) { 
				ac.Update (); // update action
			}
		}
		//销毁动作
		foreach (int key in waitingDelete) {
			SSAction ac = actions[key]; 
			actions.Remove(key); 
			Object.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 ();
	}


	// Use this for initialization
	protected void Start () {
	}
}

CCActionManager类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CCActionManager : SSActionManager, ISSActionCallback {
	
	private FirstController sceneController;
	private CCMoveToAction moveToA , moveToB, moveToC, moveToD;

	protected new void Start() {
		sceneController = (FirstController)SSDirector.getInstance ().currentSceneController;
		sceneController.actionManager = this;
	}

	// Update is called once per frame
	protected new void Update ()
	{
        //调用父类SSActionManager的函数
        base.Update ();
	}
		
	//region--endregion用于折叠代码,无实际意义
	#region ISSActionCallback implementation
	public void SSActionEvent (SSAction source, SSActionEventType events = SSActionEventType.Competeted, int intParam = 0, string strParam = null, Object objectParam = null)
	{

	}
	#endregion
}

ISSActionCallback接口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

FirstController类中改动不大,主要是用CCActionManeger对象处理替换MoveController对象处理,以及定义相关action动作,传递给CCActionManeger动作管理器,另外还有把判断游戏结束的函数逻辑抽出放到Judge类,此处略过这部分代码。

游戏视频(最终效果与之前类似)
注:视频中的背景需要下载相关资源包,对该游戏没有影响。
游戏视频链接

牧师与魔鬼过河小游戏(动作分离版)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值