给Content添加两个组件来控制滑动列表。
首先给在MainCityWnd界面中添加打开TaskWnd界面的方法,然后在BaseData中添加数据配置的类型,这里有两个,一个是基本的类型,另外一个是任务完成度的类型。
public class TaskRewardCfg:BaseData
{
public string taskName;
public int count;
public int exp;
public int coin;
}
public class TaskRewardData:BaseData
{
public int prgs;
public bool taked;
}
首先在服务器端配置任务奖励,主要在CfgSvc中进行,从xml读取任务奖励数据
public class TaskRewardCfg : BaseData
{
public int count;
public int exp;
public int coin;
}
public class TaskRewardData : BaseData
{
public int prgs;
public bool taked;
}
private Dictionary taskRewardDic = new Dictionary();
private void InitTaskRewardCfg()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"D:\u3dworkspace\DarkGod_第五章\Client\Assets\Resources\ResCfgs\taskreward.xml");
XmlNodeList nodLst = doc.SelectSingleNode("root").ChildNodes;
for (int i = 0; i < nodLst.Count; i++)
{
XmlElement ele = nodLst[i] as XmlElement;
if (ele.GetAttributeNode("ID") == null)
{
continue;
}
int ID = Convert.ToInt32(ele.GetAttributeNode("ID").InnerText);
TaskRewardCfg trc = new TaskRewardCfg
{
ID = ID
};
foreach (XmlElement e in nodLst[i].ChildNodes)
{
switch (e.Name)
{
case "count":
trc.count = int.Parse(e.InnerText);
break;
case "exp":
trc.exp = int.Parse(e.InnerText);
break;
case "coin":
trc.coin = int.Parse(e.InnerText);
break;
}
}
taskRewardDic.Add(ID, trc);
}
PECommon.Log("TaskRewardCfg Init Done.");
}
public TaskRewardCfg GetTaskRewardData(int id)
{
TaskRewardCfg agc = null;
if (taskRewardDic.TryGetValue(id, out agc))
return agc;
return null;
}
给玩家数据添加一个任务数组,用来表示任务的完成情况
public string[] taskArr;
在数据库中进行添加和进行初始化化
#region Task Arr
//任务完成情况 任务编号|完成情况|是否接任务
//1|0|0#2|0|0#4|0|0#
string[] taskStrArr = reader.GetString("task").Split('#');
playerData.taskArr = new string[6];
for(int i = 0;i=5)
{
playerData.taskArr[i] = taskStrArr[i];
}
else
{
throw new Exception("DataError");
}
}
#endregion
在服务器端DBMgr处理好taskAR的添加和查询,然后在数据库的表中添加task一栏。
新建一个TaskSys,用来处理服务器端Task的一些操作。
class TaskSys
{
private static TaskSys instance = null;
public static TaskSys Instance
{
get
{
if (instance == null)
{
instance = new TaskSys();
}
return instance;
}
}
private CacheSvc cacheSvc = null;
public void Init()
{
cacheSvc = CacheSvc.Instance;
PECommon.Log("TaskSys Init Done.");
}
}
在客户端解析任务奖励配置
private Dictionary taskRewardDic = new Dictionary();
private void InitTaskRewardCfg(string path)
{
TextAsset xml = Resources.Load(path);
if (!xml)
{
PECommon.Log("xml file:" + path + " not exist", LogType.Error);
}
else
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml.text);
XmlNodeList nodLst = doc.SelectSingleNode("root").ChildNodes;
for (int i = 0; i < nodLst.Count; i++)
{
XmlElement ele = nodLst[i] as XmlElement;
if (ele.GetAttributeNode("ID") == null)
{
continue;
}
int ID = Convert.ToInt32(ele.GetAttributeNode("ID").InnerText);
TaskRewardCfg trc = new TaskRewardCfg
{
ID = ID
};
foreach (XmlElement e in nodLst[i].ChildNodes)
{
switch (e.Name)
{
case "taskName":
trc.taskName = e.InnerText;
break;
case "count":
trc.count = int.Parse(e.InnerText);
break;
case "coin":
trc.coin = int.Parse(e.InnerText);
break;
case "exp":
trc.exp = int.Parse(e.InnerText);
break;
}
}
taskRewardDic.Add(ID, trc);
}
}
}
public TaskRewardCfg GetTaskRewardCfg(int id)
{
TaskRewardCfg agc = null;
if (taskRewardDic.TryGetValue(id, out agc))
return agc;
return null;
}
然后完善TaskWnd
using PEProtocol;
using System.Collections.Generic;
using UnityEngine;
public class TaskWnd : WindowRoot
{
private PlayerData pd = null;
private List trdLst = new List();
protected override void InitWnd()
{
base.InitWnd();
pd = GameRoot.Instance.PlayerData;
RefreshUI();
}
private void RefreshUI()
{
trdLst.Clear();
}
}
完善RefreshUI方法,根据xml中的任务配置进行任务显示
private void RefreshUI()
{
trdLst.Clear();
List todoLst = new List();
List doneLst = new List();
//1|0|0
for(int i = 0;i
完善实例化的方法,把任务的详细信息进行显示
//实例化
for(int i =0;i();
float prgVal = trd.prgs * 1.0f / trf.count;
imgPrg.fillAmount = prgVal;
}
继续完善该方法,用来控制任务按钮点击的显示
//代码控制点击事件
Button btnTake = GetTrans(go.transform, "btnTake").GetComponent
下面是其他的方法
private void ClickTakeBtn(string name)
{
Debug.Log("Name:"+name);
//TODO
}
public void ClickCloseBtn()
{
SetWndState(false);
}
首先修改之前的一个BUG,每次创建预制体之前先要删除之前的预制体。
在GameMsg中添加上发送和接收任务奖励消息的类
[Serializable]
public class ReqTaskReward
{
public int rid;
}
[Serializable]
public class RspTaskReward
{
//TODO
}
客户端的点击完成任务按钮后,需要向服务器端发送信息,然后得到金币和经验值的信息
private void ClickTakeBtn(string name)
{
Debug.Log("Name:"+name);
string[] nameArr = name.Split('_');
int index = int.Parse(nameArr[1]);
GameMsg msg = new GameMsg
{
cmd=(int)CMD.ReqTaskReward,
reqTaskReward = new ReqTaskReward
{
rid = trdLst[index].ID
}
};
netSvc.SendMsg(msg);
TaskRewardCfg trc = resSvc.GetTaskRewardCfg(trdLst[index].ID);
int coin = trc.coin;
int exp = trc.exp;
GameRoot.AddTips(Constants.Color("获得奖励:", TxtColor.Blue) + Constants.Color(" 金币 +" + coin + " 经验 " + exp, TxtColor.Green));
}
服务器端对拿到的信息进行处理,首先需要拿到任务详情和任务完成情况
public void ReqTaskReward(MsgPack pack)
{
ReqTaskReward data = pack.msg.reqTaskReward;
GameMsg msg = new GameMsg
{
cmd = (int)CMD.RspTaskReward
};
PlayerData pd = cacheSvc.GetPlayerDataBySession(pack.session);
TaskRewardCfg trc = cfgSvc.GetTaskRewardCfg(data.rid);
TaskRewardData trd = CalcTaskRewardData(pd, data.rid);
}
public TaskRewardData CalcTaskRewardData(PlayerData pd,int rid)
{
TaskRewardData trd = null;
for(int i=0;i
完成任务后,在服务器端对数据进行添加后发送给客户端
if(trd.prgs == trc.count&&trd.taked == false)
{
pd.coin += trc.coin;
PECommon.CalcExp(pd, trc.exp);
trd.taked = true;
//更新任务进度数据
CalcTaskArr(pd, trd);
if(!cacheSvc.UpdatePlayerData(pd.id,pd))
{
msg.err = (int)ErrorCode.UpdateDBError;
}
else
{
RspTaskReward rspTaskReward = new RspTaskReward
{
coin = pd.coin,
lv=pd.lv,
exp = pd.exp,
taskArr = pd.taskArr
};
msg.rspTaskReward = rspTaskReward;
}
}
else
{
msg.err = (int)ErrorCode.ClientDataError;
}
pack.session.SendMsg(msg);
其中需要有修改字符串数据TaskArr的方法
public void CalcTaskArr(PlayerData pd,TaskRewardData trd)
{
string result = trd.ID + "|" + trd.prgs + (trd.taked ? 1 : 0);
//查找索引号
int index = -1;
for(int i = 0;i
首先需要在引导系统中检测是否是该任务,然后更新进度
public void CalcTaskPrgs(PlayerData pd,int tid)
{
TaskRewardData trd = CalcTaskRewardData(pd, tid);
TaskRewardCfg trc = cfgSvc.GetTaskRewardCfg(tid);
if(trd.prgs < trc.count)
{
trd.prgs += 1;
//更新任务进度
CalcTaskArr(pd, trd);
}
}
新增一个发送进度消息的类
[Serializable]
public class PshPower
{
public int power;
}
TaskSys中的计算进度函数在计算完成后需要发送消息到客户端
public void CalcTaskPrgs(PlayerData pd,int tid)
{
TaskRewardData trd = CalcTaskRewardData(pd, tid);
TaskRewardCfg trc = cfgSvc.GetTaskRewardCfg(tid);
if(trd.prgs < trc.count)
{
trd.prgs += 1;
//更新任务进度
CalcTaskArr(pd, trd);
ServerSession session = cacheSvc.GetOnlineServersession(pd.id);
if(session!=null)
{
session.SendMsg(new GameMsg
{
cmd = (int)CMD.PshTaskPrgs,
pshTaskPrgs = new PshTaskPrgs
{
taskArr = pd.taskArr
}
});
}
}
}
在服务器端合适的地方调用这些函数,任务点
在客户端添加接收任务奖励消息的方法
public void RspTaskReward(GameMsg msg)
{
RspTaskReward data = msg.rspTaskReward;
GameRoot.Instance.SetPlayerDataByTask(data);
taskWnd.RefreshUI();
maincityWnd.RefreshUI();
}
public void PshTaskPrgs(GameMsg msg)
{
PshTaskPrgs data = msg.pshTaskPrgs;
GameRoot.Instance.SetPlayerDataByTaskPrgs(data);
}
我们强化升级一次,可以看到下面的情况
创建新的系统副本系统FubenSys来管理FubenWnd
using UnityEngine;
public class FubenWnd : WindowRoot
{
protected override void InitWnd()
{
base.InitWnd();
}
public void ClickCloseBtn()
{
audioSvc.PlayUIAudio(Constants.UIClickBtn);
SetWndState(false);
}
}
using UnityEngine;
public class FubenSys : SystemRoot
{
public static FubenSys Instance = null;
public FubenWnd fubenWnd;
public override void InitSys()
{
base.InitSys();
Instance = this;
PECommon.Log("Init FubenSys...");
}
public void EnterFuben()
{
OpenFubenWnd();
}
#region Fuben Wnd
public void OpenFubenWnd()
{
fubenWnd.SetWndState();
}
#endregion
}
在主城引导系统中添加任务对接
在打开其他页面的同时,最后暂停导航
数据库中添加副本一栏,用来表示已经处于的副本数
本节根据上面的fuben来显示关卡
public Button[] fbBtnArr;
private PlayerData pd;
public Transform pointerTrans;
public void RefreshUI()
{
int fbid = pd.fuben;
for(int i = 0;i
我们将数据库中的fuben设置为1002,运行可以看到下面的结果