稍微复杂一点的瞄准算法-直线瞄准算法
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; } }