理解Robocode的规则系统,你才能写出更好的坦克。许多规则在Robotcode的Roles类中进行了描述。为了便于大家理解,本文对各种规则参数进行详细叙述。
时间
robocode的时间单位为”轮”(turn)。因此,在描述移动速度时,单位为”像素每轮”(pixels/turn)。“轮”是独立于真实时间的抽象时间单位。游戏速度越快,单位时间内执行的轮数就越多。
在Robocode提供的类中,许多类都提供了getTime()方法。该方法返回从该局开始到现在或事件发生时的轮数。如在我们自己写的坦克类中,我们可以通过this.getTime()取得代码执行到该行时的时间。又如,在雷达扫描到目标事件发生时,会调用方法:
onScannedRobot(ScannedRobotEvent event)
该方法的参数event代表了扫描到目标事件。因此我们可以使用event.getTime()获得事件发生的时间。
移动速度和加速度
在robocode中,坦克不会是匀速移动的!因为在robocode中,有加速度的概念。总的来说,坦克的移动速度介于0-8之间。robocode会自动管理速度。例如:坦克从一点移动到另一点的过程一般是: 开始移动-加速-减速-停止。我们可以通过Robot.getVelocity()方法取得坦克当前移动速度。
除了坦克有移动速度外,子弹也有移动速度,只不过子弹的移动速度是匀速的。在Robot类中,有两个用于射击的方法:
void fire(double power) //以指定的能量开火
Bullet fireBullet(double power) //以制定的能量开火,并返回子弹对象
这里要说的是,开火时的能量越高,子弹移动速度越快。Robocode API中提供了一个Rules类,这里面包含了许多常量以及一些静态方法。 我们可以使用Rules.getBulletSpeed(double bulletPower)根据能量计算子弹速度。
方向及转向
Robocode中,”朝向”是一个绝对概念,就像我们现实生活中的“东南西北一样”。在Robot类中,提供了获得Body、Gun、Radar朝向的方法:
getHeading() //取得Body朝向
getGunHeading() //取得Gun朝向
getRadarheading() //取得Radar朝向
在本系类的第一节我们就介绍了坦克的转向方法,现将与转向相关的API截图如下:
如果你想做一个“见着就打”的坦克,实际上再简单不过:
首先,在run方法的循环中,只写一行语句: turnGunLeft(20), 这样你的坦克就会不停地旋转炮塔,而雷达会随着炮塔的旋转一同旋转,一旦目标处于雷达正前方,onScannedRobot方法会被触发。在onScannedRobot方法中,你只需要this.fire(1) 就可以了。不过,这样的坦克在战场上生存能力是很有限的,因为:
1. 该坦克不移动,会成为“活靶子”
2. 该坦克无法命中移动目标,除非瞎猫碰着死耗子
对于车身来说,转向的速度不总是相同的,这跟坦克当前速度有关,速度越快,转向越慢(跟我们开车一样,当过弯的时候,需要减速)。车身的转向速度最快为10度/turn。
对于炮塔和雷达,转向速度是固定的,分别为:20度/turn 和 45度/turn。
能量、生命、GunHeat
在我玩的这个Robocode版本中,已经废除了生命的概念。此版本的规则是: 开炮和被对手击中需要耗费能量,击中对手会获得能量,当能量耗尽时,坦克就死了。
开炮的能量为0-3之间的double值。开炮能量越大,GunHeat越大,GunHeat需要一段时间才能冷却,冷却后,我们才能再次开炮。因此,开炮的能量越大,开炮的威力越大,开炮间隔越长。反之亦然。
下面列出一些规则公式:
- 每次击中回复能量: 3*firepower
- 火炮过热(gunHeat) : 1 + firepower/5 ;
- 如果火炮过热(gunHeat>0)则不能开炮。
- 在游戏开始时所有的坦克都是过热的。
- 给对手造成伤害: 4*firepower
- 附加伤害: 如果firepower>1 ,附加伤害=2*(power-1)
- 能量补充: 当你击中对手,你会获得3 * power能量补充
碰撞
碰撞到别的坦克,或者碰撞到边界,都会使自己的速度立减为零,而且会有不同程度的伤害。
碰撞: 双方0.6伤害.
撞墙: 1.2伤害