Java 让键盘控制在我的乒乓球游戏中发挥作用

Java 让键盘控制在我的乒乓球游戏中发挥作用,java,javafx,user-controls,scenebuilder,pong,Java,Javafx,User Controls,Scenebuilder,Pong,我的问题是如何修复代码,使应用程序在运行时能够接受键盘输入。现在,我确实有了所需的大部分代码,但我不确定我缺少了什么来让它工作 现在请注意,这个程序是使用EclipseLuna(最新版本)和JavaFX制作的,JavaFX使用Scenebuilder来构建GUI,因此请确保解决方案的所有内容都能考虑到这些方面 现在是我的代码。当然,只要你们能解释一下我的代码,你们就可以把我的代码重新编译并进行修改。仅仅拥有一个或另一个并不像拥有两个一样有效 我的PongController班,所有东西都是在那里

我的问题是如何修复代码,使应用程序在运行时能够接受键盘输入。现在,我确实有了所需的大部分代码,但我不确定我缺少了什么来让它工作

现在请注意,这个程序是使用EclipseLuna(最新版本)和JavaFX制作的,JavaFX使用Scenebuilder来构建GUI,因此请确保解决方案的所有内容都能考虑到这些方面

现在是我的代码。当然,只要你们能解释一下我的代码,你们就可以把我的代码重新编译并进行修改。仅仅拥有一个或另一个并不像拥有两个一样有效

我的PongController班,所有东西都是在那里制作的

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import java.util.Random;

public class PongController {

final int PADDLE_MOVEMENT_INCREMENT = 7;
final int BALL_MOVEMENT_INCREMENT = 3;

double centerTableY;

DoubleProperty currentUserPaddleY = new SimpleDoubleProperty();
DoubleProperty currentComputerPaddleY = new SimpleDoubleProperty();
double initialComputerPaddleY;

DoubleProperty ballCenterX = new SimpleDoubleProperty();
DoubleProperty ballCenterY = new SimpleDoubleProperty();

double allowedPaddleTopY;
double allowedPaddleBottomY;

Timeline timeline;

@FXML
Rectangle table;
@FXML  
Rectangle compPaddle;
@FXML  
Rectangle userPaddle;
@FXML  
Circle ball;

public void initialize() {

    currentUserPaddleY.set(userPaddle.getLayoutY());
    userPaddle.layoutYProperty().bind(currentUserPaddleY);

    ballCenterX.set(ball.getCenterX());
    ballCenterY.set(ball.getCenterY());

    ball.centerXProperty().bind(ballCenterX);
    ball.centerYProperty().bind(ballCenterY);


    initialComputerPaddleY = compPaddle.getLayoutY();
    currentComputerPaddleY.set(initialComputerPaddleY);
    compPaddle.layoutYProperty().bind(currentComputerPaddleY);


    allowedPaddleTopY = PADDLE_MOVEMENT_INCREMENT;
    allowedPaddleBottomY = table.getHeight() - userPaddle.getHeight() - PADDLE_MOVEMENT_INCREMENT;

    centerTableY = table.getHeight()/2;
 }

public void keyReleasedHandler(KeyEvent event){

    KeyCode keyCode = event.getCode();

    switch (keyCode){
        case UP:
            process_key_Up();
            break;
        case DOWN:
            process_key_Down();
            break;
        case S:
            process_key_S();
            break;
    default:
        break;
    }
}


private void process_key_Up() {

    if (currentUserPaddleY.get() > allowedPaddleTopY) {
        currentUserPaddleY.set(currentUserPaddleY.get() - PADDLE_MOVEMENT_INCREMENT);
    }
}

private void process_key_Down() {

    if (currentUserPaddleY.get()< allowedPaddleBottomY) {
        currentUserPaddleY.set(currentUserPaddleY.get() + PADDLE_MOVEMENT_INCREMENT);
    }
}

private void process_key_S() {
    ballCenterY.set(currentUserPaddleY.doubleValue() + userPaddle.getHeight()/2);
    ballCenterX.set(userPaddle.getLayoutX());
    moveTheBall();
}

private void moveTheBall(){

    Random randomYGenerator = new Random();
    double randomYincrement = randomYGenerator.nextInt(BALL_MOVEMENT_INCREMENT);

    final boolean isServingFromTop = (ballCenterY.get() <= centerTableY)?true:false;

    KeyFrame keyFrame = new KeyFrame(new Duration(10), event -> {
        if (ballCenterX.get() >= -20) {
            ballCenterX.set(ballCenterX.get() - BALL_MOVEMENT_INCREMENT);

            if (isServingFromTop) {
                ballCenterY.set(ballCenterY.get() + randomYincrement);
                currentComputerPaddleY.set( currentComputerPaddleY.get() + 1);

            } 

            else {
                ballCenterY.set(ballCenterY.get() - randomYincrement);

                currentComputerPaddleY.set(currentComputerPaddleY.get() - 1);
            }

            if(checkForBallPaddleContact(compPaddle)){
                timeline.stop();
                currentComputerPaddleY.set(initialComputerPaddleY);
                bounceTheBall();
            };

         } 
        else {
            timeline.stop();
            currentComputerPaddleY.set(initialComputerPaddleY);
         }
        updateScore();
     });

    timeline = new Timeline(keyFrame);
    timeline.setCycleCount(Timeline.INDEFINITE);

    timeline.play();
 }


