JAVA坦克大战系列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?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吧! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |