小小千想和您聊一聊

当前位置: 首页> 技术分享> 坦克大战系列10-高效雷达(下)

坦克大战系列10-高效雷达(下)

  前言

  本篇将给大家准备一个非常高效的雷达扫描坦克,可以有效的锁定敌人。

  高效雷达坦克示例

  废话就不多说了,直接上代码吧。
1.import java.awt.Color;  
2.  
3.import robocode.AdvancedRobot;  
4.import robocode.RobotDeathEvent;  
5.import robocode.ScannedRobotEvent;  
6.  
7.public class QFRadarRobot extends AdvancedRobot{  
8.  Enemy target;//定义敌人  
9.  final double PI = Math.PI;//创建常量PI  
10.  int direction = 1;//向前方向值为1,向后为-1;  
11.    public void run() {  
12.        target = new Enemy();  
13.        target.distance = 10000;//初始化敌人距离  
14.          
15.        this.setAdjustGunForRobotTurn(true);//使枪和坦克独立  
16.        this.setAdjustRadarForGunTurn(true);//时枪和雷达独立  
17.          
18.        this.turnRadarRightRadians(2*PI);//雷达扫描一周(弧度)  
19.          
20.        while(true) {  
21.            doScanner();//扫描别的坦克  
22.            out.println(target.distance);  
23.            execute();//执行以上所有命令              
24.        }  
25.    }  
26.      
27.      
28.    //移动坦克  
29.    private void doMovement() {  
30.          
31.        if(getTime()%20==0){  
32.            //每20个时间间隔执行一次  
33.            direction *=-1;//反向运动  
34.            setAhead(direction*300);//前后运动  
35.        }  
36.        //依据弧度转向  
37.        this.setTurnRightRadians(target.bearing+(PI/2));  
38.          
39.    }  
40.     
41.  
42.     
43.  
44.    //雷达扫描  
45.    private void doScanner() {  
46.        double radarOffset;//雷达扫描区域  
47.        if(getTime()-target.ctime>4){  
48.            //如果4秒内在小区域中没有发现目标  
49.            radarOffset = 360;//雷达转一圈  
50.        }else{  
51.            //找到目标后使搜索范围扩大以至于不丢失目标  
52.            radarOffset = this.getRadarHeadingRadians()-absbearing(getX(),getY(),target.x,target.y);  
53.            if(radarOffset<0){  
54.                radarOffset-=PI/8;//稍稍增大扫描区域  
55.            }else{  
56.                radarOffset+=PI/8;//稍稍增大扫描区域  
57.            }  
58.        }  
59.        this.setTurnRadarLeftRadians(NormaliseBearing(radarOffset));//旋转雷达  
60.          
61.    }  
62.  
63.  
64.     
65.    //转向弧度差  
66.   public double NormaliseBearing(double ang){  
67.        if(ang>PI)  
68.            ang -=2*PI;  
69.        if(ang<-PI)  
70.            ang +=2*PI;  
71.        return ang;  
72.    }  
73.     
74.     
75.    //如果角度大于360度,则得到标准化角度  
76.    public double NormaliseHeading(double ang){  
77.        if(ang>2*PI){  
78.            ang -= 2*PI;  
79.        }  
80.        if(ang<0){  
81.            ang +=2*PI;  
82.        }  
83.        return ang;  
84.    }   
85.   //确定目标的移动直线距离  
86.    public double getrange(double x1,double y1,double x2,double y2){  
87.        double xo = x2-x1;  
88.        double yo = y2-y1;  
89.        double h = Math.sqrt(xo*xo+yo*yo);  
90.        return h;  
91.    }  
92.      
93.      
94.      
95.      
96.      
97.    //确定绝对位置的方法  
98.    public double absbearing(double x1,double y1,double x2,double y2){  
99.        double xo = x2-x1;//水平位移  
100.        double yo = y2-y1;//垂直位移  
101.        double h = getrange(x1,y1,x2,y2);  
102.        if(xo>0&&yo>0){  
103.            return Math.asin(xo/h);//正弦弧度  
104.        }  
105.        if(xo>0&&yo<0){  
106.            return Math.PI - Math.asin(xo/h);  
107.        }  
108.        if(xo<0&&yo<0){   
109.            return Math.PI + Math.asin(-xo/h);  
110.        }  
111.        if(xo<0&&yo>0){  
112.            return 2.0*Math.PI- Math.asin(-xo/h);  
113.        }  
114.        return 0;  
115.    }  
116.      
117.    //扫描到敌方坦克  
118.    public void onScannedRobot(ScannedRobotEvent e) {  
119.        if((e.getDistance()<target.distance)||target.name==e.getName()){  
120.            //确定坦克绝对位置  
121.            double absbearing_rad = (this.getHeadingRadians()+e.getBearingRadians())%(2*PI);  
122.            //定义坦克的相关信息  
123.            target.name = e.getName();  
124.            target.x = getX()+Math.sin(absbearing_rad)*e.getDistance();//计算目标的X坐标  
125.            target.y = getY()+Math.cos(absbearing_rad)*e.getDistance();//计算目标的Y坐标  
126.            target.bearing = e.getBearingRadians();//  
127.            target.head = e.getHeadingRadians();//获得坦克头的方向  
128.            target.ctime = getTime();//记录扫描到坦克的时间  
129.            target.speed = e.getVelocity();//记录目标的速度  
130.            target.distance = e.getDistance();//记录目标离自己的距离  
131.              
132.        }  
133.      
134.    }  
135.      
136.      
137. 
138.      
139.    //内部类,用来保存对手的相关信息  
140.    class Enemy{  
141.        String name;//定义坦克的名字  
142.          
143.        public double bearing;  
144.        public double head;  
145.        public long ctime; //记录扫描到该坦克的时间  
146.        public double speed;  
147.        public double x,y;//坐标  
148.        public double distance;//距离  
149.        //预计坦克x坐标  
150.        public double guessX(long when){  
151.            long diff = when - ctime;  
152.            return x+Math.sin(head)*speed*diff;  
153.        }  
154.        //预计坦克y坐标  
155.        public double guessY(long when){  
156.            long diff = when-ctime;  
157.            return y + Math.cos(head)*speed*diff;  
158.        }  
159.    }  
160.}  
  通过示例代码中的注释大家能够发现,本坦克的雷达扫描就是基于敌人的移动方式提前预判敌人可能会出现的目标位置,如果敌人不再预测的目标位置,便会快速旋转雷达一周以便于更方便的锁定敌人。

  好啦,本期内容就到这里喽,我是不会玩游戏却非得写游戏的陈老师,一起来学习JAVA吧!

上一篇:HTML5工具初识之网页编辑器

下一篇:PS 抠人像如何抠得干净

QQ技术交流群

千锋Java开发官方①群
811099962

加入群聊