2016-08-17 7 views
0

私はプログラミングが新しく、私はJavaFXで2人のPongのゲームに取り組んできました。 1人のプレイヤーはW/Sを使用して「パドル」を移動し、もう1人のプレイヤーは上下の矢印を使用して自分の「パドル」を移動します。私が残している問題は、一度に1人のプレイヤーだけがパドルを動かすことができるということです。私はそれを得る方法を理解することができないので、同時に彼らはそれぞれのパドルを動かすことができます。私は1つのキーボードイベントハンドラで両方のパドルを制御していたが、それは問題だと思った。私は2つの別々のキーボードハンドラを作ったが、組み込みのsetFocusTraversableメソッドによって引き起こされると思われる別の問題がある。私がしようとしていることが意味をなさないことを願っています。何か案は?Javafxのキーボードで2つの四角形を移動する

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; 
      } 
     } 

    } 
}; 
} 

答えて

2

keyPressedイベントは、最後に押されたキーに対して繰り返しトリガされます。

これを回避するには、各パドルの希望の動きを覚えて、keyReleasedイベントも聞きます。 AnimationTimerを使用して動きを実行して、毎フレームの更新を実行することができます(更新頻度をより詳細に制御するためにTimelineを使用することもできます)。

さらに、他のクラスがクラスのフィールドに直接書き込むことはできないため、メンバー変数の可視性をさらに制限することをお勧めします。また、イベントを単一のNodeで処理することをお勧めします。 Nodeは一度に1つのフォーカスのみを持ち、別の場所でイベントを処理するとコードが重複します。

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; 
      } 

     } 
    }; 
} 
+0

ありがとうございます。それは動作し、それは今、すべての意味があります。 AnimationTimerの使い方を私の人生では理解できませんでした。余分なヒントをありがとう – Jorg1776

関連する問題