我开始使用Java制作游戏。我目前正在研究一个基本敌人,该敌人会在远距离内射击,当它射击时,我希望它等待x秒并以y的速度发射3枚子弹。
因此,我决定使用计时器来创建此延迟:
public class DelayFire
{
Toolkit toolkit;
Timer timer;
//The enemy firing
Enemy com;
public DelayFire(double seconds, Enemy e, boolean un)
{
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
com = e;
timer.schedule(new FireTask(un), (int) seconds * 1000);
}
class FireTask extends TimerTask
{
public boolean unfire = false;
public FireTask (boolean x)
{
this.unfire = x;
}
public void run()
{
if(com.health>0)
{
com.charging = false;
com.fire();
if(unfire==true)
{
com.fire = false;
com.canFire = true;
}
this.cancel();
}
}
}
}
然后我在敌人类中将其称为3次,每次延迟不同:
void spray()
{
new DelayFire(2.0,this,false);
new DelayFire(2.5,this,false);
new DelayFire(3.0,this,true);
}
每当玩家处于射击范围内时,都会调用此空洞(这也属于敌人类别):
if(canFire==true && fire==false)
{
spray();
canFire = false;
fire = true;
}
然而,经过所有这些工作,一旦我进入射程,它只会产生两发子弹。直到我离开并再次进入敌人的视线。
注意:我只将代码的某些部分放在可能会出错的地方。让我知道是否需要查看更多代码。
最佳答案
您确定要发射两发子弹吗?您可以尝试在System.out.println("Hello, Bullet World!")
的run()
方法中插入FireTask
。您可能会惊讶地发现该行将打印三遍。
您正在体验的是演员阵容的关联性。考虑一下代码的这一部分:
(int) seconds * 1000
由于
seconds
是双精度型,并且您想要一个int(或者可能是一个长整数),所以自然要对它进行强制转换。但是,强制转换不会将整个表达式seconds * 1000
强制转换为int-只是seconds
。接下来,考虑您对DelayFire
类的实例化:new DelayFire(2.0,this,false);
new DelayFire(2.5,this,false);
new DelayFire(3.0,this,true);
在这里,使用双精度值
2.0
,2.5
和3.0
。但是,2.5
在乘法之前被强制转换为int,导致其变为平坦的2
。因此,您的程序将安排2秒钟后发射两枚子弹,并在3秒钟后发射一枚子弹。要解决此问题,请在整个表达式周围加上一些括号并加上乘法:
(int) (seconds * 1000)
这应该导致正确的行为。但是,您的代码中可能还有其他错误。但是先尝试一下。
编辑:作为旁注,您的
if
语句中的条件过于复杂。您基本上是通过编写if (unfire == true)
将布尔值表达式转换为另一个布尔值表达式。由于unfire
是布尔表达式,因此不需要==
运算符。您可以简单地编写if (unfire)
。而不是检查值是否为false,而使用一元!
运算符对表达式if (!unfire)
求反。