 private boolean checkForBallPaddleContact(Rectangle paddle){
     if (ball.intersects(paddle.getBoundsInParent())){
         return true;
     } else {
          return false;
     }
 }

 private void bounceTheBall() {
     double theBallOffTheTableX = table.getWidth() + 20;

     KeyFrame keyFrame = new KeyFrame(new Duration(10), event -> {

         if (ballCenterX.get() < theBallOffTheTableX) {
             ballCenterX.set(ballCenterX.get() + BALL_MOVEMENT_INCREMENT);
             if (checkForBallPaddleContact(userPaddle)){
                 timeline.stop();
                 moveTheBall();
             };

         } 
         else {
             timeline.stop();
         }
         updateScore();
     });

     timeline = new Timeline(keyFrame);
     timeline.setCycleCount(Timeline.INDEFINITE);

     timeline.play();
   }

 private void updateScore(){
     int computerScore = 0;
     int userScore = 0;
      if (ballCenterX.get() > table.getWidth()){
          // Computer bounced the ball and the User didn't hit it back
          computerScore ++;
      } else if (ballCenterY.get() > 0 && ballCenterY.get() <= table.getHeight()){
          // The User served the ball and Computer didn't hit it back
          userScore++;
      } else{
          // The User served the ball off the table
          computerScore++;
      }


      System.out.println("Computer: " + computerScore + ", User: " + userScore);
    }
}

我只想提前说声谢谢,这是我第一次使用这个网站,尽管我以前使用这个网站来获取想法。

欢迎使用Stack。这里的大多数人都直截了当,没有太多的玩笑,所以不要觉得我们太苛刻了。“确保解决方案的所有内容都考虑到这些方面”——“当然,只要你能在代码旁边解释,就用我的代码和更正重新编写代码吧。只有一个或另一个不会像两个都有那么有效。”你问得太多了,但是没有描述你真正想要什么(除了一个非常简短的部分句子)。你需要什么?你试过了吗?会发生什么?应该怎么做?这一点实际上是你的工作:“我确实拥有所需的大部分代码,但我不确定我缺少什么才能让它正常工作。”你需要找到代码中给你带来问题的部分,然后具体询问这个问题。这超出了这个网站的范围,简单地转储你的代码,并期望一些没有报酬的陌生人花时间了解整个事情,然后筛选它,找到每一个问题,并为你解决。我想知道的是,我需要在我的代码中实现什么,无论是在我的主控制器中还是在我的控制器中,因此,我不需要在运行PongMain类之后打开窗口,只需要在Scenebuilder中放置元素,我需要知道如何合并我的键代码,以便在运行程序时,我可以按“S”键发球,上下移动我的球拍,这是我无法理解的。我不知道在这两个类中键入什么才能使其正常工作。
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.fxml.FXMLLoader;

public class PongMain extends Application {

@Override
public void start(Stage primaryStage) {
    try {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(PongMain.class.getResource("GUI.fxml"));
        Group root = (Group) loader.load();
        Scene scene = new Scene(root,400,250);

        primaryStage.setScene(scene);
        primaryStage.show();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

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