I'm making simple space craft game. I have a player (space ship) that fires rockets. When the space button is pressed the player launches a rocket. The problem is that when I hold "space", rockets are launched continuously. How can I prevent this effect and make pressing the space button detected only every 2 seconds, for example (and launch only one rocket)?
-
So you want fire every n seconds while spacebard is pressed down or you want to fire single rocket on every spacebar press ? – Antoniossss Feb 06 '17 at 11:21
-
I want to disable space bar for 2 seconds every time the ship fires. – user7470489 Feb 06 '17 at 11:22
-
@JonK although the concept is similar, this is a question in JavaFX, not Swing. I'm don't think it's fair to not give JavaFX a chance to do it in other ways. – user1803551 Feb 06 '17 at 12:36
-
@user1803551 How is it different? – James_D Feb 06 '17 at 13:15
-
@James_D JavaFX has other ways to do this which are not applicable to Swing, and vice versa. The answers can be different. I was about to post a JavaFX-only answer which does not fit the other question. – user1803551 Feb 06 '17 at 13:19
-
Did any of the answers solve your problem? – user1803551 Feb 21 '17 at 00:02
3 Answers
You possibly could try to create a list where pressed keys gonna be stored. After pressing the button listener will add that button to list, and will start to count time of pressure. Not sure if is this the best way, but I know, that the same procedure used when developer want to handle few pressed key at once.

- 1
- 2
You can store in your Ship
class whether it is ready to fire a rocket and then in the method which fires the rocket, check for this member.
On rocket launch set this member to false and then you can start a Timeline
for example which will reset the flag as it finishes.
Ship class
public class Ship {
private boolean readyToFireRocket = true;
private static final double ROCKET_LAUNCHING_DELAY = 2d;
public void fireRocket() {
if(readyToFireRocket) {
readyToFireRocket = false;
System.out.println("Rocket is fired");
KeyFrame keyFrame = new KeyFrame(Duration.seconds(ROCKET_LAUNCHING_DELAY),
e -> readyToFireRocket = true);
Timeline reloadRockets = new Timeline(keyFrame);
reloadRockets .play();
}
}
}
An example Application
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = new BorderPane();
Ship ship = new Ship();
Scene scene = new Scene(root, 300, 275);
scene.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.SPACE) {
ship.fireRocket();
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

- 21,311
- 6
- 55
- 60
One option is to deregister the event handler for a duration of 2 seconds whenever it is used (and re-register it at the end of the duration). I assume that you are using a setOnKeyPressed(e -> ...)
to register the handler that reacts to pressing space.
- Create and hold a reference to that handler so you can register and deregister it at will.
- Create a
PauseTransition
with a delay of 2 seconds that registers the above handler when it's done (doing nothing). - In the
handle()
method, deregister the handler and start the transition.
Here is an example:
public class FXExmple extends Application{
private Button button = new Button("PRESS SPACE");
private PauseTransition pt = new PauseTransition(Duration.seconds(2));
@Override
public void start(Stage stage) throws Exception {
MyEventHandler eh = new MyEventHandler();
pt.setOnFinished(e -> button.setOnKeyPressed(eh));
button.setOnKeyPressed(eh);
Pane pane = new Pane();
pane.getChildren().add(button);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
private class MyEventHandler implements EventHandler<KeyEvent> {
@Override
public void handle(KeyEvent event) {
System.out.println("FIRED");
button.setOnKeyPressed(null);
pt.play();
}
}
public static void main(String[] args) {
launch(args);
}
}
Note that this won't give you fine control over the duration since there is duration associated with (de)registering the handler and starting the transition, but they are very small. There is also a limit for the frequency in which the OS sends the events, so if you are planning to go down to ~50ms delays - beware.

- 12,965
- 5
- 47
- 74