You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现焦点切换后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:25:57