码迷,mamicode.com
首页 > 编程语言 > 详细

稍微复杂一点的瞄准算法-直线瞄准算法

时间:2015-02-14 20:02:25      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

package jiaqi;

import java.awt.geom.Point2D;

import robocode.AdvancedRobot;
import robocode.Rules;
import robocode.ScannedRobotEvent;

public class MyDemoRobot extends AdvancedRobot{

	

	/**
	 * 扫描到敌人的时间
	 */
	private double time1 = 0;
	private Enemy enemy = new Enemy();
	private boolean discover = false;// 敌人是否被发现属性
	private double heading = 0.0;
	private double radarHeading = 0.0;
	private double bPower = 3;
	private double time = 0; // 子弹飞行时间
	private double distance = 3000;// 敌人即将到达的位置的距离

	@Override
	public void onScannedRobot(ScannedRobotEvent e) {
		discover = true;// 发现敌人
		time1 = getTime();

		// 初始化敌人
		enemy.setBearing(e.getBearingRadians());
		enemy.setSpeed(e.getVelocity());
		enemy.setDistance(e.getDistance());
		enemy.setHeading(e.getHeadingRadians());

		time = distance / Rules.getBulletSpeed(bPower);
	}

	/**
	 * 打扮
	 */
	private void dressing() {
	}

	/**
	 * 车炮和雷达分离
	 */
	private void severance() {
		setAdjustGunForRobotTurn(true);
		setAdjustRadarForGunTurn(true);
	}

	/**
	 * 最简单的移动算法
	 */
	private void simpleMove() {
		double increment = 0;
		if (enemy.getBearing() > 0) {
			increment = Math.PI / 2 - enemy.getBearing();
			setTurnLeftRadians(increment);
		} else {
			increment = Math.PI / 2 + enemy.getBearing();
			setTurnRightRadians(increment);
		}
		setAhead(1000);
	}

	/**
	 * 安全距离
	 */
	private double safDis = 100;

	/**
	 * 移动
	 */
	private void movement() {
		if (getDistanceRemaining() < 1) {
			double nx = 0;
			double ny = 0;
			// 计算一个随机的安全的X,Y坐标
			nx = Math.random() * (getBattleFieldWidth() - 2 * safDis) + safDis;
			ny = Math.random() * (getBattleFieldHeight() - 2 * safDis) + safDis;

			double headArg = 90 - Math.atan2(ny - getY(), nx - getX());// 计算我们车身要旋转的角度
			headArg = getPA(headArg);
			double dis = Point2D.distance(getX(), getY(), nx, ny);// 计算我们的机器人移动的距离

			if (headArg - getHeadingRadians() > Math.PI / 2) {
				setTurnRightRadians(headArg - getHeadingRadians() + Math.PI);
				setAhead(-dis);
			} else {
				setTurnRightRadians(headArg - getHeadingRadians());
				setAhead(dis);
			}
		}
	}

	/**
	 * 雷达锁定敌人
	 */
	private void doScan() {
		// 判断是否扫描到敌人
		if (discover) {
			// 计算雷达旋转的角度
			heading = this.getHeadingRadians();
			radarHeading = this.getRadarHeadingRadians();
			double temp = radarHeading - heading - enemy.getBearing();
			// 处理异常角度
			temp = correctAngle(temp);
			temp *= 1.2;
			// 设置机器人的雷达回扫
			setTurnRadarLeftRadians(temp);
			// 开始执行机器人运行的设置

		}
	}

	/**
	 * 选择火力
	 */
	private double firePower() {

		return bPower;
	}

	private double correctAngle(double scan) {
		scan %= 2 * Math.PI;// 防止出现大于360度的角
		if (scan > Math.PI) {
			scan = -(2 * Math.PI - scan);// 计算出角度取负为了让雷达反方向旋转
		}
		if (scan < -Math.PI) {
			scan = 2 * Math.PI + scan;
		}
		return scan;
	}

	/**
	 * 直接瞄准
	 */
	private double immidate() {
		double increment = heading + enemy.getBearing()
				- getGunHeadingRadians();
		increment %= 2 * Math.PI;
		increment = correctAngle(increment);
		return increment;
	}

	/**
	 * 调炮
	 */
	private void gun() {
		// double increment = immidate();
		double increment = line();
		setTurnGunRightRadians(increment);

	}

