Play - 框架:解析task

本节目标:了解task的执行流程

在上一节,我们简要分析了SelectPlay.lua的代码来理解Play的运行流程。在这一节,我们将继续深入,分析task的解析。 我们之前简化了RunPlay中的代码,现在让我们再深入一些:

 1function RunPlay(name)
 2    ...
 3    DoRolePosMatch(curPlay)
 4    ...
 5    for rolename, task in pairs(curPlay[gCurrentState]) do
 6        -- 排除非task的情况(例如switch函数,match匹配规则)
 7        if rolename ~= "switch" and rolename ~= "match" then
 8            -- 如果存在闭包,对task进行解包
 9            if type(task) == "function" then
10                task = task(gRoleNum[rolename])
11            end
12            -- 解析当前执行的机器人号码
13            local roleNum = gRoleNum[rolename]
14            -- 执行task对应的cskill
15            if roleNum ~= -1 then
16                -- 执行除运动以外的task参数
17                if task[3] ~= nil then
18                    -- 包括踢球模式、目标朝向、踢球精度、踢球力度、以及特殊flag配置
19                    local mkick = task[3](roleNum)
20                    local mdir = task[4](roleNum)
21                    local mpre = task[5](roleNum)
22                    local mkp  = task[6](roleNum)
23                    local mcp  = task[7](roleNum)
24                    local mflag = task[8]
25
26                    ... -- 判断并配置是否吸球
27                    ... -- 判断并配置是否踢球
28
29                end
30            end
31
32            -- 从lua端调用到c++-skill层
33            task[1](roleNum)
34        end
35    end
36end
1function goSimplePos(p, d, f)
2    ...
3    local mexe, mpos = SimpleGoto{pos = p, dir = idir, flag = iflag}
4    return {mexe, mpos}
5end
1...
2{
3    switch = ...,
4    Leader = task.goSimplePos(CGeoPoint(0,0)),
5    -- 结合task.lua,上述代码等效于Leader = {mexe, mpos}
6    match = "(L)"
7},
8...
function SimpleGoto(task)
    ...
    execute = function(runner)
        mpos = _c(task.pos,runner)
        mdir = _c(task.dir,runner)

        task_param = TaskT:new_local()
        ...
        return skillapi:run("Goto", task_param)
    end

    matchPos = function()
        return _c(task.pos)
    end

    return execute, matchPos
end

我们观察task.lua中的goSimplePos函数,这个函数返回一个table,包含了两个元素,mexempos。在TestScript.lua中,我们调用了goSimplePos函数,返回的table被赋值给了Leader,这个table中的两个元素被分别赋值给了mexempos。在RunPlay函数中,我们通过task[1](roleNum)调用了mexe,这个函数会返回一个execute函数,这个函数会在RunPlay中被调用,执行SimpleGoto中的execute函数。在execute函数中,我们调用了skillapi:run函数,这个函数会调用c++层的Goto技能。

除此之外,SimpleGoto.lua中的matchPos函数即task[2]会返回一个目标点,这个目标点会在RunPlayDoRolePosMatch中被调用,用于动态匹配。

你可以看到,从上述的Play.lua的第17行开始,有关于task列表参数的第3-第8项,这些项是用于配置踢球模式、目标朝向、踢球精度、踢球力度、以及特殊flag配置。所以你可以在task.lua中的某个函数返回8个参数,这样做的好处是可以直接将非运动的简单指令交给lua层处理实现与运动本身的解耦,在c++层只需要负责移动即可,这可以在类似于动态射门的skill中实现更出色的效果。