Java Swing - служба ScheduledExecutor перестает работать на UserInput - PullRequest
0 голосов
/ 22 апреля 2020

Я строю Лабиринт, где Монстр отслеживает игрока и движется к нему. У меня есть функция SwapCells, в которой, как мне кажется, кроется проблема. SwapCells используется для перемещения как Monster, так и Player. У меня есть ScheduledExecutorService, который запускает Monstermover, который использует SwapCells. Монстр начинает двигаться, когда начинается игра, теперь проблема в том, что когда я начинаю перемещать игрока, ScheduledExecutorService перестает работать, и я могу перемещать только игрока. Я считаю, что проблема в том, что, в отличие от MoveMonster, Keylistener не является частью ScheduledExecutorService, поэтому, когда я вызываю KeyListener, который, в свою очередь, запускает SwapCell, он останавливает ScheduledExecutorService. Любой совет? Пожалуйста, помогите!

private final int CELLSIZE = 20;
private ArrayList<Level> levels = new ArrayList<Level>();
private Player player;
private Monster monster;
private DisplayInfo display;        
private int xSize;
private int ySize;
private int currentLevel = 0;
private int direction = 0;
//private CountDownTimer timer = new CountDownTimer(15);

public Game(int xSize, int ySize) {
    player = new Player(0,0);
    monster = new Monster(0,1);
    setXSize(xSize);
    setYSize(ySize);
    setLayout(new GridLayout(ySize, xSize));
    addLevel();
    addKeyListener(new KeyListener() {                  

        // POSSIBLE PROBLEM IS HERE !!
        @Override
        public void keyPressed(KeyEvent event) {

                if(!hitWall) }  
                swapCells(getCurrentLevel().getMap()[x+dx][y+dy], getCurrentLevel().getMap()[x][y], player);
            }
            }
        }
    });     

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
    executor.scheduleAtFixedRate(() -> moveMonster(), 0L, 1000L, TimeUnit.MILLISECONDS);        

}                                            

public void swapCells(Cell cell1, Cell cell2, Mover mover) {
    Icon tempIcon = cell1.getLabel().getIcon();
    String tempID = cell1.getID();

    // sets mover's x and y value
    mover.setX(cell1.getX());
    mover.setY(cell1.getY());       

    // sets mover's cell to new cell
    getCurrentLevel().getpMaze().setCell(cell1, mover);

    getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].setID(cell2.getID());
    getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].getLabel().setIcon(cell2.getLabel().getIcon());
    getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].setID(tempID);
    getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].getLabel().setIcon(tempIcon);        
}

public void moveMonster() { 

    PerfectMaze currentMaze = getCurrentLevel().getpMaze();
    ArrayList<Cell> trackToPlayer = currentMaze.getTrack(currentMaze.getMonsterCell(), currentMaze.getPlayerCell(), "P");
    Collections.reverse(trackToPlayer);
    Cell nextCell = trackToPlayer.get(1);   
    //swapCells(nextCell, currentMaze.getMonsterCell(), monster);
    swapCells(getCurrentLevel().getMap()[nextCell.getX()][nextCell.getY()], getCurrentLevel().getMap()[monster.getX()][monster.getY()], monster);       

}

1 Ответ

1 голос
/ 22 апреля 2020

Вы должны взаимодействовать только с компонентами Swing из Swing «Thread Dispatch Thread» (EDT). Но вы создали ExecutorService, и его потоки напрямую управляют компонентами Swing.

Вместо этого выполните фоновую работу в SwingWorker, , которая может безопасно передавать графические обновления в EDT.

...