哈利波特中文手机游戏戏robocode怎么设置中文

坐标基本概念
首先我们还是来看看 Robocode API 中的一段文字翻译。
All coordinates are expressed as (x,y).
所有的坐标都用 x,y 来表示
All coordinates are positive.
所有的坐标都为正
The origin (0,0) is at the bottom left of the screen.
坐标原点 (0,0) 在屏幕的左下角
Positive x is right. X 的右边为正
Positive y is up. Y 的上面为正
图 1 显示了 Robocode 中的坐标系统,有关图的详细说明请看我们前面介绍的文章 .
“动静机器人”测试法
好了,我们知道了 Robocode 整个坐标系统,一切问题都好办了。先让我们进行一些有趣的实验。我们仍以”动静机器人”的方法进行测试。这是个测试机器人方向,坐标参数的很好办法。见下说明:
设计两个机器人,任意取名为 Geny 和 GenyTrack。Geny 是个静止的机器人,它主要任务是打印自己的当前坐标,用来验证 GenyTrack 追踪它的位置是否正确。GenyTrack 顾名思义,它就是我们要研究的追踪目标机器人了。它在此负责锁定 Geny 的坐标,距离并打印出探测到的 Geny 机器人的 X,Y 坐标及距离 , 此处使用了 Java.lang 类库中的 Math.round 方法 , 四舍五入得到的 double 类型的数据,方便对比。最后用表格对比,以此来验证我们使用方法的正确性。
当然还有很多有趣的测试方法来等待着你的验证。如测速度,加速度时我们就可用”龟兔赛跑”的方法;测炮管,雷达坦克车旋转相互影响度可用”离心重力”的方法。相信从测试方法的名字聪明的你们就知道他的用法了。
在我们开始前,Skyala.Li 建议你们下载源码 ( )
先看看 GenyTrack 的表演。当然你也可参考文章内附加的辅助说明 Robocode 坐标系统的代码。
import robocode.*;
public class Geny extends AdvancedRobot
public void run ()
while (true)
// round 对 get 到的数据进行四舍五入处理
out.println("x:"+Math.round(getX()));
out.println("y:"+Math.round(getY()));
GenyTrack:
import robocode.*;
public class GenyTrack extends AdvancedRobot
public void run ()
while (true)
turnRadarRight(400);
public void onScannedRobot(ScannedRobotEvent e)
double bearing = (getHeading() + e.getBearing()) % 360;
double distance = e.getDistance();
bearing = Math.toRadians(bearing);
double genyX = getX() + Math.sin(bearing) *
double genyY = getY() + Math.cos(bearing) *
out.println("genyX:"+ Math.round(genyX));
out.println("genyY:"+ Math.round(genyY));
注意这两个机器人我们都使用了 AdvancedRobot 的类,这可是高级机器人的说明了。有关高级机器人大家可以查找 Robocode API 的说明,也可看看 Sing Li 的 .
要得到目标坐标我们首先得知道我们和目标之间的距离。这里的距离探测很简单,只要运用 GenyTrack 机器人 ScannedRobotEvent 事件中的 getDistance() 方法我们就可得到 Geny 机器人和你之间的距离差了。只是要注意一点,由于机器人存在着宽和高 , 可分别用 Robocode API 中的 getWidth() 和 getHeigth() 方法得到。而两个机器人的距离是以双方的中心点为终点。如图所示,L 才是它们的距离,A 的距离是错误的。
知道了对方的距离,知道了整个坐标系统。我们就来锁定我们的目标 Geny. 我们先来看看图 3 所示:
列表 1 就是我们用”动静机器人”测试法得出的数据。你将会惊喜若狂,不错,我们成功的探测到了我们可怜的 Geny 的坐标。惊喜过后你就会不明白了 : 我们是怎样实现这一切的?为什么代码中使用到了非 Robocode 中的类库 Math,还似乎用到了正余弦求解,还有弧度?不错,这就是 Robocode: 处处都让我们惊奇,处处都让我们学习新的知识。如果你对中学时代的数学三角几何解法已经陌生,没关系,你将在我们本文最后的 中将学习到这些。它将勾起你中学时代的记忆。
现在让我们来分析分析我们 GenyTrack 到底做了些什么:
在 GenyTrack 的 ScanndeRobotEvent 事件中我们首先得到 Geny 的绝对角度 bearing,也即相对屏幕的角度。并从 ScannedRobotEvent 扫描事件中得到的大量信息分析中提炼出 Geny 和 GenyTrack 的距离为 distance。有了 Geny 的角度 , 有了 Geny 的距离我们再根据三角学基础(详见文 )就可求出
Geny 的精确坐标了。
又由于 Java 类库中的正弦函数 sin 余弦函数 cos 是以弧度制(详见文 )为角度的参数。所以我们利用了
Math.toRadians 方法把 Geny 的绝对角度转化为弧度。见列表 2
double bearing = (getHeading() + e.getBearing()) % 360;
double distance = e.getDistance();
bearing = Math.toRadians(bearing);
double genyX = getX() + Math.sin(bearing) *
double genyY = getY() + Math.cos(bearing) *
out.println("genyX:"+ Math.round(genyX));
out.println("genyY:"+ Math.round(genyY));
注意三角函数的基础中:对边长 =sina * 斜边长,侧边长 =cosa *斜边长,但要记住 Robocode 中三角坐标系统中的 sin 和 cos 和我们数学中的三角坐标系统有一定差别,也即上面的 sina 和 cosa 要对换,对边长 =cosa* 斜边长。图 4 画出了 Geny 和 GenyTrack 之间角度和距离的关系以及 Robocode 所采用的三角坐标系统。
黑线条为 GenyTrack 的 X,Y 坐标 , 蓝线条以 Geny 的距离 distance 和绝对角度 bear 求得的 X,Y 坐标 , 两者相加得到的就是 Geny 的 X 和 Y 坐标。
至于 Math 类库的使用,我们就不详细说明了。读者也可从下面的 IBM Java 专区链接中找到很多有关的知识,也可参考一些 Java 类库书籍说明。当你设计高级 Robocode 机器人时你会发现,Math 类库是你不可缺少的一部分知识。此处我们只简单的介绍正弦函数及余弦函数的使用。
public static double sin(double a)
Returns the trigonometric sine of an angle.
Parameters:
a - an angle, in radians.
the sine of the argument
Sin 函数返回三角的正弦函数,参数 a 是一个以 double 类型以弧度表示的角度值,返回类型为 double.
public static double cos(double a)
Returns the trigonometric cosine of an angle.
Parameters:
a - an angle, in radians.
the cosine of the argument
Cos 函数返回三角的余弦函数,参数 a 是一个以 double 类型的弧度表示的角值 , 返回类型为 double.
有人会问为什么不使用 ScanndeRobot 事件中的 getRadarHeadingRadians() 方法直接得到弧度。哦,你来看看 的一段说明:
public void onScannedRobot(ScannedRobotEvent event) {
enemyX=Math.sin(Util.standardMathDirRadians(getRadarHeadingRadians()))*event
.getDistance();
enemyY=Math.cos(Util.standardMathDirRadians(getRadarHeadingRadians()))*event
.getDistance();
看起来好像正确的,但是你实践一下会发现他很不准确,为什么呢?原因在于 getRadarHeadingRadians() 函数,当你调用此函数的时候实际上雷达已经不在刚刚扫描到敌人的那个角度了,他已经转过了十几度甚至更多。雷达默认转动速度是 45 度 /robocode 单位时间,实际上一般来说你用 getRadarHeadingRadians() 得到的值总是 45 度的整数倍。(一些情况除外,比如说你用了 turnRadarLeft(11) 类似的语句以后)。
Robocode 也遵循数学应用中的基本法则用两种方法来表示方向的角度:角度制和弧度制,本文的代码及以前文章中的代码我们一直用的是角度制。另外一种方法就是利用 ScannedRobotEvent.getBearingRadians()+robot.getHeadingRadians() 得到敌人以弧度表示的方向,这个方法在本文章中没有说明了,有兴趣的朋友可以自己试试用 Java.util 类库来实现 . 也可参考文档 。大家也可比较两种方法各自特点,这将是个很有意思的过程。
当然,即使是最简单的机器人也不会坐在那一动不动等着你来消灭。它会躲避你的进攻以及扫描,当你向它原来坐标处开火,说不定它已经跑得老远了,当然这一切都不是我们所希望看到的。 我们的目的是要消灭它 : 不管他是移动或静止的。下面我们就结合方向系统与坐标系统,来锁定我们移动的目标。创造一个我们自己的高级扫描机器人。建议你在此处下载源代码 ( )
并看看演示效果再回到我们的文章中来。显示如图 5:
对比一下上面的数据,不管目标 GenyMove 在哪 GenyRadar 都能得到它精确的坐标。是不是有一种成就感!是的,敌人已经完全在我们的掌握之中。即使它在移动中也无法摆脱我们雷达的扫描控制。这里只是很简单举了一些例子,GenyMove 在每一个时间周期(有关时间周期的说明见的 2)移动自己的位置并打印出移动后的坐标,而 GenyRadar 扫描系统不停的扫描目标,并一直追踪,同时打印出扫描到的 GenyMove 方位。关键部分在我们的 ScannedRobotEvent 事件如列表 3
public void onScannedRobot( ScannedRobotEvent e )
double heading = e.getBearing() +getHeading();
double distance = e.getDistance(); // 求得距离
double ager_bearing = Math.toRadians(heading % 360); // 角度转为弧度
double genyX = getX() + Math.sin(ager_bearing) *
double genyY = getY() + Math.cos(ager_bearing) *
out.println("genyX:"+ Math.round(genyX));
out.println("genyY:"+ Math.round(genyY));
if( heading &= 360 )
heading = heading - 360;
if( heading & 0 )
heading = heading +360;
double bearing = getRadarHeading() -
double radar_
boolean radar_
if( 0 &= bearing && bearing &= 180 )
radar_direction = LEFT;
else if( bearing &= -180 )
radar_direction = LEFT;
bearing = ( 360 + bearing );
else if( bearing & 0 )
radar_direction = RIGHT;
bearing =( -bearing );
radar_direction = RIGHT;
bearing = (360 - bearing);
radar_degree = bearing * 1.3 ; // 加大每一时间周期 (tick) 的扫描范围
if( radar_direction == RIGHT )
setTurnRadarRight( radar_degree );
execute();
setTurnRadarLeft( radar_degree );
execute();
我们在代码中首先求得 GenyMove 的绝对角度,然后用扫描时雷达的绝对角度减去目标 GenyMove 的角度求得两者的角度差也即我们雷达要旋转的角度。最后利用一个小技巧 radar_degree = bearing * 1.3 使雷达在目标的范围左右摆动以扩大雷达扫描区域 . 这样不管目标往哪边移动都在自己的雷达扫描区内。
在此没有进行很详细的讲解了,我想凭你学到的方向及坐标知识很快能明白个中原理并设计出自己的高级扫描机器人来。 聪明的你可能会高兴的想,哈,我的炮管用相同的办法锁定目标,这样敌人不就没办法跑了,被我追着打。答案是错误的,雷达的扫描是条长线能直接定位到目标上 ,它到目标的时间差几乎为零,并且雷达的扫描范围比炮管大且精确。而炮管每时间周期只有 20 度,它定位目标是依靠着子弹 , 只有子弹打中了目标,才能说炮管的计算坐标是精确的。但是由于子弹 到达目标位置时需要一定的时间差,子弹本身又有速度值(20-3*power),所以要想炮管锁定目标并让子弹击中目标,我们还得经过精确的计算
, 并要预测目标可能的行动:是直线前进,还是做圆周运动,还是随机运动等等。 这些都是我们要充分考虑的因素。是不是很有挑战性 ! 这一切都在 Robocode 的世界中等待着您的创造!
三角函数基础
下面我们只是很简单的介绍了一下与 Robocode 相关的三角函数知识,要想了解详细的,大家可从家中高中代数与几何书中得到这一切。
1 .角的概念
在平面内,角可以看作一条射线绕着它的端点旋转而成的图形。如图,一条射线由原来的位置 OA,绕着它的端点 O 按逆时方向旋转到另一位置 OB,就形成角 a. 旋转开始时的射线 OA 叫做角 a 的始边,旋转终止时的射线 OB 叫做角 a 的终边,射线的端点 O 叫做角 a 的顶点。习惯上,我们把按逆时针方向旋转而成的角叫做正角;按顺时针方向旋转而成的角叫做负角 . 所有与 a 终边相同的角包括 a 在内,可以用式子表示:a+K*360 度 , 对应到 Robocode 的方向系统中,只要我们以机器人的 heading
方向做射线,延长到与屏幕交点处的角度就是我们机器人的 heading 角度。
2. 直角三角函数
在△ ABC 中,∠ a 为直角,我们把锐角 A 的对边与斜边的比叫做∠ A 的正弦,记作 sina;锐角 a 的邻边与斜边的比叫做∠ a 的余弦,记作 cosa,即
sina= 对边 BC/ 斜边 AB
cosa= 邻边 AC/ 斜边 AB
3. 单位圆和三角函数线
半径为 1 的圆叫做单位圆。设单位圆的圆心与坐标原点重合,则单位圆与 x 轴的交点分为别为 A(1,0)、A ′ (-1,0),与 y 轴的交点分别为 B(0,1)、B ′ (0,-1)。设角 a 的顶点在圆心 O,始点与 x 轴的正半轴重合,终边与单位圆相交于点 P,过点 P 作 PM 垂直 x 轴于 M,则由直角三角函数的定义可知 :OM=cosa,MP=sina ,点 P 的坐标为 (cosa,sina),即 P(cosa,sina)。其中 cosa = OM*1,sina = MP*1。Robocode
中所有有关的坐标都可用这种方法求得。
4 .弧度制
用度做单位来度量角的制度叫做角度制。数学和其他科学研究中常用另一种度量角的制度―弧度制。以角的顶点为圆心,以任意长的半径作圆把这个角所对的弧长与半径的比来衡量角的制度叫做弧度制 . 长度等于半径的弧长叫 1 弧度。这段弧所对的圆心角的大小也是 1 弧度。通常单位“弧度”省略不写。例:弧长为 1.3325。单位就是弧度。由角度和弧度两种单位之间的关系得到 :2 π弧度 =360 度 ,2/3 π弧度 =270 度 , π弧度 =180 度 ,1/2 π弧度 =90 度 , 并可推出 1 弧度 = 360 度 /2
π = 57 °即 1 弧度 = 角度 *180/Math.PI.
一般规定:正角的弧度数为正数,负角的弧度数为负数,零角的弧度数为零。这样角的集合与实数集合的元素就建立起了“一一对应”的关系。
经典Robocode例子代码- -SnippetBot
Robocode教程1——安装、运行、配置
教你玩Robocode(5)——调试技巧
如何获得海量的RoboCode代码
没有更多推荐了,用游戏来学习Java技术(Robocode攻略)
我的图书馆
用游戏来学习Java技术(Robocode攻略)
Robocode(用游戏来学习Java技术还是用Java来玩游戏?)用你的JAVA编程技术来玩游戏吧!不会JAVA?那就用游戏来学习JAVA吧!什么是Robocode?
其实我对机器人一直很感兴趣。我记得在我还是初中的时候,就知道 AplleⅡ上有一个程序,用它来编写简单的机器人程序,然后相互作战。当时自己还完全不懂编程,总是向往着,那神秘的编程高手玩的游戏是怎样的?
Robocode就是这样一个东西,但是更好一些。它是一个基于Java语言的机器人作战游戏。 其代码的编写和建模都不错,玩起来也很有趣。Robocode是很多"编程游戏"软件中的一个,他们共同的特征是在没有用户输入的状态下许多机器人在一个及竞技场中比赛,用户必须编制一个高效的机器人来取胜。Robocode特别的像一场机器人坦克的大混战,它们互相开火直到只剩一个胜利者。程序完全是由JAVA编写,并且玩家必须要创造一个继承自Robot类的类。
你希望在玩游戏的过程中、在闪躲炮弹、执行精确攻击的演练中学会Java编程的 继承、多态性、事件处理以及内部类这些内容吗?Robocode 这个游戏为全世界的 Java 开发者实现这个愿望,它把游戏风潮变成了教学工具,人们对它的上瘾程度令人吃惊。下面,我参考网友 Sing Li 以前写的文章,让我们一起来拆解 Robocode,同时着手建造属于自己的、定制的、小而精悍的战斗机器吧!
Robocode 是一个很容易使用的机器人战斗仿真器,可以在所有支持 Java 2 的平台上运行。您创建一个机器人,把它放到战场上,然后让它同其他开发者们创建的机器人对手拼死战斗到底。Robocode 里有一些预先做好的机器人对手让你入门,但一旦您不再需要它们,就可以把您自己创建的机器人加入到正在世界范围内形成的某个联盟里去和世界最强手对阵。
每个 Robocode 参加者都要利用 Java 语言元素创建他或她的机器人,这样就使从初学者到高级黑客的广大开发者都可以参与这一娱乐活动。初级的 Java 的开发者们可以学习一些基础知识:调用 API 代码、阅读 Javadoc、继承、内部类、事件处理等等。高级开发者们可以在构建“最优品种”的软件机器人全球竞赛中提高他们的编程技巧。在本文中,我们将介绍 Robocode,并指导您从构建您平生第一个 Robocode 机器人开始征服世界。我们还将看一下迷人的“后台”机制,正是它使得 Robocode 起作用。
首先当然是下载和安装 Robocode 啦
Robocode 是 Mathew Nelson 的智慧之作,他是 IBM Internet 部门 Advanced Technology 的软件工程师。现在Robocode的主页已经搬迁到sourceforge这个开源网站上了,大家可以在这里下载RobotCode的最新版&到3月21日为止最新版本是1.0.7,大小为3.2M。好了,下载回来后当然还要在你的电脑上安装JAVA运行库才行的哦~地址是1.先安装好JAVA运行库,好像需要重启的?忘记了……2.把下载回来的robocode-setup.jar复制到c盘根目录3.打开 开始菜单 的“运行”,输入 java -jar "c:\robocode-setup.jar" 进行安装4.安装完后就可以在开始菜单中找到Robocode的菜单了,来~我们进入战场咯!
安装完成后,您也可以通过 shell 脚本(robocode.sh)、批处理文件(robocode.bat)或桌面上的图标来启动 Robocode 系统。此时,战场将会出现。在此,您可以通过菜单调用 Robot Editor 和 compiler。
Robocode 系统组件当您启动 Robocode 时,将看到两个GUI窗口,这两个窗口构成了 Robocode 的 IDE:
图 1. Robocode IDE
战场是机器人之间进行战斗直至分出胜负的场地。主要的仿真引擎被置于其中,并且允许您在这里创建战斗、保存战斗以及打开新建的或现有的战斗。通过界面区域内的控件,您可以暂停或继续战斗、终止战斗、消灭任何机器人个体或获取任何机器人的统计数据。此外,您可以在此屏幕上激活 Robot Editor。
Robot Editor 是一个定制的文本编辑器,它可以用于编辑生成机器人的 Java 源文件。在它的菜单里集成了 Java 编译器(用于编译机器人代码)以及定制的 Robot 打包器。由 Robot Editor 创建并成功编译的所有机器人都会处于战场上一个部署就绪的位置。
Robocode 里的每个机器人都由一个或多个 Java 类构成。这些类可以被压缩成一个 JAR 包。为此,Robocode 的最新版本提供了一个可以在战场 GUI 窗口中激活的“Robot Packager”。
对 Robocode 机器人的详细分析在写这篇文章时,Robocode 机器人是一个图形化的坦克。图 2 是一个典型的 Robocode 机器人的图解。
图 2. 对 Robocode 机器人的详细分析
请注意,机器人有一门可以旋转的炮,炮上面的雷达也是可以旋转的。机器人坦克车(Vehicle)、炮(Gun)以及雷达(Radar)都可以单独旋转,也就是说,在任何时刻,机器人坦克车、炮以及雷达都可以转向不同的方向。缺省情况下,这些方向是一致的,都指向坦克车运动的方向。
我们先不考虑怎么编程来实现机器人战斗,我们先用自带的例子机器人来一场战斗吧
单击菜单上的Battle,然后选New,出现了New Battle对话框
图 3. New Battle 对话框
左边的框是Packages,相当于一个文件夹,里面包含多个Robots(机器人)我们选择sample这个包,里面有Corners、Crazy、Fire等等很多例子的机器人了随便选择几个你喜欢的,然后按Add添加到Selected Robots框,进了这个框就是准备要上战场的机器人了~选择好后,按 StartBattle 开战吧!
现在你已经知道怎样可以使用机器人去战斗并且也构建好你的战场了,好,下面我们学习怎样来编写属于自己的战斗机器人!!
战场是机器人之间进行战斗直至分出胜负的场地。主要的仿真引擎被置于其中,并且允许在这里创建战斗、保存战斗以及打开新建的或现有的战斗。通过界面区域内的控件,可以暂停或继续战斗、终止战斗、消灭任何机器人个体或获取任何机器人的统计数据。此外,我们可以在此屏幕上的Robot菜单打开 Editor,就是我们机器人的代码编辑器了!Robot Editor 是一个定制的文本编辑器,它可以用于编辑生成机器人的 Java 源文件。在它的菜单里集成了 Java 编译器(用于编译机器人代码)以及定制的 Robot 打包器。由 Robot Editor 创建并成功编译的所有机器人都会处于战场上一个部署就绪的位置。我们就是要在这里编写机器人了。选择“File”》“New”》“Robot”来新建一个机器人。它会首先要你输入这个机器人的名字(注意名字首字母要大写哦),然后要你输入包的名字(就是保存这个机器人的文件夹名称),这样就生成了一个蠢蠢的机器人XForce的代码了~因为我们还没替它加上人工智能,呵呵!
现在单击菜单的Complie下的Complie进行编译,保存好,我们的机器人已经生产出来咯~现在关闭Editor,在进入New Battle,Pakeage下选择你刚才的包的名字,Robot下就有了我们新建的XForce机器人了~添加进去吧,然后选择多几个其他的机器人,开始战斗!
看~我们的XForce在战斗了!
是否觉得它太蠢了点呢?来,继续来学习~~
Robocode 机器人是一个图形化的坦克,请注意,机器人有一门可以旋转的炮,炮上面的雷达也是可以旋转的。机器人坦克车(Vehicle)、炮(Gun)以及雷达(Radar)都可以单独旋转,也就是说,在任何时刻,机器人坦克车、炮以及雷达都可以转向不同的方向。缺省情况下,这些方向是一致的,都指向坦克车运动的方向。
附:Robot 命令  Robocode 机器人的命令集都收录在 Robocode API Javadoc 中。这些命令都是 robocode.Robot 类的公共方法。
(1)移动机器人、炮和雷达
  移动机器人及其装备的基本命令:
turnRight(double degree) 和 turnLeft(double degree) 使机器人转过一个指定的角度。
ahead(double distance) 和 back(double distance) 使机器人移动指定的像素点距离;这两个方法在机器人碰到墙或另外一个机器人时即告完成。
turnGunRight(double degree) 和 turnGunLeft(double degree) 使炮可以独立于坦克车的方向转动。
turnRadarRight(double degree) 和 turnRadarLeft(double degree) 使炮上面的雷达转动,转动的方向也独立于炮的方向(以及坦克车的方向)。
  这些命令都是在执行完毕后才把控制权交还给程序。此外,转动坦克车的时候,除非通过调用下列方法分别指明炮(和雷达)的方向,否则炮(和雷达)的指向也将移动。
setAdjustGunForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车转动时,炮保持原来的方向。
setAdjustRadarForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车(和炮)转动时,雷达会保持原来的方向。
setAdjustRadarForGunTurn(boolean flag):如果 flag 被设置成 true,那么炮转动时,雷达会保持原来的方向。而且,它执行的动作如同调用了 setAdjustRadarForRobotTurn(true)。
(2)获取关于机器人的信息
getX() 和 getY() 可以捕捉到机器人当前的坐标。
getHeading()、getGunHeading() 和 getRadarHeading() 可以得出坦克车、炮或雷达当前的方向,该方向是以角度表示的。
getBattleFieldWidth() 和 getBattleFieldHeight() 可以得到当前这一回合的战场尺寸。
(3)射击命令
  一旦掌握了移动机器人以及相关的武器装备的方法,我们就该考虑射击和控制损害的任务了。每个机器人在开始时都有一个缺省的“能量级别”,当它的能量级别减小到零的时候,我们就认为这个机器人已经被消灭了。射击的时候,机器人最多可以用掉三个能量单位。提供给炮弹的能量越多,对目标机器人所造成的损害也就越大。 fire(double power) 和 fireBullet(double power) 用来发射指定能量(火力)的炮弹。调用的 fireBullet() 版本返回 robocode.Bullet 对象的一个引用,该引用可以用于高级机器人。(也就是说,当你确定能击中对方,火力越大越好咯^_^)
  每当机器人在移动或转动时,雷达一直处于激活状态,如果雷达检测到有机器人在它的范围内,就会触发一个事件。作为机器人创建者,我们有权选择处理可能在战斗中发生的各类事件。基本的 Robot 类中包括了所有这些事件的缺省处理程序。但是,们可以覆盖其中任何一个“什么也不做的”缺省处理程序,然后实现自己的定制行为。下面是一些较为常用的事件:
ScannedRobotEvent。通过覆盖 onScannedRobot() 方法来处理 ScannedRobotEvent;当雷达检测到机器人时,就调用该方法。
HitByBulletEvent。通过覆盖 onHitByBullet() 方法来处理 HitByBulletEvent;当机器人被炮弹击中时,就调用该方法。
HitRobotEvent。通过覆盖 onHitRobot() 方法来处理 HitRobotEvent;当您的机器人击中另外一个机器人时,就调用该方法。
HitWallEvent。通过覆盖 onHitWall() 方法来处理 HitWallEvent;当您的机器人撞到墙时,就调用该方法。
很多研究Robocode的 玩家都被其中的方向及坐标弄糊涂了。整个屏幕哪个是0度角,整个是坐标原点呢? 顺时针与逆时针的方向如何区分?
一段英文的翻译及说明:
heading - absolute angle in degrees with 0 facing up the screen, positive clockwise. 0 &= heading & 360.
bearing - relative angle to some object from your robots heading, positive clockwise. -180 & bearing &= 180
heading:是机器人方向与屏幕正上方的角度差,方向在0到360之间.
bearing:是机器人的某个部件如雷达发现的目标与方向的角度差,顺时针为正角度在-180到180之间
几个在Robocode中很重要的概念:
坐标系:Robocode整个坐标系都是战场屏幕以左下角为原点
绝对方向系:Robocode中不管机器人在哪个方向都是以静态战场屏幕为参照的绝对角度(也即大家说的Heading),正上方为0度角。也即不管是Robot,Gun,Radar向北为0,向东为90,向南为180,向西为270。
相对方向系:相对方向是Robot,Gun,Radar以机器人的动态heading角度为参照的角度差不再以整个静态屏幕为参照了,叫它相对因为机器人的heading是随着机器人移动而不停的在改变,heaing只是个相对物体。
顺时针和逆时针是看另一机器人是在你的Heading角度的(0,180)还是(-180,0)之间。
  再次提醒:Heading是个静态角度,正上方总为0.不管是取Heading,还是取方向。Bearing是个角度差值,是由参照的Heading和发现时的Heading的差值。方向的问题就说到这,欢迎大家讨论。
我看了Robocode的基础知识,自己写了个bot,放到BattleField上却是屡战屡败……伤心ing。
  Bot对于周围环境的了解非常有限。它可以知道其它机器人的距离、方位、方向、速度和能量等级。但是,它看不到子弹。怎么才可以有效的躲避对方的子弹呢?
  Bot虽然看不到子弹,但是对方的能量等级还是可以scan到了。对方只要发射子弹就会耗损能量,并且耗损的能量介于0和3之间。根据这些线索,如何发现其它机器人正向它开炮对于“笨笨”的Bot不就易如反掌了? ^_^
  当Bot检测到对方发射子弹的信息时,向左或向右移动一小步,嘿嘿,子弹就打不到咯~并且大多数Bot的瞄准方法是要么直接向目标开炮,要么试着根据Bot的速度和方向来推算位置。如果我的Bot不移动,两种算法都会正好冲着这个Bot的当前位置开炮。哈哈哈,这时我的Bot再移动,不就全部都打不到啦。(是不是颇有武侠小说里以静制动的高手味道?^_^)
  下面是部分代码和注释:
double previousEnergy = 100;&//初始状态对方能量为100int movementDirection = 1;&//移动方向int gunDirection = 1;&//炮管方向
/*** 当检测到对方Bot,触发事件* @param e*/public void onScannedRobot(ScannedRobotEvent e) {//调整自己和对方之间的角度setTurnRight(e.getBearing()+90-30*movementDirection);
//如果对方的能量损耗一定值,进行躲避动作double changeInEnergy = previousEnergy - e.getEnergy();if (changeInEnergy&0 && changeInEnergy&=3) {//躲避!movementDirection = -movementD&//和上次的躲避方向相反setAhead((e.getDistance()/4+25)*movementDirection);}//将炮管指向对方当前位置gunDirection = -gunDsetTurnGunRight(99999*gunDirection);
//射击fire(1);
//重新设置对方能量previousEnergy = e.getEnergy();}
  是不是很简单?这个技巧还存在问题。子弹一发射,我的Bot就移动,所以它最终可能会移回炮弹轨迹之内。最好是在估计子弹要到达时再移动。
  我有个更大胆的假设:因为现在我的Bot命中率还不高,那么如果我的Bot一直不开火,只是躲避对方的子弹的话,能不能拖到对方的能量为0呢?确实存在一点问题。对方子弹一发射,我的Bot就移动,并且这个移动是规律的来回移动。如果移动距离短了,就可能在回来的时候撞到对方的子弹;如果移动距离长了,就等于做一个直线运动,对方很容易计算得到Bot的运动轨迹。还有一个问题,躲避的时候很有可能撞到墙上……(撞墙是要减energy的:~()
  针对以上的问题,我另写了一个Bot。代码如下:
import robocode.*;
public class HanicBot extends AdvancedRobot{private double eD //对方的距离 //移动的距离private double radarMove = 45; //雷达移动的角度private double dFireP //火力
/*** main func run()*/public void run() {eDist = 300;while(true){//每过一个周期,运动随机的距离double period = 4*((int)(eDist/80)); //周期;敌人越接近,周期越短,移动越频繁//周期开始,则移动if(getTime()%period == 0){move = (Math.random()*2-1)*(period*8 - 25);setAhead(move + ((move &= 0) ? 25: -25));}//避免撞墙double heading = getHeadingRadians(); //取得bot方向的弧度数double x = getX() + move*Math.sin(heading); //移动move后将要达到的x坐标double y = getY() + move*Math.cos(heading); //移动move后将要达到的y坐标double dWidth = getBattleFieldWidth(); //战场的宽度double dHeight = getBattleFieldHeight(); //战场的长度//当(x,y)超过指定的范围,则反向移动moveif(x & 30 || x & dWidth-30 || y & 30 || y & dHeight-30){setBack(move);}turnRadarLeft(radarMove); //转动雷达}}//end run()
/*** 当检测到对方Bot,触发事件* @param e*/public void onScannedRobot(ScannedRobotEvent e) {eDist = e.getDistance(); //取得对方距离radarMove = -radarM //设置雷达double eBearing = e.getBearingRadians(); //取得和对方相对角度的弧度数//将bot转动相对的角度,以后bot的运动将是以对方为圆心的圆周运动setTurnLeftRadians(Math.PI/2 - eBearing);//转动炮管指向对方setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(getHeadingRadians() + eBearing - getGunHeadingRadians()));//根据对方距离射击dFirePower = 400/eDif (dFirePower & 3){dFirePower = 3;}fire(dFirePower);}}
  首先,为了迷惑对方,不让对方容易的得到Bot的移动规律,Bot就要在一定的时间内做出随机的运动,这个很容易办到。并且,我给Bot的运动改变时间规定了周期。这个周期随离对方的距离改变,敌人越接近,周期越短,移动越频繁。
double period = 4*((int)(eDist/80));if(getTime()%period == 0){move = (Math.random()*2-1)*(period*8 - 25);setAhead(move + ((move &= 0) ? 25: -25));}
  其次,Bot的运动不是呈直线的。而是以对方为圆心的圆周运动。
setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(getHeadingRadians() + eBearing - getGunHeadingRadians()));
  最后是如何避免撞墙。这里要用到点三角函数-_-!! 原理就是,计算Bot一次运动后将要达到的坐标是不是位于规定的危险区域。如果是,则立即反方向运动。
double heading = getHeadingRadians();double x = getX() + move*Math.sin(heading);double y = getY() + move*Math.cos(heading);double dWidth = getBattleFieldWidth();double dHeight = getBattleFieldHeight();if(x & 30 || x & dWidth-30 || y & 30 || y & dHeight-30){setBack(move);}
这个Bot的威力如何?呵呵,我去测试一下先~
好了,就说到这里了,欢迎各大高手来踩……
关于其它的一些"编程游戏"&有许多软件是基于这种思想的,Robocode它自己就是来源于机器人大战Robot Battle()这款软件。其它的编程游戏还包括:&· AI Fleet Commander&· AI Wars&· AT-Robots&· Bolo&· BotWarz&· C-Robots&· Cadaver&· CodedWombat&· Colobot&· Corewars&· CybWar&· GRobots&· DroidBattles&· Karel the Robot&· Mindrover&· IntelliBots&· Omega&· RealTimeBattle&· Robot Wars&· RoboWar&· SRobots&· VBRobots&就我所看过的"编程游戏",Robocode是最简单上手的。
· 它非常容易上手,是特别为教学而设计的&· 它具有平滑且吸引人的图形&· 它完全地将编辑器,编译器和运行环境集成在了一起。&· 它是由JAVA编写的,且JAVA非常适合当作初学语言
喜欢该文的人也喜欢

我要回帖

更多关于 手机游戏键盘怎么设置中文 的文章

 

随机推荐