原文链接:http://blog.csdn.net/lyh916/article/details/45767357
1.任务管理类与任务类是一对一的关系,而任务管理类与其他类是一对多的关系。对于一对多,比较容易想到的就是观察者模式了。在观察者模式中,是观察者决定要监视的东西,而不是事件的发生者决定谁观察它。
2.对于任务类/任务条件类/任务奖励类来说,有逻辑意义上的,也有界面意义上的,因此要分开处理。
这里给出主要的逻辑代码:
- using System.Collections;
- using System.Collections.Generic;
- using System.Xml.Linq;
- using System;
-
- public class Task {
-
- public TaskItem taskItem;
-
- public string taskID;
- public string taskName;
- public string caption;
- public List<TaskCondition> taskConditions = new List<TaskCondition>();
- public List<TaskReward> taskRewards = new List<TaskReward>();
-
-
- 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);
- }
- }
- 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>();
- 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