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进一步封装成任务函数这一过程。书写一个状态调用两任务函数,可以呈现如下效果: