简单任务系统

代码已上传至:https://github.com/pinzeweifen/demo/tree/master/Unity/Frame

作为一个Unity 的用户,接触这编辑器已经很久了,写的代码一般都是拖拖拖。

也萌生过写个架构,但是都失败了。至于原因可能是我知识量不足?

作为只萌新,今日来写写任务系统。

首先我想知道的是任务到底有哪些类型,然后我找到了这边文章,我觉得他归类得很好,所以直接用他的了

https://necromanov.wordpress.com/2010/11/23/quest_design_2/

先把底层写了,我应该有一个抽象的任务类,它将会记录任务的状态

    public abstract partial class Task
    {
        public enum State
        {
            /// <summary>
            /// 不可接取
            /// </summary>
            CannotAccept,

            /// <summary>
            /// 可接取
            /// </summary>
            CanAccept,

            /// <summary>
            /// 任务进行中
            /// </summary>
            DoTasking,

            /// <summary>
            /// 完成未领奖
            /// </summary>
            CompleteTask,

            /// <summary>
            /// 完成已领取奖励
            /// </summary>
            FinishTask
        }
    }

在我的设计中,所有任务都会在游戏开始的时候就创建完毕,将会有一个管理类来管理到底哪个任务接受哪个任务完成和放弃。所以我用了一个词典来保存所有的任务。

    /// <summary>
    /// 任务管理
    /// </summary>
    public class TaskManager
    {
        private Dictionary<int, Task> dic = new Dictionary<int, Task>();

        public Task this[int key]
        {
            get { return dic[key]; }
        }

        public bool Add(Task task)
        {
            if (dic.ContainsKey(task.GetID))
                return true;

            dic[task.GetID] = task;
            return false;
        }

        public void Remove(int task)
        {
            if (dic.ContainsKey(task))
                dic.Remove(task);
        }
    }

任务管理器全局当然只会有一个,你可以添加单例模式。如果添加的任务ID 重复了就返回 true。如果要在返回true后执行代码,只需要这样

            TaskManager taskManager = new TaskManager();

            if (taskManager.Add(new StrikeKillTask(0,new Award(),
                new EqOperation(1,1),new EqOperation(1,1),new EqOperation(1,1))))
            {

            }

假设返回检测的是 false ,你将会多执行一次取反操作。

我应该可以查询到某个任务是否可接

        public bool IsAccept()
        {
            return acceptOperation.IsTrue();
        }

由于我想使用类代替运算符操作方便数据转换为对应代码。所以封装了四个运算符

    /// <summary>
    /// 运算符运算
    /// </summary>
    public abstract class OperatorOperation
    {
        protected object obj, obj2;
        public OperatorOperation(object o)
        {
            obj = o;
        }
        public OperatorOperation(object o,object o2)
        {
            obj = o;
            obj2 = o2;
        }
        public abstract bool IsTrue();
        public abstract bool IsTrue(object obj);
    }

    /// <summary>
    /// 相等
    /// </summary>
    public class EqOperation : OperatorOperation
    {
        public EqOperation(object o) : base(o) { }
        public EqOperation(object o,object o2) : base(o,o2) { }

        public override bool IsTrue()
        {
            return obj.Equals(obj2);
        }

        public override bool IsTrue(object obj)
        {
            return this.obj.Equals(obj);
        }
    }

    /// <summary>
    /// 不相等
    /// </summary>
    public class NotEqOperation : OperatorOperation
    {

        public NotEqOperation(object o) : base(o) { }
        public NotEqOperation(object o, object o2) : base(o, o2) { }

        public override bool IsTrue()
        {
            return !obj.Equals(obj2);
        }

        public override bool IsTrue(object obj)
        {
            return !this.obj.Equals(obj);
        }
    }

    /// <summary>
    /// 并且
    /// </summary>
    public class AndOperation : OperatorOperation
    {
        public AndOperation(OperatorOperation o) : base(o) { }
        public AndOperation(OperatorOperation o, OperatorOperation o2) : base(o, o2) { }

        public override bool IsTrue()
        {
            return (obj as OperatorOperation).IsTrue() && (obj2 as OperatorOperation).IsTrue();
        }

        public override bool IsTrue(object obj)
        {
            if (obj is OperatorOperation)
                return (this.obj as OperatorOperation).IsTrue() && (obj as OperatorOperation).IsTrue();
            return false;
        }
    }

    /// <summary>
    /// 或
    /// </summary>
    public class OrOperation : OperatorOperation
    {
        public OrOperation(OperatorOperation o) : base(o) { }
        public OrOperation(OperatorOperation o, OperatorOperation o2) : base(o, o2) { }

        public override bool IsTrue()
        {
            return (obj as OperatorOperation).IsTrue() || (obj2 as OperatorOperation).IsTrue();
        }

        public override bool IsTrue(object obj)
        {
            if (obj is OperatorOperation)
                return (this.obj as OperatorOperation).IsTrue() || (obj as OperatorOperation).IsTrue();
            return false;

        }
    }

