Search code examples
java2d-games

Fire Rate Issue in Java 2D Gaming


I am creating a 2D tank game and I want my tank to be able to shoot immediately once the fire button is pressed and then again every half second, while the fire button is held. Currently In my game, my first bullet shoots immediately after the fire button is pressed, then there is a delay (I presume half second) until my tank starts shooting a stream of bullets. I'm wondering why the initial delay after the first bullet works, but the successive ones fail. Below I have included the method which creates bullets which is called every frame in my 144Hz main game loop:

public void addBullets(ArrayList<Animate> animates, ArrayList<Drawable> drawables){
    if (this.ShootPressed) {
        if( firstShot || (System.currentTimeMillis() - timeSinceLastShot) >= 500) {
            Bullet newBullet = this.addBullet();
            animates.add(newBullet);
            drawables.add(newBullet);
            firstShot = false;
            timeSinceLastShot = System.currentTimeMillis();
        }
    }
} 

Here are the associated methods in my KeyListener class:

public void keyPressed(KeyEvent key) {
    int keyPressed = key.getKeyCode();
    if (keyPressed == up) {
        this.t1.toggleUpPressed();
    }
    if (keyPressed == down) {
        this.t1.toggleDownPressed();
    }
    if (keyPressed == left) {
        this.t1.toggleLeftPressed();
    }
    if (keyPressed == right) {
        this.t1.toggleRightPressed();
    }
    if(keyPressed == shoot) {
        this.t1.toggleShootPressed();
        this.t1.setFirstShot(true);
    }

I am including this for additional information even though the bug happens before the key is released:

public void keyReleased(KeyEvent ke) {
    int keyReleased = ke.getKeyCode();
    if (keyReleased  == up) {
        this.t1.unToggleUpPressed();
    }
    if (keyReleased == down) {
        this.t1.unToggleDownPressed();
    }
    if (keyReleased  == left) {
        this.t1.unToggleLeftPressed();
    }
    if (keyReleased  == right) {
        this.t1.unToggleRightPressed();
    }
    if (keyReleased  == shoot) {
        this.t1.unToggleShootPressed();
    }

}

Solution

  • I suspect it's an issue with key-repeats which will repeatedly call KeyPressed while the key is held. It is usually setup to behave as you describe. Consequently, "firstShot" will be repeatedly set to true and a shot will be fired.

    I advise restricting your event code, mainly as it's continuous in nature, to only toggling actions, rather than performing any logic. You can determine whether a shot is first or not in your game loop, with the help of some messages from your events.

    However, the firstShot variable is not really necessary at all as the time delta will account for it. Removing it would also prevent firing faster than every 500ms by pressing the fire key rapidly, which you may or may not want.