	/**
	 * 获得正角的方法
	 * 
	 * @return
	 */
	private double getPA(double angle) {
		angle %= 2 * Math.PI;
		if (angle < 0) {
			angle += 2 * Math.PI;
		}
		return angle;
	}

	/**
	 * 直线瞄准
	 * 
	 * @return
	 */
	private double line() {
		// 计算出敌人即将出现的坐标
		// 1. 计算敌人目前的坐标
		double ea = getPA(getHeadingRadians() + enemy.getBearing());// 敌人的所在方向角度
		double ex = getX() + enemy.getDistance() * Math.sin(ea);// 敌人目前的X坐标
		double ey = getY() + enemy.getDistance() * Math.cos(ea);// 敌人目前的Y坐标

		// 2. 计算敌人即将运动距离
		double s = 0;// 保存敌人运动距离
		if (enemy.getSpeed() >= Rules.MAX_VELOCITY - 0.1) {
			s = enemy.getSpeed() * time;
		} else if (enemy.getSpeed() > 0.0) {
			double as = (Math.pow(Rules.MAX_VELOCITY, 2) - Math.pow(
					enemy.getSpeed(), 2))
					/ 2 * Rules.ACCELERATION;// 加速运动的距离
			double vs = (time - (Rules.MAX_VELOCITY - enemy.getSpeed())
					/ Rules.ACCELERATION)
					* Rules.MAX_VELOCITY;// 匀速运动的距离
			s = as + vs;
		} else {
			s = 0.0;
		}

		// 3. 计算敌人即将出现的坐标
		double nextx = ex + s * Math.sin(enemy.getHeading());
		double nexty = ey + s * Math.cos(enemy.getHeading());
		distance = Point2D.distance(getX(), getY(), nextx, nexty);
		double t = Math.atan2(nexty - getY(), nextx - getX());// 计算敌人即将到达位置的角度

		return correctAngle((Math.PI / 2 - t - getGunHeadingRadians())
				% (2 * Math.PI));
	}

	public void run() {
		// 第一步:要给机器人一身漂亮的行头,车身,炮和雷达及扫描弧要着上独特的颜色。
		dressing();
		// 第二步:要让机器人的车炮和雷达分离,互不影响。高级机器人都这样做。
		severance();
		// 让雷达先转一圈,以触发雷达扫描事件
		// setTurnRadarLeft(400);
		// execute();
		while (true) {
			if (!discover) {
				setTurnRadarLeftRadians(Math.PI * 2.1);
				execute();
			} else {
				// 第三步:要确定机器人如何移动的算法
				movement();
				// 第四步:要确定机器人如何选择火力的算法
				double fire = firePower();
				// 第五步:要确定机器人如何锁定其它机器人的算法
				doScan();
				// 第六步:要确定机器人如何计算角度并调整炮口瞄准敌人的算法
				gun();
				// if (getGunTurnRemaining() <= 0) {
				// 开枪
				setFire(fire);
				execute();
				// }
				// 判断敌人是否丢失
				loseTarget();
				execute();
			}
		}
	}

	/**
	 * 判断是否丢掉敌人
	 * 
	 */
	private void loseTarget() {
		if ((getTime() - time1) >= 4)
			discover = false;
	}
	
	
	
}
======================================
package jiaqi;

public class Enemy {

	private double bearing;//自己与敌人的夹角
	private double distance;//与敌人的距离
	private double heading;
	private double velocity;
	
	private double speed;
	
	public double getSpeed() {
		return speed;
	}
	public void setSpeed(double speed) {
		this.speed = speed;
	}
	public double getBearing() {
		return bearing;
	}
	public void setBearing(double bearing) {
		this.bearing = bearing;
	}
	public double getDistance() {
		return distance;
	}
	public void setDistance(double distance) {
		this.distance = distance;
	}
	public double getHeading() {
		return heading;
	}
	public void setHeading(double heading) {
		this.heading = heading;
	}
	public double getVelocity() {
		return velocity;
	}
	public void setVelocity(double velocity) {
		this.velocity = velocity;
	}
	
	
	
	
}

  

稍微复杂一点的瞄准算法-直线瞄准算法

标签:

原文地址:http://www.cnblogs.com/aicpcode/p/4292089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!