您的位置:首页 > 移动开发 > Unity3D

[Unity实战]一个简单的任务系统(一)

2016-07-01 10:33 447 查看
原文链接:http://blog.csdn.net/lyh916/article/details/45767357

1.任务管理类与任务类是一对一的关系,而任务管理类与其他类是一对多的关系。对于一对多,比较容易想到的就是观察者模式了。在观察者模式中,是观察者决定要监视的东西,而不是事件的发生者决定谁观察它。

2.对于任务类/任务条件类/任务奖励类来说,有逻辑意义上的,也有界面意义上的,因此要分开处理。

这里给出主要的逻辑代码:

[csharp] view
plain copy

using System.Collections;  

using System.Collections.Generic;  

using System.Xml.Linq;  

using System;  

  

public class Task {  

  

    public TaskItem taskItem;//对应的UI面板  

  

    public string taskID;//任务ID  

    public string taskName;//任务名字  

    public string caption;//任务描述     

    public List<TaskCondition> taskConditions = new List<TaskCondition>();  

    public List<TaskReward> taskRewards = new List<TaskReward>();  

  

    //根据taskNum读取xml,实现初始化  

    public Task(string taskID)  

    {  

        this.taskID = taskID;  

        XElement xe = TaskManager.Instance.rootElement.Element(taskID);  

        taskName = xe.Element("taskName").Value;  

        caption = xe.Element("caption").Value;  

  

        IEnumerable<XElement> a = xe.Elements("conditionID");  

        IEnumerator<XElement> b = xe.Elements("conditionTargetAmount").GetEnumerator();  

  

        IEnumerable<XElement> c = xe.Elements("rewardID");  

        IEnumerator<XElement> d = xe.Elements("rewardAmount").GetEnumerator();  

  

        foreach (var s in a)  

        {  

            b.MoveNext();  

            TaskCondition tc = new TaskCondition(s.Value, 0, int.Parse(b.Current.Value));  

            taskConditions.Add(tc);  

        }  

  

        foreach (var s in c)  

        {  

            d.MoveNext();  

            TaskReward tr = new TaskReward(s.Value, int.Parse(d.Current.Value));  

            taskRewards.Add(tr);  

        }  

    }  

  

    //判断条件是否满足  

    public void Check(TaskEventArgs e)  

    {  

        TaskCondition tc;  

        for (int i = 0; i < taskConditions.Count; i++)  

        {  

            tc = taskConditions[i];  

            if (tc.id == e.id)  

            {  

                tc.nowAmount += e.amount;  

                if(tc.nowAmount < 0) tc.nowAmount = 0;  

                if (tc.nowAmount >= tc.targetAmount)  

                    tc.isFinish = true;  

                else  

                    tc.isFinish = false;  

  

                taskItem.Modify(e.id,tc.nowAmount);  

            }  

        }  

  

        for (int i = 0; i < taskConditions.Count; i++)  

        {  

            if (!taskConditions[i].isFinish)  

            {  

                taskItem.Finish(false);  

                return;  

            }  

        }  

        taskItem.Finish(true);  

        e.taskID = taskID;  

        TaskManager.Instance.FinishTask(e);  

    }  

  

    //获取奖励  

    public void Reward()  

    {  

        TaskEventArgs e = new TaskEventArgs();  

        e.taskID = taskID;  

        TaskManager.Instance.GetReward(e);  

    }  

  

    //取消任务  

    public void Cancel()  

    {  

        TaskEventArgs e = new TaskEventArgs();  

        e.taskID = taskID;  

        TaskManager.Instance.CancelTask(e);  

    }  

}  

[csharp] view
plain copy

using UnityEngine;  

using System.Collections;  

using System.Collections.Generic;  

using System.Xml.Linq;  

using System;  

  

public class TaskManager : MonoSingletion<TaskManager> {  

  

    public Dictionary<string, Task> dictionary = new Dictionary<string,Task>();//id,task  

    public XElement rootElement;  

  

    public event EventHandler<TaskEventArgs> getEvent;//接受任务时,更新任务到任务面板等操作  

    public event EventHandler<TaskEventArgs> finishEvent;//完成任务时,提示完成任务等操作  

    public event EventHandler<TaskEventArgs> rewardEvent;//得到奖励时,显示获取的物品等操作  

    public event EventHandler<TaskEventArgs> cancelEvent;//取消任务时,显示提示信息等操作  

  

    void Start()  

    {  

        MesManager.Instance.checkEvent += CheckTask;  

        rootElement = XElement.Load(Application.dataPath + "/TestTask/Task.xml");//得到根元素  

    }  

  

    public void GetTask(string taskID)  

    {  

        if (!dictionary.ContainsKey(taskID))  

        {  

            Task t = new Task(taskID);  

            dictionary.Add(taskID, t);  

  

            TaskEventArgs e = new TaskEventArgs();  

            e.taskID = taskID;  

            getEvent(this, e);  

        }  

    }  

  

    public void CheckTask(System.Object sender, TaskEventArgs e)  

    {  

        foreach (KeyValuePair<string, Task> kv in dictionary)  

        {  

            kv.Value.Check(e);  

        }  

    }  

  

    public void FinishTask(TaskEventArgs e)  

    {  

        finishEvent(this, e);  

    }  

  

    public void GetReward(TaskEventArgs e)  

    {  

        if (dictionary.ContainsKey(e.taskID))  

        {  

            Task t = dictionary[e.taskID];  

            for (int i = 0; i < t.taskRewards.Count; i++)  

            {  

                TaskEventArgs a = new TaskEventArgs();  

                a.id = t.taskRewards[i].id;  

                a.amount = t.taskRewards[i].amount;  

                a.taskID = e.taskID;  

                rewardEvent(this,a);  

            }  

        }  

        dictionary.Remove(e.taskID);  

    }  

  

    public void CancelTask(TaskEventArgs e)  

    {  

        if (dictionary.ContainsKey(e.taskID))  

        {  

            cancelEvent(this,e);  

            dictionary.Remove(e.taskID);  

        }  

    }   

}  

思路(这里以怪物被消灭后为例):

1.怪物消灭后,发送信息到消息中心,消息中心再将消息分发给监听它的东西,例如得分增加,经验上升等等,其中包括发送给我们的TaskManager(如果没有消息中心,那么如果想增加一个观察者观察怪物消灭的信息,就要改动怪物的代码,相反,如果使用消息中心,那么只需要在新增的观察者中注册事件就可以了)

2.TaskManager将信息传递到正在执行的任务Task,Task根据条件判断是否完成任务,如果完成了,则通知TaskManager(两者是一对一的关系)

3.TaskManager将任务完成的消息分发出去

测试:

1.对于收集物品的任务,当收集完成后,再丢弃部分物品。结果:任务不显示完成,领取不了奖励

2.多个任务同时进行。结果:可以领取完成了任务的奖励

3.接受任务后再打开任务面板。结果:显示正常

4.任务中存在相同条件的。结果:正常



不足:

1.对于收集物品的任务,没有对物品起始数量进行初始化

2..等等

总结:

这里可以看到事件委托的强大了吧!

这是unitypackage:
http://yun.baidu.com/s/1gdH7sWF
Ps:导入unity后会发现报错,这时只需添加一个MonoSingletion类即可:http://blog.csdn.net/lyh916/article/details/45898343

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: