仿真足球最快截球的设计和实现
在前面的文章中,我们已经将整个平台的流程和基本命令的使用讲解完毕了。在这一篇文章中,我们将要讲解编写自己的球队中最为基础,也是最为重要的一个部分。截球。
什么是截球?
大家自己在踢足球的时候,你的队友给你传一个球过来,大部分的时候你需要跑动才能将球拿到。但是,如果拿到球,这个时候你需要更加球的速度和自己的经验来判断球未来的位置,然后向你判断的那个位置去跑,这样才能拿到球。在这个过程中,你对球未来位置的判断,以及跑向这个位置并最终将球得到,就是我们现在所说的截球。
截球有哪些方式?
截球的方式有很多,基本上可以概括为3类:简单截球,最快截球和战略截球。
简单截球:
咱们可以下载录像来观看实际的运行效果(该录像文件需要在平台中打开)。
简单截球的实现原理很简单:
判断自己的身体朝向是否朝着足球?如果不是,转身朝向足球;如果是,想前奔跑。
实现代码如下:
/// <summary>
/// 简单截球的实现
/// </summary>
/// <param name="agent">要去截球的机器人</param>
/// <param name="ball">足球</param>
/// <returns>截球的命令</returns>
public static Command Dash2Ball(Agent agent, Ball ball)
{
Vector2f tempPos = ball.Pos - agent.Pos;
Command command = new Command();
if (Math.Abs(tempPos.GetDirection() - agent.Dir) < 10)
{
command.CType = CommandType.Dash;
command.Parameter1 = RuleSettings.Instance.MaxDashVel;
}
else
{
command.CType = CommandType.Turn;
command.Parameter1 = tempPos.GetDirection();
}
return command;
}
简单截球的示意图如下:
大家可以看出,因为没有对足球未来的位置进行判断,所以说在实际的截球过程中,会走不少弯路。
最快截球:
咱们可以下载录像观看实际的运行效果(该录像文件需要在平台中打开)。
最快截球的示意图如下:
大家可以看出,因为对足球未来的位置进行了判断,所以说在实际的截球过程中不会走弯路。
战略截球:
战略截球会对可以足球的未来位置进一步判断,从多个可以截球的位置中,选择出最适合自己的位置去截球(可能是最快的,也可能不是)。
这个属于更加高级的话题了,不属于我们这篇文章讨论的范围。
最快截球的设计原理
大家一定听说过“狼追兔子”的问题。
啥?你没有听说过?问题描述是这样的“狼在兔子南边100米,看见兔子马上追。狼速10米每秒,兔子7米每秒。兔子往东跑,狼向着兔子跑,多久追到?”
简单吧。不过这可是一道小学生的数学奥赛题哦,对小学生来说还是有一定难度的。
我们的球员就是“狼”,足球就是“兔子”,其它的情景都是一样的。
我们用了一种非常简单,但是很直观实现:
计算出足球运动X周期后的位置,判断我方的截球球员是否能在X周期内到达该位置。
如果可以,则X周期就是最快截球需要的周期,同时足球在X周期后的位置就是我们的截球的位置。
如果不可以,则让X+1,在回到最开始的判断。
实际的伪代码如下:
/// <summary>
/// 计算某一个球员的最快截球位置
/// </summary>
/// <param name="ball">需要截的球</param>
/// <param name="agent">需要去截球的队员</param>
/// <returns>最快截球位置</returns>
public Vector2f PredictFastestInterceptBallPos(Ball ball, Agent agent)
{
int cycle = 0;
Vector2f pos = ball.Pos;
//判断球员能否在cycle周期内到达pos这个位置
while (predictCycle2Pos(agent, pos) > cycle)
{
cycle++;
//计算cycle周期后,足球的位置
pos = predictBallPos(cycle);
}
return pos;
}
最快截球的实现
我们给的代码中,多加了一个功能,判断场上谁可以最快截球(相当于将场上所有球队的最快截球周期数都求解出来,然后去最快的那个)。
大家可以通过下载最快截球c#球队代码来了解具体的实现。
在下一篇文章中,我们将向大家介绍基于最快截球的其它策略部分的编写:传球,射门,进攻跑位和防守跑位。