Task - 丰富你的任务库

在战术包中创建任务库

你可以在你的战术包中创建任务库。假设你的战术包名称叫做my_tactic_2024

# in Rocos root directory
mkdir -p Core/my_tactic_2024
cd Core/my_tactic_2024
cp ../tactic/task.lua.template task.lua

打开战术包目录下的task.lua文件,你可以看到如下内容:

module(..., package.seeall)
-- write your own task functions, and use it with `task.xxx()` in our own play

编写任务函数 - 以后卫为例

在比赛中,经常会用到后卫角色,我们可以在刚刚创建的task.lua中添加如下代码:

 1module(..., package.seeall)
 2
 3-- write your own task functions, and use it with `task.xxx()` in our own play
 4
 5local inter2penalty = function(line)
 6    debugEngine:gui_debug_line(line:point1(), line:point2(),4)
 7    -- 定义禁区相关的坐标值
 8    local penaltyX = -(param.pitchLength / 2 - param.penaltyDepth - param.playerRadius)
 9    local penaltyBottom = -param.pitchLength / 2
10    local penaltyY = param.penaltyWidth / 2 + param.playerRadius
11    -- 定义禁区相关的点
12    local penaltyCorner1 = CGeoPoint(penaltyX, penaltyY)
13    local penaltyCorner2 = CGeoPoint(penaltyX, -penaltyY)
14    local penaltyBottomCorner1 = CGeoPoint(penaltyBottom, penaltyY)
15    local penaltyBottomCorner2 = CGeoPoint(penaltyBottom, -penaltyY)
16    -- 定义禁区的边
17    local penaltyLines = {
18        CGeoSegment(penaltyBottomCorner1, penaltyCorner1),
19        CGeoSegment(penaltyCorner1, penaltyCorner2),
20        CGeoSegment(penaltyCorner2, penaltyBottomCorner2),
21    }
22    -- 绘制debug信息
23    for _, penaltyLine in ipairs(penaltyLines) do
24        debugEngine:gui_debug_line(penaltyLine:point1(), penaltyLine:point2(), 4)
25    end
26    -- 判断交点
27    for _, penaltyLine in ipairs(penaltyLines) do
28        local inter = CGeoLineLineIntersection(line,penaltyLine)
29        local pos = inter:IntersectPoint()
30        if penaltyLine:IsPointOnLineOnSegment(pos) then
31            debugEngine:gui_debug_line(penaltyLine:point1(), penaltyLine:point2(), 4)
32            return CGeoPoint(pos:x(),pos:y())
33        end
34    end
35    return nil
36end
37
38function leftBack()
39    local penaltyLeft = CGeoPoint(-param.pitchLength / 2, param.goalWidth/2)
40    local ipos = function()
41        return inter2penalty(CGeoLine(ball.pos(),penaltyLeft)) or penaltyLeft
42    end
43	local mexe, mpos = GoCmuRush{pos = ipos, dir = dir.playerToBall, vel = CVector(0,0)}
44	return {mexe, mpos}
45end
46
47function rightBack()
48    local penaltyRight = CGeoPoint(-param.pitchLength / 2, -param.goalWidth/2)
49    local ipos = function()
50        return inter2penalty(CGeoLine(ball.pos(),penaltyRight)) or penaltyRight
51    end
52    local mexe, mpos = GoCmuRush{pos = ipos, dir = dir.playerToBall, vel = CVector(0,0)}
53	return {mexe, mpos}
54end

在上述代码中,我们先定义了一个局部函数inter2penalty用于计算一条线与己方禁区的交点,然后定义了两个任务函数leftBack和rightBack,分别用于控制左后卫和右后卫。在任务函数中,我们使用了GoCmuRush函数并调用inter2penalty函数计算传入参数。虽然这样的实现方式有一些简略,且从性能的角度,inter2penalty函数这样的通用功能更适合放在c++端,但这不妨碍我们来展现利用已有的较为通用的Skill进一步封装成任务函数这一过程。书写一个状态调用两任务函数,可以呈现如下效果: