2017-03-22 36 views
0

我正在開發一個使用JavaFX的簡單Pong克隆,並且我在移動槳時遇到了困難。我想爲此使用KeyEventDispatcher,並在我的AnimationTimer循環中檢查按鍵。調用dispatchKeyEvent來執行形狀翻譯

Main類:

public class Main extends Application { 

    private Player m_pUser; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 

     Group root = new Group(); 
     Scene scene = new Scene(root, 500, 300); 
     ObservableList list = root.getChildren(); 

     KeyPressedChecker kpc = new KeyPressedChecker(); 

     m_pUser = new Player(kpc); 

     list.add(m_pUser.getPaddleDrawable()); 

     GamePlayLoop gameLoop = new GamePlayLoop(m_pUser); 
     gameLoop.start(); 

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

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

GamePlayLoop類:

public class GamePlayLoop extends AnimationTimer { 

    Player m_pUser; 

    public GamePlayLoop(Player p) { 
     m_pUser = p; 
    } 

    public void handle(long now) { 
     m_pUser.update(); 
    } 
} 

KeyPressedChecker類:

public class KeyPressedChecker implements KeyEventDispatcher { 

    private static boolean downPressed = false; 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent ke) { 
     synchronized (KeyPressedChecker.class) { 
      switch (ke.getID()) { 

       case KeyEvent.KEY_PRESSED: 
        if (ke.getKeyCode() == KeyEvent.VK_DOWN) 
         downPressed = true; 
       break; 
       case KeyEvent.KEY_RELEASED: 
        if (ke.getKeyCode() == KeyEvent.VK_DOWN) 
         downPressed = false; 
        break; 
      } 

      return false; 
     } 
    } 

    public static boolean isDownPressed() { 
     synchronized (KeyPressedChecker.class) { 
      return downPressed; 
     } 
    } 
} 

Player類:

public class Player { 

    private Paddle m_paddle; 
    private KeyPressedChecker m_kpc; 

    public Player(KeyPressedChecker kpc) { 
     m_paddle = new Paddle(); 
    } 

    public Rectangle getPaddleDrawable() { 
     return m_paddle.getDrawable(); 
    } 

    public void update() { 
     if (m_kpc.isDownPressed()) 
      m_paddle.moveDown(); 
     m_paddle.update(); 
    } 
} 

最後我Paddle類:

public class Paddle { 

    private Rectangle m_rect; 
    private double m_nPosY; 

    public Paddle() { 
     m_rect = new Rectangle(10, 60); 
    } 

    public void moveDown() { 
     m_nPosY += 5; 
    } 

    public Rectangle getDrawable() { 
     return m_rect; 
    } 

    public void update() { 
     m_rect.setTranslateY(m_nPosY); 
    } 
} 

我的問題是,槳不在現場翻譯。實際上,dispatchKeyEvent根本不被調用。爲什麼是這樣?

回答

0

KeyEventDispatcher是AWT的一部分,AWT是一個完全獨立於JavaFX的工具包。 (即使它是JavaFX的一部分,你只是實例化你的實現類,但不要對它做任何事情......)。

在JavaFX中執行此操作的方法是在場景中爲KeyEvent.KEY_PRESSED事件註冊事件處理程序。

因此,使用當前的設計(約),你會做

public class KeyPressedChecker implements EventHandler<KeyEvent> { 

    private boolean downPressed = false; 

    @Override 
    public void handle(KeyEvent ke) { 
     if (ke.getEventType() == KeyEvent.KEY_PRESSED) { 
      downPressed = true ; 
     } else if (ke.getEventType() == KeyEvent.KEY_RELEASED) { 
      downPressed = false ; 
     } 
    } 

    public boolean isDownPressed() { 
     return downPressed; 
    } 

} 

在你Player類(我改名領域,以配合適當的naming conventions

public class Player { 

    private Paddle paddle; 
    private KeyPressedChecker kpc; 

    public Player(KeyPressedChecker kpc) { 
     this.paddle = new Paddle(); 
     this.kpc = kpc ; 
    } 

    public Rectangle getPaddleDrawable() { 
     return paddle.getDrawable(); 
    } 

    public void update() { 
     if (kpc.isDownPressed()) 
      paddle.moveDown(); 
     paddle.update(); 
    } 
} 

,然後一切都與

相連
public class Main extends Application { 

    private Player pUser; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 

     Group root = new Group(); 
     Scene scene = new Scene(root, 500, 300); 
     ObservableList list = root.getChildren(); 

     KeyPressedChecker kpc = new KeyPressedChecker(); 

     scene.addEventHandler(KeyEvent.ANY, kpc); 

     pUser = new Player(kpc); 

     list.add(pUser.getPaddleDrawable()); 

     GamePlayLoop gameLoop = new GamePlayLoop(pUser); 
     gameLoop.start(); 

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

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

這是非常有用的,解決了我的問題,謝謝你很多!我知道重命名類變量 - 我爲它們命名的推理例如'm_pUser'是表示一個成員變量(與匈牙利符號結合)以避免必須確保我寫'this'以避免名稱衝突,因爲局部變量不會在名稱中包含'm'。希望我正確解釋自己。 – petehallw

+0

@petehallw我理解其他語言中使用的約定,但強烈建議您在編寫Java時遵循Java約定(對其他語言也是如此)。這會讓其他程序員更容易閱讀你的代碼。就FWIW而言,我討厭'm_pUser',因爲它不可能在內部發聲。 (如果能解決問題,請將答案標爲正確。) –

+0

可以理解,我會在將來考慮。標記爲正確,謝謝。出於興趣,你的意思是「內部發聲」? – petehallw