⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shooter3.c

📁 虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人虚拟足球机器人
💻 C
字号:
#include <airobot/c/ActionListeningRobot.h>

/* 新的踢球算法 */
void shoot(double targetX, double targetY, double ballX, double ballY);

//计算球在times个单位时间后的位置
void next(int times, double* nextX, double* nextY);

void onTick(struct TickAction* action)
{
	
	double targetX = getOpponentGoalCenterX();
	double targetY = getOpponentGoalCenterY();
	double hitedX = getBallX();
	double hitedY = getBallY();
	nextPoint(1,2,3,4,&hitedX,&hitedY);
	printDouble(hitedX);
	printDouble(hitedY);
	
	// 跌代计算球的运行线路,计算未来的击球点
	for (int i = 0; i < 200; i++)
	{
		double nextX, nextY;
		next(i, &nextX, &nextY);
		if (distance(nextX, nextY, getX(), getY()) < i * getMaxMoveVelocity())
		{
			hitedX = nextX;
			hitedY = nextY;
			break;
		}
	}
	shoot(targetX, targetY, hitedX, hitedY);
}

void shoot(double targetX, double targetY, double ballX, double ballY)
{
	/* R越小,抢劫能力就越强,不过背身拿球的能力会减弱 */
	double R =((getBallRadius() + getRadius())*0.93);
	
	double tangentX1, tangentX2, tangentY1, tangentY2; //两个切点的坐标
	double bestHitX, bestHitY; //最佳击球点坐标
	double tangentBearing, ballToMeHeading;

	double distanceToTarget = distance(targetX, targetY, getX(), getY());
	if(distanceToTarget<R) //防止出现异常
	{
		setMoveToward(targetX, targetY, getMaxMoveVelocity());
		return;
	}
	
	tangentBearing = acos(R/distanceToTarget);
	ballToMeHeading = heading(ballX, ballY, getX(), getY());
	
	nextPoint(
		ballX, ballY, 
		ballToMeHeading + tangentBearing,
		R,
		&tangentX1, &tangentY1
	);
	
	nextPoint(
		ballX, ballY,
		ballToMeHeading - tangentBearing,
		R,
		&tangentX2, &tangentY2
	);
	
	nextPoint(
		ballX, ballY,
		heading(targetX, targetY, ballX, ballY),
		R,
		&bestHitX, &bestHitY
	);

	modifyInCourt(&tangentX1, &tangentY1, getRadius());
	modifyInCourt(&tangentX2, &tangentY2, getRadius());
	modifyInCourt(&bestHitX, &bestHitY, getRadius());
	
	if (distance(getX(), getY(), bestHitX, bestHitY) < distance(getX(), getY(), tangentX1, tangentY1))
		setMoveToward(bestHitX, bestHitY, getMaxMoveVelocity());
	else if (distance(bestHitX, bestHitY, tangentX1, tangentY1) < distance(bestHitX, bestHitY, tangentX2, tangentY2))
		setMoveToward(tangentX1, tangentY1, getMaxMoveVelocity());
	else setMoveToward(tangentX2, tangentY2, getMaxMoveVelocity());
}

void next(int times, double* nextX, double* nextY)
{
	double velocity = getBallVelocity(); // 球当前的速度
	double heading = getBallHeading(); // 球当前的方向	
	double acc = -getBallNegativeAcceleration(); // 球的加速度
	*nextX = getBallX();
	*nextY = getBallY();
	
	for (int i = 0; i < times; i++)
	{
		if(velocity==0) break;			
		nextPoint(*nextX, *nextY, heading, velocity * 1, nextX, nextY);

		// 摩擦减速
		if (velocity > 0)
		{
			velocity += acc * 1;
			velocity = fmax(0, velocity);
		}
		else if (velocity < 0)
		{
			velocity -= acc * 1;
			velocity = fmin(0, velocity);
		}
		
		// 撞墙检测
		if ((*nextX) < 0 || (*nextX) > getCourtWidth())
		{
			heading = PI - heading;
			modifyInCourt(nextX, nextY, getBallRadius());
		}
		if ((*nextY) < 0 || (*nextY) > getCourtHeight())
		{
			heading = -heading;
			modifyInCourt(nextX, nextY, getBallRadius());
		}
	}
}
													

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -