Java-初始化游戏后出现错误-扫雷舰



我遇到了这个奇怪的问题,但我似乎无法解决。我有一个按钮,上面写着"新游戏"。在我玩了一次游戏,然后按下"新游戏"返回initGame()后,我遇到了一个问题,因为我无法右键单击上一个游戏的地雷所在的单元格。我可以左键点击没有问题,因此我迷路了。

(附言:如果你想就如何缩短/简化我的代码向我提供建议,也可以这样做!)

请注意,这是我代码的一部分(其他一切都很好):

private void initGame() {
    minesFlagged=10;
    tfFlag.setText(minesFlagged + "");
    CellMouseListener listener = new CellMouseListener();
   // Reset cells, mines, and flags
   for (int row = 0; row < ROWS; row++) {
      for (int col = 0; col < COLS; col++) {
         // Set all cells to un-revealed
         btnCells[row][col].setEnabled(true);  // enable button
         btnCells[row][col].setForeground(FGCOLOR_NOT_REVEALED);
         btnCells[row][col].setBackground(BGCOLOR_NOT_REVEALED);
         btnCells[row][col].setFont(FONT_NUMBERS);
         btnCells[row][col].setText("");       // display blank
         mines[row][col] = false;   // clear all the mines
         flags[row][col] = false;   // clear all the flags
         zeroesVisit[row][col] = false;
         btnCells[row][col].setIcon(null);  
         btnCells[row][col].addMouseListener(listener); 
      }
   }
   for (int row = 0; row <= ROWS; row++) {
      for (int col = 0; col <= COLS; col++) {
         sol[row][col]=-1;             
       }
    }
// Set the number of mines and the mines' location
   numMines = 10; //rmb the array starts from zero and ends at index 9
   for(int i=0;i<numMines;i++){
       Random rand = new Random();
       //get random position for next mine
       int row = rand.nextInt(ROWS);
       int col = rand.nextInt(COLS);
       while(mines[row][col]||mines[0][0]){//if this position is a mine
           //we get new position
           row = rand.nextInt(ROWS);
           col = rand.nextInt(COLS);       
       }
       mines[row][col]=true;
   }
}
private void findSol(int rowSelected,int colSelected){
    for (int rr = rowSelected - 1; rr<= rowSelected + 1; rr++){//finding how many surrounding mines
        for (int cc = colSelected - 1; cc <= colSelected + 1; cc++){
            if(rr>=0 && cc>=0 && rr<ROWS && cc<COLS){
               if (mines[rr][cc]){
                   sol[rowSelected][colSelected]++;
                }
            }
        }
    }
}
    private class CellMouseListener extends MouseAdapter {
   @Override
   public void mouseClicked(MouseEvent e) {
      // Determine the (row, col) of the JButton that triggered the event
      int rowSelected = -1,colSelected = -1;
      // Get the source object that fired the Event
      JButton source = (JButton)e.getSource();
      // Scan all rows and columns, and match with the source object
      boolean found = false;
      boolean done = true;
      for (int row = 0; row < ROWS && !found; ++row) {
         for (int col = 0; col < COLS && !found; ++col) {
            if (source == btnCells[row][col]) {
               rowSelected = row;
               colSelected = col;
               found = true;   // break both inner/outer loops
            }
         }
      }
      // Left-click to reveal a cell; Right-click to plant/remove the flag.
      if (e.getButton() == MouseEvent.BUTTON1 && (!flags[rowSelected][colSelected])) {  // Left-button clicked
         //If you hit a mine, game over - OKAY
         //Otherwise, reveal the cell and display the number of surrounding mines - okay
          if (mines[rowSelected][colSelected]){
             btnCells[rowSelected][colSelected].setBackground(BGCOLOR_REVEALED);
             imgMines = new ImageIcon(getClass().getResource("Bombicon.png"));                
             btnCells[rowSelected][colSelected].setIcon(imgMines);
             JOptionPane.showMessageDialog(null, "Game Over! Try to complete the game~");
         }else{
             btnCells[rowSelected][colSelected].setBackground(FGCOLOR_REVEALED); //though foreground is text color  
             btnCells[rowSelected][colSelected].setIcon(null);
             sol[rowSelected][colSelected]=0;
             findSol(rowSelected,colSelected);
             if(sol[rowSelected][colSelected]>0){
                 btnCells[rowSelected][colSelected].setText(""+sol[rowSelected][colSelected]); 
                 btnCells[rowSelected][colSelected].removeMouseListener(this);
                 colorCell(rowSelected,colSelected);                     
             }               
             else if(sol[rowSelected][colSelected]==0){                                                              
                 do{
                     done = true;
                     for(int r=0;r<ROWS;r++){//scanning through whole board
                         for(int c=0;c<COLS;c++){                               
                             if(sol[r][c]==0 && !zeroesVisit[r][c]){
                                 zeroesVisit[r][c]=true;
                                 for(int row=r-1;row<=r+1;row++){//open the 8 surrounding cells
                                     for(int col=c-1;col<=c+1;col++){
                                         if(row>=0 && col>=0 && row<ROWS && col<COLS){//make sure not out of bounds
                                             btnCells[row][col].setBackground(FGCOLOR_REVEALED);
                                             btnCells[row][col].setIcon(null);
                                             sol[row][col]=0;
                                             findSol(row,col);             
                                             btnCells[row][col].removeMouseListener(this);  
                                             if(sol[row][col]>0){
                                                 btnCells[row][col].setText(""+sol[row][col]);                                                                                                      
                                                 colorCell(row,col);                                                     
                                             }
                                             else if(sol[row][col]==0){
                                                 btnCells[row][col].setText("");
                                                 done=false;//to prompt looping again
                                             }
                                         }                                   
                                     }                                                               
                                 }
                             }                                                                                                  
                         }       
                     }
                 }while(!done);//scan again to find all/any the zero cells                                                                                          
             }
         }
      }else if (e.getButton() == MouseEvent.BUTTON3) { // right-button clicked
         //If the location is flagged, remove the flag
         // Otherwise, plant a flag. - COMPLETED
          if(flags[rowSelected][colSelected]){
              flags[rowSelected][colSelected]=false;
              btnCells[rowSelected][colSelected].setBackground(BGCOLOR_NOT_REVEALED);
              btnCells[rowSelected][colSelected].setIcon(null);
              minesFlagged++;
              tfFlag.setText(minesFlagged + "");
          }else{
              flags[rowSelected][colSelected]=true;
              btnCells[rowSelected][colSelected].setBackground(FGCOLOR_NOT_REVEALED);
              imgFlags = new ImageIcon(getClass().getResource("whiteflag.png"));
              btnCells[rowSelected][colSelected].setIcon(imgFlags);  
              minesFlagged--;
              tfFlag.setText(minesFlagged + "");
          }
      }
      //Check if the player has won, after revealing this cell - COMPLETED
      int completeCount=0,flagCount=0;
      for (int row = 0; row < ROWS; ++row) {
          for (int col = 0; col < COLS; ++col) {
              if(!mines[row][col] && btnCells[row][col].getBackground()==FGCOLOR_REVEALED){                   
                  completeCount++;
                  if((ROWS*COLS-numMines) == completeCount){
                      JOptionPane.showMessageDialog(null, "CONGRATULATIONS!");
                  }                  
              }
          }
      }
   }
}

每次初始化游戏时,您似乎都在调用addMouseListener。这并不能取代以前游戏中现有的MouseListener,所以你现在在按钮上有了一个额外的监听器,而你没有调用removeMouseListener。如果某些按钮没有触发事件,我会先对此进行调查。

在第一次创建Frame时,最好只添加一次侦听器。然后向mouseClicked事件方法添加逻辑,以忽略"停用"按钮上的单击,而不是一遍又一遍地删除和添加侦听器。

如果你必须采取这种方法,我建议在initGame方法中添加监听器之前,从任何有MouseListener的按钮中删除所有MouseListeners(可以使用getMouseListenes方法找到它们)。

正如ArielB所说,最好将您的模型(矿的位置和瓦片的状态等)从UI代码中分离到另一个类中。

最新更新