0

I'm trying to make a pong game, but the movement is clunky; there is a slight delay whenever I hold down a key to make a paddle move.

For example, I'll hold a key, the paddle will move once, and then it will take a second before it begins moving again continuously.

I'm told that this is a feature of the OS, not of Java; however, I would still like to find a workaround in Java so that the movement is smooth and continuous from the beginning, without having to wait for the OS to begin autopressing the key.

Can someone help? (I've tried booleans and keylisteners and "while" loops, but these did not work for me. A passage taken from one of these failed attempts is written below:)

root.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            switch (event.getCode()) {
                case UP:    paddle1Up = true; 
                            break;
                case DOWN:  paddle1Down = true; 
                            break;

                case W:  paddle2Up  = true; 
                            break;
                case S: paddle2Down  = true; 
                            break;
            }
        }
    });

    root.setOnKeyReleased(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            switch (event.getCode()) {
                case UP:    paddle1Up = false; 
                            break;
                case DOWN:  paddle1Down = false; 
                            break;

                case W:  paddle2Up  = false; 
                            break;
                case S: paddle2Down  = false; 
                            break;
            }
        }
    });

    root.requestFocus(); 

    primaryStage.setTitle("Pong");
    primaryStage.setScene(scene);
    primaryStage.setOnCloseRequest((event)->System.exit(0));
    primaryStage.show();

    // This is the main animation thread
    new Thread(() -> {
        while (true) {
            sim.evolve(1.0);
            while (paddle1Up){
                sim.movePaddle(sim.getPaddle1(), 0, -1);
            }
            while (paddle1Down){
                sim.movePaddle(sim.getPaddle1(), 0, 1);
            }
            while (paddle2Up){
                sim.movePaddle(sim.getPaddle2(), 0, -1);
            }
            while (paddle2Down){
                sim.movePaddle(sim.getPaddle2(), 0, 1);
            }

            Platform.runLater(()->sim.updateShapes());
            try {
                Thread.sleep(25);
            } catch (InterruptedException ex) {

            }
        }
    }).start();
}
Asker
  • 1,299
  • 2
  • 14
  • 31
  • 1
    You could consider not resetting the value on the keyup-event. Now this would lead to an extremely fast movement to the bottom. To circumvent this calculate the timedifference since the last call of the while-loop and multiply that with the speed you wish to use. – Gildraths Nov 09 '16 at 18:06
  • Thanks, but can you also explain how this timedifference can be calculated? I'm not sure I see what is meant here. – Asker Nov 09 '16 at 18:25
  • 1
    Simply save System.currentTimeMillis() of the last loop and substract it from the current one. With this you have the milliseconds since the last loop. Now you can simply calculate how far the "bar" should move with your speed. Basically timedifference/1000*(speedInCMperSec) – Gildraths Nov 09 '16 at 18:46
  • Ah, I see. Thanks! But, another question: going back to the original comment, the suggestion was to not reset the value on the keyup event. What is the purpose of this? Wouldn't this mean that it would be impossible for the paddle to stay still? – Asker Nov 11 '16 at 02:08
  • Ah yes that's true, it would be better if you set your speed to zero on the keyup-event. Then it should work like intended – Gildraths Nov 11 '16 at 17:41

1 Answers1

1

Pretty sure you need to write

case KeyEvent.VK_UP:

Unless you extend the KeyEvent class, of course.

Also I don't think it's necessary to have a while loop in your while loop, instead stick with if statements:

        while (true) {
        sim.evolve(1.0);
        if (! paddle1Up){
            sim.movePaddle(sim.getPaddle1(), 0, -1);
        }

Not sure if intentional either, notice the ! in the if statement (your while loop).

I have seen numerous similar cases before like this. And I've also experienced it once, though I am unsure of the cause. Now it's hard to say without seeing more of your code, but I strongly recommend implements the keylistener and using the methods there, quite similar to your code, it should hopefully work without problem. You might already read this post or this post, if not perhaps it will help.

Hope it works out for you.

Community
  • 1
  • 1
  • Yes, the "!" in the if statement was a typo. Fixed it now. Thanks for the help! Will look into this more later. – Asker Nov 09 '16 at 18:24