![](http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg)
在上2篇文章中,我们介绍了博客园仿真足球竞赛平台的基本使用方法和它的基本工作原理。
在这篇文章中,我们将一起来了解如何使用c#球队的球队模板来编写自己的足球队。
在上2篇文章中,我们介绍了博客园仿真足球竞赛平台的基本使用方法和它的基本工作原理。
在这篇文章中,我们将一起来了解如何使用c#球队的球队模板来编写自己的足球队。
推荐文章:
- 如何利用Java球队模板编写自己的足球队
- 博客园仿真足球竞赛平台Python版SDK
订阅本系列文章
我们首先可观看视频,然后再看文章后面的详细介绍。
清晰版下载
使用VS打开c#球队的球队模板,可以看到这个解决方案包含了2个项目
第一个项目是:CnblogsDotNetSDK
这是一个类库项目,这个SDK将负责与比赛平台之间的通信,由Communication和Data这2个名字空间中的类完成。我们在编写球队的时候不需要去考虑他们。
Settings名字空间中包含了比赛平台的基本常量:
FieldSettings:这个类中包含了和比赛场地相关的常量。如场地的长,宽,球门的大小,禁区的大小等等,使用非常简单,比如我要得到球场的长度:
double fieldLength = FieldSettings.Instance.FieldLength;
GameSettings:这个类中包含了和比赛设置相关的常量。如比赛的周期长短,每个周期可以思考的时间等等。比如我要获得比赛的周期数:
int cycleNum = GameSettings.Instance.GameCycle;
RuleSettings:这个类中包含了和比赛规则相关的常量。如球员每一个周期最大的奔跑距离,踢球的速度范围等等。比如我要获得球员每个周期能奔跑的最大距离:
double dashDis = RuleSettings.Instance.MaxDashVel;
ServerSettings:这个类由SDK内部与平台通信使用。
Utility名字空间中包含了和2D几何运算相关的类:
NumeralHelper:提供数字计算方面的帮助类,如其中的SolveABCFormula可以用于求解2元1次方程,GetLengthGeomSeries这一类函数用于求解等比数组方面的问题。
AngleHelper:提供角度方面的辅助计算,所有的角度计算都是以角度计算的。如NormalizeAngle可以将任意一个角度转化为-180,180之间,SinDeg用于计算某个角度的Sin值等等。
以下几个几何类都是Struct结构的,是值类型,而不是引用类型
Vector2f:代表了一个2D坐标区域的坐标点。有X和Y坐标,提供2D坐标中一些相应的计算。如GetLength得到自己到原点的长度,运算符重载等等。这个类型在实际的编写中将会大量地使用。
Rectangle:代表了一个矩形。有左上角坐标和右下角坐标,提供了和矩形相关的一些计算。如判断某个点(Vector2f)是否在矩形内IsInside等等。
Line:代表直线以及相应的计算。直线的表示为方程:ay + bx + c = 0,如GetIntersection可以求2条直线之间的交点等等。
Circle:代表圆的平面几何计算类。圆用圆心和半径来表示,如IsInside判断某个点(Vector2f)是否在圆内,GetIntersectionPoints求解2个圆的交点等等。
第二个项目是:DemoTeamCSharp
这是一个控制台程序,也就是咱们的球队的启动文件,他将包含球队的所有逻辑部分。
Program.cs:这个是咱们程序的主入口。在Main函数中,我们可以设定自己的球队名称和作者名称
![](/Images/OutliningIndicators/ContractedBlock.gif)
设置球队的基本信息
//设置球队的基本信息
string myTeamName = "www.cnblogs.com";
string author = "博客园";
Main函数中的其它的代码将调用SDK与比赛平台通信。
Agent:代表球员。它包含了球员的2个属性,球员的位置(Pos)和球员的身体朝向(Dir)。
Ball:代表足球。它包含了足球的2个属性,足球的位置(Pos)和足球的速度(Vel)。
WorldModel:代表了场上的所有信息,他是一个球员(Agent)和足球(Ball)的集合。包含了5个我方球员(OwnAgents)和5个对方球员(OpsAgents)以及一个足球(Ball)的信息。
MyTeam:这是我们编写球队的主角。他包含了2个非常重要函数
- SetWorldModelFromServer:用于将从服务器中获得的场上信息转化为自己定义的数据结构。这个函数在每个仿真周期中,接收到平台发过来的信息后被调用(参见Program.Main函数),这样就可以把我们需要的信息填充到我们自己定义的数据结构中去了。
- Think:这个函数利用SetWorldModelFromServer得到的场上信息,分析后,返回一个Command[] ,其中包含了我方5名球员的命令。我们所有的逻辑判断都在这个函数中。
球员命令的说明
球员可以执行的命令种类共有5种
![](/Images/OutliningIndicators/ContractedBlock.gif)
命令的种类
/// <summary>
/// 命令的种类
/// </summary>
public enum CommandType
{
/// <summary>
/// 扑球命令
/// </summary>
Catch = 0,
/// <summary>
/// 奔跑命令
/// </summary>
Dash = 1,
/// <summary>
/// 转身命令
/// </summary>
Turn = 2,
/// <summary>
/// 无命令
/// </summary>
Stay = 3,
/// <summary>
/// 踢球命令
/// </summary>
Kick = 4,
/// <summary>
/// 未知命令
/// </summary>
Unknow = 5
}
命令(Command)的结构
![](/Images/OutliningIndicators/ContractedBlock.gif)
命令的结构
/// <summary>
/// 命令类,用于保存命令
/// </summary>
public struct Command
{
/// <summary>
/// 命令所属的类型
/// Stay, Turn, Dash, Kick, Catch
/// </summary>
public CommandType CType;
/// <summary>
/// 命令的第一个参数
/// Dash 代表一个周期移动的距离
/// Turn 代表转身后角度
/// Kick 代表给球的速度大小
/// </summary>
public double Parameter1;
/// <summary>
/// 命令的第二个参数
/// Kick 代表给球的速度方向
/// </summary>
public double Parameter2;
}
通过上面的2段代码可以了解到5中命令的使用方法:
停止命令(相当于本周期不执行任何命令):
![](/Images/OutliningIndicators/ContractedBlock.gif)
Stay
//实例化一个新的Stay命令
Command stayCommand = new Command();
//设置命令的种类
stayCommand.CType = CommandType.Stay;
//这个参数可以忽略
stayCommand.Parameter1 = 0;
//这个参数可以忽略
stayCommand.Parameter2 = 0;
扑球命令(只有守门员并且在禁区中才能执行)
![](/Images/OutliningIndicators/ContractedBlock.gif)
Catch
//实例化一个新的Catch命令
Command catchCommand = new Command();
//设置命令的种类
catchCommand.CType = CommandType.Catch;
//这个参数可以忽略
catchCommand.Parameter1 = 0;
//这个参数可以忽略
catchCommand.Parameter2 = 0;
奔跑命令(可以向前或向后奔跑)
![](/Images/OutliningIndicators/ContractedBlock.gif)
Dash
//实例化一个新的Dash命令
Command dashCommand = new Command();
//设置命令的种类
dashCommand.CType = CommandType.Dash;
//这个参数设置奔跑的速度(奔跑的速度必须在 RuleSettings.Instance.MinDashVel和RuleSettings.Instance.MaxDashVel之间)
dashCommand.Parameter1 = 0.2;
//这个参数可以忽略
dashCommand.Parameter2 = 0;
转身命令
![](/Images/OutliningIndicators/ContractedBlock.gif)
Turn
//实例化一个新的Turn命令
Command turnCommand = new Command();
//设置命令的种类
turnCommand.CType = CommandType.Turn;
//这个参数设置转身后身体朝向的角度(奔跑的速度必须在RuleSettings.Instance.MaxTurnAngle和RuleSettings.Instance.MinTurnAngle之间)
turnCommand.Parameter1 = 0.2;
//这个参数可以忽略
turnCommand.Parameter2 = 0;
踢球命令(执行该命令的球员和足球之间的距离小于RuleSettings.Instance.MaxKickBallDistance)
![](/Images/OutliningIndicators/ContractedBlock.gif)
Kick
//实例化一个新的Kick命令
Command kickCommand = new Command();
//设置命令的种类
kickCommand.CType = CommandType.Kick;
//这个参数设置踢球的速度大小(踢球的速度大小必须在RuleSettings.Instance.MaxKickBallVelocity和RuleSettings.Instance.MinKickBallVelocity之间)
kickCommand.Parameter1 = 0.2;
//这个参数设置踢球的角度(相对球员自己的身体朝向而言)(踢球的角度在RuleSettings.Instance.MaxKickBallAngle和RuleSettings.Instance.MinKickBallAngle之间)
kickCommand.Parameter2 = 0;
在下一篇文章中,我将帮助大家深入地理解仿真周期的概念。
博客园仿真足球交流小组
相关资源下载
相关文章