实现焦点切换后JavaFX多人俄罗斯方块Down按键方法崩溃
JavaFX多人俄罗斯方块焦点切换后Down键崩溃问题求助
我正在用JavaFX开发一款多人俄罗斯方块,每个游戏运行在独立的Stage窗口中。每个游戏有独立输入逻辑,收到对应按键时会在两个Stage间切换焦点,以此实现同时游玩。整体功能运行正常,这是参考Stack Overflow上的焦点切换方案修改输入逻辑后的结果。
当前输入处理核心代码如下:
public void handleInput(KeyEvent event) { switch(event.getCode()) { case UP: if (!StartBoard.stageList.get(0).isFocused()) { StartBoard.stageList.get(0).requestFocus(); StartBoard.gameList.get(0).handleInput(event); } else { tetr.rotate(MESH); } break; case LEFT: if (!StartBoard.stageList.get(0).isFocused()) { StartBoard.stageList.get(0).requestFocus(); StartBoard.gameList.get(0).handleInput(event); } else { tetr.move(false, MESH); } break; case RIGHT: if (!StartBoard.stageList.get(0).isFocused()) { StartBoard.stageList.get(0).requestFocus(); StartBoard.gameList.get(0).handleInput(event); } else { tetr.move(true, MESH); } break; case DOWN: if (!StartBoard.stageList.get(0).isFocused()) { StartBoard.stageList.get(0).requestFocus(); StartBoard.gameList.get(0).handleInput(event); } else { tetr.slam(MESH); } } }
针对WASD按键有对应分支逻辑,操作stageList.get(1)和gameList.get(1)。gameList中的元素为MainBoard类型(即当前handleInput方法所在的类,负责单个游戏的运行),tetr是Tetromino类实例,负责处理俄罗斯方块的旋转、移动等操作。
现在遇到的问题:每次按下Down键都会导致游戏崩溃,表现为两个游戏窗口无响应数秒后关闭,仅保留启动窗口。但在实现动态焦点切换前,手动点击切换焦点时,tetr.slam方法运行完全正常;且对应另一个MainBoard的S按键(功能等同于Down)仍可正常工作。
附上tetr.slam及相关方法代码(虽认为问题不在此,但仍提供参考):
public void slam(int MESH[][]) { while (!fall(MESH)) { fall(MESH); } }
MESH定义和fall方法:
public int[][] MESH = new int [StartBoard.XMAX/StartBoard.SIZE][StartBoard.YMAX/StartBoard.SIZE]; public boolean fall(int MESH[][]) { for (Rectangle i: rectList) { if (i.getY() + StartBoard.SIZE >= StartBoard.YMAX || MESH[(int)i.getX()/StartBoard.SIZE][((int)i.getY() + StartBoard.SIZE)/StartBoard.SIZE] == 1) { return true; } } for (Rectangle i: rectList) { i.setY(i.getY() + StartBoard.SIZE); } return false; }
其中MESH是MainBoard的成员变量,会传入对应的Tetromino实例。
补充游戏实例创建的线程代码,供排查并发问题:
startButton.setOnAction(new EventHandler <ActionEvent>() { public void handle(ActionEvent event) { playerVal.set(0); startTask(); } }); } public void startTask() { //Creates runnable Runnable task = new Runnable() { public void run() { runTask(); } }; //Run task in bgThread Thread bgThread = new Thread(task); Thread bgThread2 = new Thread(task); //Terminate running thread if application exists bgThread.setDaemon(true); bgThread2.setDaemon(true); //Start thread bgThread.start(); bgThread2.start(); } /** * Sets up new stages for a Tetris game. */ public void runTask() { Platform.runLater(new Runnable() { @Override public void run() { Pane localPane = new Pane(); Scene localScene = new Scene(localPane, XMAX + 150, YMAX); Stage inner = new Stage(){{setScene(localScene); }}; inner.initOwner(stage); //inner.initModality(Modality.WINDOW_MODAL); int val = playerVal.getAndIncrement(); inner.setX((XMAX + 150) * val ); inner.setY(YMAX / 2 - 150); stageList.add(inner); inner.show(); MainBoard localMainBoard = new MainBoard(val); gameList.add(localMainBoard); System.out.println("*****START******"); try { localMainBoard.start(inner); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); }
恳请各位提供排查思路。
内容的提问来源于stack exchange,提问作者Kyle Nickson
相关产品推荐
相关产品推荐

