Robocode教程7——雷达锁定,“观察者号”

摘自:http://site.douban.com/widget/notes/7736245/note/211198836/

 

Robocode教程7——雷达锁定

在这次教程中,我们要写这样一个代码,它将让敌人逃不出我们的眼睛。雷达锁定是一个高效战斗机器人的基础,因为robot只有执行onScannedRobot方法,我们才能够获取敌人的信息,而onScannedRobot方法只有在我们的雷达扫描到敌人之后才会被调用,当然,调用的过程是自动的。
雷达是以机器人为圆心的一条射线,为了更直观,我们最好打开雷达图形显示,方法是:
进入robocode,打开Options-> Preferences->view options,勾选Visible Scan Arcs

 


还记得我们的Enemy类吗?它在我们的这个机器人中有着至关重要的作用。所以如果不太熟悉class Enemy的话还是先去看看吧。
在Enemy类中有一个direction变量,它的值为:
direction = bearingRadian + me.getHeadingRadians();

 


如这张图所示,弄懂了direction变量,雷达锁定就很简单了。
雷达的扫描实际上是一条线,当扫描线扫描到目标时,触发onScannedRobot事件,更新当前数据,包括direction。当程序执行到onScannedRobot内的代码时,雷达扫描线的角度getRadarHeadingRadians()已经和direction有所偏离。为了锁定目标,我们可以把雷达往反方向扫描。因为雷达旋转很快,而且getRadarHeadingRadians()和direction的偏移量不大,机器人是有一定大小的。于是扫描线在目标身上来回扫动,实现了雷达锁定。

public void onScannedRobot(ScannedRobotEvent e) { 
             enemy.update(e,this); 
        double Offset = rectify( enemy.direction -getRadarHeadingRadians() ); 
      setTurnRadarRightRadians( Offset * 1.5); 
}
这是我们的onScannedRobot方法,enemy.updata(e,this);是调用我们的enemy对象里面的方法,更新敌人信息,当然,忘了一点,在这之前,我们需要生成一个enemy对象,具体方法为:
Enemy enemy = new Enemy();
这里我们还要解释一下rectify方法,它的作用是对角度进行修正,因为direction减去我们雷达的朝向,有可能会大于180度或者小于-180度,比如当大于180度时,我们所需要转动的角度并不需要那么大,只需方向转一个角度就可以了。这个rectify方法很简单,当在后面应用很多。它的代码为:
    public double rectify ( double angle ) 
    { 
        if ( angle < -Math.PI ) 
            angle += 2*Math.PI; 
        if ( angle > Math.PI ) 
            angle -= 2*Math.PI; 
        return angle; 
}
在代码中,enemy.direction -getRadarHeadingRadians()是雷达所要旋转的偏移量。假设之前雷达顺时针扫描,那么enemy.direction略小于getRadarHeadingRadians(),为负。经rectify()方法修正后即为需要转动的值。然后用setTurnRadarRightRadians旋转雷达,旋转度数为偏移的1.5倍,因为RadarOffset为负,故反方向扫描,保证无论目标
如何移动,扫描线始终在目标身上。上面的1.5可以改成2,3等数。当你在Options中打开了Visible Scan Arcs选项后,就可以看到绿色的扇形,倍数为1.5的时候,类似一条线,而倍数为2,3的时候就可以看到像是一个扇形。
另外我们还要说一下另外两段代码:
                 setAdjustGunForRobotTurn( true ); 
        setAdjustRadarForGunTurn( true );
它们的作用是使雷达、大炮、车身运动独立,具体参考API手册。

到这里我们雷达扫描的代码就完成了,运行试试我们的“观察者号”吧!!

 



附:观察者号完整代码:

package cm; 
import java.awt.*;
import robocode.*; 

public class ObserverRobo extends AdvancedRobot 
{
        Enemy enemy = new Enemy();
        public static double PI = Math.PI;
             
        public void run() 
        { 
                setAdjustGunForRobotTurn( true ); 
        setAdjustRadarForGunTurn( true ); 
        this.setColors(Color.red, Color.blue, Color.yellow, Color.black, Color.green);
        
                while(true){
                        if(enemy.name == null){
                                setTurnRadarRightRadians(2*PI); 
                                execute(); 
                        }
                        else{
                                execute();
                        }
                }
    }
             
    public void onScannedRobot(ScannedRobotEvent e) 
    { 
            enemy.update(e,this); 
        double Offset = rectify( enemy.direction - getRadarHeadingRadians() ); 
        setTurnRadarRightRadians( Offset * 1.5); 
    }
  //角度修正方法,重要
    public double rectify ( double angle ) 
    { 
        if ( angle < -Math.PI ) 
            angle += 2*Math.PI; 
        if ( angle > Math.PI ) 
            angle -= 2*Math.PI; 
        return angle; 
    }
    public class Enemy {
            public double x,y;
            public String name = null;
            public double headingRadian = 0.0D; 
        public double bearingRadian = 0.0D; 
        public double distance = 1000D; 
        public double direction = 0.0D; 
        public double velocity = 0.0D; 
        public double prevHeadingRadian = 0.0D; 
        public double energy = 100.0D; 
        
        
        public void update(ScannedRobotEvent e,AdvancedRobot me){
                name = e.getName();
                headingRadian = e.getHeadingRadians();
                bearingRadian = e.getBearingRadians();
                this.energy = e.getEnergy();
                this.velocity = e.getVelocity();
                this.distance = e.getDistance();
                direction = bearingRadian + me.getHeadingRadians(); 
                x = me.getX() + Math.sin( direction ) * distance; 
                y= me.getY() + Math.cos( direction ) * distance; 
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值