我正在使用JavaFX开发一个简单的Pong克隆,我很难移动桨。我想为此使用KeyEventDispatcher
,并在AnimationTimer
循环期间检查按键操作。
我的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 :(得分: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);
}
}