我对编程很新,而且我一直在使用JavaFX进行双人Pong游戏。一名玩家使用W / S移动他的"桨#34;而其他玩家使用向上/向下箭头。我一直存在的问题是只有一名球员可以一次移动他的球拍。我无法弄清楚如何获得它,以便他们可以同时移动他们的单个拨片。我有一个键盘事件处理程序控制两个拨片,我认为这是问题。我制作了两个单独的键盘处理程序,但是我认为是由内置的setFocusTraversable方法引起的另一组问题。我希望我尝试做的事情有道理。有什么想法吗?
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
public class Game{
Rectangle leftPaddle;
double leftPaddleY = 260;
Rectangle rightPaddle;
double rightPaddleY = 260;
public void createGame(Group gameDisplay){
//creates background
Rectangle background = new Rectangle(0,0,800,600);
background.getStyleClass().add("background");
//draws field lines
Canvas game = new Canvas(800, 600);
GraphicsContext gc = game.getGraphicsContext2D();
gc.setStroke(Paint.valueOf("WHITE"));
gc.setLineWidth(5);
gc.strokeLine(400, 0, 400, 600);
gc.strokeOval(300, 200, 200, 200);
gc.strokeRect(0, 150, 100, 300);
gc.strokeRect(700, 150, 100, 300);
gc.setStroke(Paint.valueOf("BLACK"));
gc.setLineWidth(8);
gc.strokeRect(0, 0, 800, 600);
//creates red paddle
leftPaddle = new Rectangle(30, leftPaddleY, 20, 70);
leftPaddle.setOnKeyPressed(paddleMovement);
leftPaddle.setFocusTraversable(true);
leftPaddle.setFill(Color.RED);
//creates blue paddle
rightPaddle = new Rectangle(750, rightPaddleY, 20, 70);
rightPaddle.setOnKeyPressed(paddleMovement);
rightPaddle.setFocusTraversable(true);
rightPaddle.setFill(Color.BLUE);
gameDisplay.getStylesheets().add(getClass().getResource("GameDisplay.css").toExternalForm());
gameDisplay.getChildren().addAll(background, game, leftPaddle, rightPaddle);
}
public EventHandler<KeyEvent> paddleMovement = new EventHandler<KeyEvent>(){
@Override
public void handle(KeyEvent event) {
//red paddle movement
if(event.getCode().equals(KeyCode.W)){
leftPaddle.setY(leftPaddleY -= 6);
if(leftPaddle.getY() < 0){
leftPaddle.setY(0);
leftPaddleY = 0;
}
}
if(event.getCode().equals(KeyCode.S)){
leftPaddle.setY(leftPaddleY += 6);
if(leftPaddle.getY() < 0){
leftPaddle.setY(0);
leftPaddleY = 0;
}
}
//blue paddle movement
if(event.getCode().equals(KeyCode.UP)){
rightPaddle.setY(rightPaddleY -= 6);
if(rightPaddle.getY() < 0){
rightPaddle.setY(0);
rightPaddleY = 0;
}
}
if(event.getCode().equals(KeyCode.DOWN)){
rightPaddle.setY(rightPaddleY += 6);
if(rightPaddle.getY() < 0){
rightPaddle.setY(0);
rightPaddleY = 0;
}
}
}
};
}
答案 0 :(得分:2)
只有在按下最后一个键时才会重复触发keyPressed
事件。
要解决这个问题,请记住&#34;每个拨片的所需移动并听取keyReleased
事件。您可以使用AnimationTimer
执行移动以每帧执行更新(您也可以使用Timeline
来更好地控制更新的频率。)
此外,我建议对成员变量的可见性进行更严格的限制,因为通常您不希望其他类能够直接写入您的类的字段。另外,我建议在单个Node
中处理事件。一次只有一个Node
可以拥有焦点,并且在不同的地方处理事件只会导致代码重复。
public class Game {
private Rectangle leftPaddle;
private double leftPaddleY = 260;
private Rectangle rightPaddle;
private double rightPaddleY = 260;
private double leftPaddleDY;
private double rightPaddleDY;
private AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
// update paddle positions
leftPaddleY += leftPaddleDY;
rightPaddleY += rightPaddleDY;
if (leftPaddleY < 0) {
leftPaddleY = 0;
}
if (rightPaddleY < 0) {
rightPaddleY = 0;
}
leftPaddle.setY(leftPaddleY);
rightPaddle.setY(rightPaddleY);
}
};
public void createGame(Group gameDisplay) {
//creates background
Rectangle background = new Rectangle(0, 0, 800, 600);
background.getStyleClass().add("background");
//draws field lines
Canvas game = new Canvas(800, 600);
GraphicsContext gc = game.getGraphicsContext2D();
gc.setStroke(Paint.valueOf("WHITE"));
gc.setLineWidth(5);
gc.strokeLine(400, 0, 400, 600);
gc.strokeOval(300, 200, 200, 200);
gc.strokeRect(0, 150, 100, 300);
gc.strokeRect(700, 150, 100, 300);
gc.setStroke(Paint.valueOf("BLACK"));
gc.setLineWidth(8);
gc.strokeRect(0, 0, 800, 600);
//creates red paddle
leftPaddle = new Rectangle(30, leftPaddleY, 20, 70);
leftPaddle.setFill(Color.RED);
//creates blue paddle
rightPaddle = new Rectangle(750, rightPaddleY, 20, 70);
rightPaddle.setFill(Color.BLUE);
// register event handlers to Canvas
game.setFocusTraversable(true);
game.setOnKeyPressed(keyPressed);
game.setOnKeyReleased(keyReleased);
gameDisplay.getStylesheets().add(getClass().getResource("GameDisplay.css").toExternalForm());
gameDisplay.getChildren().addAll(background, game, leftPaddle, rightPaddle);
// start updates of paddle positions
timer.start();
}
private EventHandler<KeyEvent> keyReleased = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
// set movement to 0, if the released key was responsible for the paddle
switch (event.getCode()) {
case W:
case S:
leftPaddleDY = 0;
break;
case UP:
case DOWN:
rightPaddleDY = 0;
break;
}
}
};
private EventHandler<KeyEvent> keyPressed = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
// start movement according to key pressed
switch (event.getCode()) {
case W:
leftPaddleDY = -6;
break;
case S:
leftPaddleDY = 6;
break;
case UP:
rightPaddleDY = -6;
break;
case DOWN:
rightPaddleDY = 6;
break;
}
}
};
}