Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
501 views
in Technique[技术] by (71.8m points)

java - JavaFX key interruptions?

I'm trying to write a game in JavaFX but I'm having a slight issue with it and that's the key listeners getting interrupted by other key presses. I'm using scene.setOnKeyPressed(KeyEvent) and it works. When the player holds down a key they move continuously but if they hit another key it forgets about the first key even if they let go of the second key. I'm trying to figure out how to allow them to do one action and then when the key they were holding is released if they're still holding the other one go back to that.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is similar to this question, though the requirements look slightly different. Similar techniques work, but if you just want to respond to the most-recently-pressed key, you probably need some kind of stack.

This example allows you to move a rectangle around the screen, with the up, down, left, or right cursor keys; only the most recently pressed key that is still down is used.

import java.util.LinkedList;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class KeyStackExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        Rectangle rect = new Rectangle(50, 50, 100, 50);
        rect.setFill(Color.SALMON);

        Pane pane = new Pane(rect);
        Scene scene = new Scene(pane, 800, 600);

        final double rectangleHSpeed = 100 ; // pixels per second
        final double rectangleVSpeed = 100 ;
        final double minX = 0 ;
        final double maxX = 800 ; 
        final double minY = 0 ;
        final double maxY = 600 ;

        final LinkedList<KeyCode> keyStack = new LinkedList<>();
        scene.setOnKeyPressed(event -> {
            KeyCode code = event.getCode();
            if (! keyStack.contains(code)) {
                keyStack.push(code); 
            }
        });

        scene.setOnKeyReleased(event -> 
            keyStack.remove(event.getCode()));


        final LongProperty lastUpdateTime = new SimpleLongProperty();
        final AnimationTimer rectangleAnimation = new AnimationTimer() {
          @Override
          public void handle(long timestamp) {
            if (! keyStack.isEmpty() && lastUpdateTime.get() > 0) {
              final double elapsedSeconds = (timestamp - lastUpdateTime.get()) / 1_000_000_000.0 ;
              double deltaX = 0 ;
              double deltaY = 0 ;
              switch(keyStack.peek()) {
              case UP:
                  deltaY = -rectangleVSpeed * elapsedSeconds;
                  break ;
              case DOWN: 
                  deltaY = rectangleVSpeed * elapsedSeconds ;
                  break ;
              case LEFT:
                  deltaX = -rectangleHSpeed * elapsedSeconds ;
                  break ;
              case RIGHT:
                  deltaX = rectangleHSpeed * elapsedSeconds ;
              default:
                  break ;
              }
              double oldX = rect.getTranslateX() ;
              double oldY = rect.getTranslateY() ;
              rect.setTranslateX(clamp(oldX + deltaX, minX, maxX));
              rect.setTranslateY(clamp(oldY + deltaY, minY, maxY));
            }
            lastUpdateTime.set(timestamp);
          }
        };
        rectangleAnimation.start();

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private double clamp(double value, double min, double max) {
        return Math.max(min, Math.min(max, value));
    }

    public static void main(String[] args) {
        launch(args);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...