结合目前的塔防项目,介绍一下游戏开发中的 任务系统
先简单介绍下要讲的任务系统,因为游戏内容不多,所以目前的任务都比较简单,与其说是任务系统,不如叫成就系统.但是就算复杂的MMORPG游戏的任务系统,也可以按照此思路来做.
这次我只实现了两大类任务(成就任务、每日任务)
先看下任务系统的配置表
任务ID | 描述 | 父类型 | 子类型 | 目标值 | 前置任务 | 奖励ID | 奖励数量 |
ID | Txt | P_Type | S_Type | Value | Pre_ID | 1 | 1001 |
1 | 今日获得金币50000 | P2 | S6 | 50000 | 0 | 1 | 1002 |
2 | 今日通关5关关卡 | P2 | S4 | 5 | 0 | 1 | 1003 |
3 | 今日杀怪达到100 | P2 | S5 | 100 | 0 | 1 | 1004 |
101 | 累积金币达到10000 | P1 | S1 | 10000 | 0 | 1 | 1005 |
102 | 累积金币达到50000 | P1 | S1 | 50000 | 101 | 1 | 1006 |
103 | 累积金币达到100000 | P1 | S1 | 100000 | 102 | 1 | 1007 |
201 | 通关关卡10 | P1 | S2 | 10 | 0 | 1 | 1008 |
202 | 通关关卡20 | P1 | S2 | 20 | 201 | 1 | 1009 |
203 | 通关关卡40 | P1 | S2 | 40 | 202 | 1 | 1010 |
301 | 累积杀怪达到100 | P1 | S3 | 100 | 0 | 1 | 1011 |
302 | 累积杀怪达到200 | P1 | S3 | 200 | 301 | 1 | 1012 |
303 | 累积杀怪达到500 | P1 | S3 | 500 | 302 | 1 | 1013 |
任务ID:唯一id
文本:显示的任务描述
父类型:1.数值 2.每日任务
子类型:(1.累积金币 2.关卡 3.累积杀怪 4.今日通关 5.今日杀怪 6.今日获得金币)
目标值:任务需达到的数量
前置任务:前置任务(根据前置任务是否完成 决定是否显示任务)
奖励ID:奖励道具的id (目前我只有一种游戏货币)
奖励数量:奖励道具的数量
上代码→
--定义枚举类型:
--子类型 (1.累积金币 2.关卡 3.累积杀怪 4.今日通关 5.今日杀怪 6.今日获得金币)
TaskSType = {
S1 = "Total_Money",
S2 = "Level",
S3 = "Total_Monster",
S4 = "Daily_Level",
S5 = "Daily_Monster",
S6 = "Daily_Money",
}
--任务管理类
local TaskModel = class("TaskModel", XXModel)
function TaskModel:init()
self.doneTaskList = {} --已经完成并领取的任务列表
self.taskList = {} --任务列表
self.totalMoney = 0 --累计获得金币
self.totalMonster = 0 --累计杀怪
self.dailyLevel = 0; --今日通过关卡
self.dailymonster= 0; --今日杀怪
self.dailymoney = 0; --今日获得金币
--初始化任务数值 key:子类型
self.taskCountList = {}
for _,v in pairs(TaskSType) do
self.taskCountList[v] = 0
end
self:resetTaskList()
end
--初始化显示任务列表
function TaskModel:resetTaskList()
self.taskList = {}
for k,v in pairs(XXIO.allData["task"]) do
if self.doneTaskList[v.ID] == nil then --未领取
if v.Pre_ID == "0" then --初始任务
self.taskList[v.ID] = v.ID
else
if self.doneTaskList[v.Pre_ID] ~= nil then --前置任务已完成
self.taskList[v.ID] = v.ID
end
end
end
end
end
--任务完成
function TaskModel:doneTask(tid)
self.doneTaskList[tid] = tid
self:resetTaskList()
self:update()
end
--所需要维护的数据结构,对应到表中每个子类型
function TaskModel:resetTaskValue()
local userModel = XXMVCManager:getModel("User")
self.taskCountList[TaskSType.S1] = self.totalMoney
self.taskCountList[TaskSType.S2] = userModel.level
self.taskCountList[TaskSType.S3] = self.totalMonster
self.taskCountList[TaskSType.S4] = self.dailyLevel
self.taskCountList[TaskSType.S5] = self.dailymonster
self.taskCountList[TaskSType.S6] = self.dailymoney
self:update()
end
--判断列表中是否有已经完成的任务
function TaskModel:hasDoneTask()
for _,v in pairs(self.taskList) do
local info = XXIO.allData["task"][v] --配置表
local curValue = self.taskCountList[TaskSType[info.S_Type]]
if tonumber(curValue) >= tonumber(info.Value) then
return true
end
end
return true
end
function TaskModel:appendLevel() --数值改变
self.dailyLevel = self.dailyLevel + 1
self:resetTaskValue()
end
function TaskModel:appendMonster(money) --数值改变
self.totalMoney = self.totalMoney + money
self.totalMonster = self.totalMonster + 1
self.dailymoney = self.dailymoney + money
self.dailymonster = self.dailymonster + 1
self:resetTaskValue()
end
return TaskModel
1.枚举值我使用的字符串,这点的好处就是可以一份代码终身试用.拿来当key,不要太香哦
2. resetTaskList()
根据完成列表doneTaskList的内容,序列化出来需要显示的任务
3. doneTask()
完成任务调用,完成的任务添加到完成列表doneTaskList,然后调用 resetTaskList
4. resetTaskValue() ※※※※※※※
这个方法里面主要做的是整个任务系统在外部唯一要维护的列表,就是你各类任务所对应的数值
我这里有6种类型的数据,只要维护好这个数值,那其他的地方不管你任务多少,都不需要在进行修改了
5. hasDoneTask()
看是否有已经完成了的任务,用于主界面任务按钮上面的红点显示
6.appendLevel appendMonster
这些方法都是为了维护那个数据列表的
基本就是这些,这个思路可以用于绝大多数任务系统,无非就是做一些修改
比如大型RPG中的:
- 击杀某个怪物
- 移动到某个点
- 采摘某个道具
- 跟某个npc对话
- 进入某个副本
- 等等等等...