Java Timer无法正常工作。一次呼叫多个计时器

时间:2014-03-18 01:35:04

标签: java timer timertask

我开始使用Java制作游戏。我目前正在研究一个基本的敌人,它将在射程内发射,当它发射时,我希望它等待x秒并以y的速率发射3发子弹。

所以我决定使用Timer来创建这个延迟:

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();
            }
        }
    }
}

然后我在Enemy课程中称它为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;
}

然而,在完成所有这项工作之后,只有在我的范围内,它才会产生两颗子弹。直到我离开并再次重新进入敌人的视线。

注意:我只将我的代码部分放在我希望会出现错误的地方。如果您需要查看更多代码,请与我们联系。

1 个答案:

答案 0 :(得分:0)

你绝对确定只发射了两颗子弹吗?您可以尝试在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.02.53.0。但是,2.5在乘法之前被转换为int,导致它变为平坦2。因此,您的程序将安排两个子弹在2秒后触发,一个子弹在3秒后触发。

要解决这个问题,请在整个表达式周围加上一些括号,并加上乘法:

(int) (seconds * 1000)

这应该会导致正确的行为。但是,您的代码中可能还有其他错误。但先尝试一下。

修改:作为旁注,if - 语句中的条件过于复杂。您基本上是通过编写if (unfire == true)将布尔值表达式转换为另一个布尔值表达式。由于unfire 布尔表达式,因此不需要==运算符。您只需撰写if (unfire)即可。而不是检查值是否为false,使用一元! - 运算符否定表达式if (!unfire)