不相等就只是取反而已,它使用起来就像下面这样

            if(new EqOperation(
                1,new NotEqOperation(
                    2,new OrOperation(
                        new EqOperation(3,4), new EqOperation(5, 6)))).IsTrue())
            {
                //code
            }

调用管理器接受任务之后,将会调用 TaskStart

        /// <summary>
        /// 接受任务
        /// </summary>
        /// <param name="task"></param>
        public bool Accept(int task)
        {
            if (dic.ContainsKey(task))
               return dic[task].Start();
            return false;
        }

它首先检查的是否可接受任务,如果可以就改变为正在进行任务的状态,并且通知开始任务,为啥要通知呢,毕竟我不可能在这里写上调用UI 的代码(#^.^#)

        public bool Start()
        {
            if (state == State.CanAccept)
                return true;
            
            OnStart();
            state = State.DoTasking;

            if (GameEvents.OnTaskStart != null)
                GameEvents.OnTaskStart(id);

            return false;
        }

如果任务已经完成那么就需要提交任务

        /// <summary>
        /// 完成任务
        /// </summary>
        /// <param name="task"></param>
        public bool Submit(int task)
        {
            if (dic.ContainsKey(task))
                return dic[task].Submit();
            return false;
        }

检查完状态后,判断是否可以领取奖励,领取完成更改状态并通知任务结束

        public bool Submit()
        {
            if(state != State.CompleteTask)
                return true;

            if (OnSubmit())
            {
                ward.Provide();
                state = State.FinishTask;

                if (GameEvents.OnTaskEnd != null)
                    GameEvents.OnTaskEnd(id);
            }
            
            return false;
        }

还有放弃任务,没什么好说了,自己领会

        public bool Renounce()
        {
            if (state != State.DoTasking)
                return true;
            
            OnRenounce();
            state = State.CanAccept;

            if (GameEvents.OnTaskRenounce != null)
                GameEvents.OnTaskRenounce(id);
            return false;
        }

当然啦还有就是任务更新

        protected void Update()
        {
            if (OnUpdate())
            {
                if (GameEvents.OnTaskUpdate != null)
                    GameEvents.OnTaskUpdate(id);
            }
        }

至此抽象的任务类就完成了?,不!你可以添加一些字段令子类不那么苦逼

实现一个具体的任务类型,击杀任务类型

击杀嘛当然是杀死某单位的时候更新任务状态,在开始任务的时候监听死亡事件

    /// <summary>
    /// 击杀任务
    /// </summary>
    public class StrikeKillTask : Task
    {
        private int count;
        private int maxCount;

        public StrikeKillTask(int id, Award ward, OperatorOperation accept, OperatorOperation update, OperatorOperation complete, State state = State.CannotAccept) : base(id, ward, accept, update, complete, state)
        {
        }

        protected override void OnStart()
        {
            count = 0;
            GameEvents.OnDeath += OnDeath;
        }

在更新前判断一下条件是否为真

        private void OnDeath(Unit unit)
        {
            //是否可以更新
            if (updateOperation.IsTrue(unit))
            {
                Update();
            }
        }

更新一下杀怪的数量,如果已经杀够就改变状态

        protected override bool OnUpdate()
        {
            if (count < maxCount)
            {
                count++;
                if(count == maxCount)
                {
                    state = State.CompleteTask;
                }
                return true;
            }
            return false;
        }

在领取奖励或放弃任务时,删除事件监听

        protected override bool OnSubmit()
        {
            //是否可以获得物品
            if (completeOperation.IsTrue(count))
            {
                GameEvents.OnDeath -= OnDeath;
                return true;
            }
            return false;
        }

        protected override void OnRenounce()
        {
            GameEvents.OnDeath -= OnDeath;
        }

当然这个类其实还没写完,需要你自己补充完整。其他类型任务应该很好写,就讲到这里啦

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼游戏开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值