2016-04-11 6 views
0

У меня возникла эта странная проблема, но я не могу понять ее. У меня есть кнопка, которая говорит «новая игра». После того, как я играю в игру один раз, а затем нажмите «новая игра», которая возвращается к initGame(), я столкнулся с проблемой, поскольку я не могу щелкнуть правой кнопкой мыши по ячейкам, которые были шахтами предыдущей игры. Я могу левым кликом без проблем, поэтому я потерян.Java - ошибка после инициализации игры - тральщик

(пс, если вы хотите мне советы о том, как сократить/упростить свой код, не стесняйтесь делать это тоже!)

Пожалуйста, советы, это часть моего кода (все остальное работает отлично):

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!"); 
        }     
       } 
      } 
     } 
    } 
} 
+1

Вызывается щелчком мыши, когда вы щелкаете правой кнопкой мыши по ячейке? (вы поставили там точку останова?), тем не менее, вы смешиваете пользовательский интерфейс и логику в своем коде - это очень плохая практика архитектуры программного обеспечения - я бы посоветовал узнать о разделении интерфейса и логики. еще одно, может быть, не связанное - вы удалили всех слушателей мыши после того, как игра закончилась? – ArielB

ответ

1

Кажется, вы вызываете addMouseListener каждый раз, когда игра инициализируется. Это не заменяет существующий MouseListener из предыдущих игр, поэтому теперь у вас есть дополнительный прослушиватель на кнопках, где вы не вызывали removeMouseListener. Я бы сначала исследовал это, если некоторые кнопки не активируют событие.

Было бы лучше только добавить слушателей один раз, когда сначала будет создан кадр. Затем добавьте логику в метод mouseClicked event, чтобы игнорировать клики на кнопках, которые «деактивированы», а не удалять и добавлять слушателя снова и снова.

Если вы должны принять этот подход, я рекомендую удалить все MouseListeners с любых кнопок, которые есть у них (они могут быть найдены с помощью метода getMouseListeners), прежде чем добавлять слушателя в метод initGame.

Как указано ArielB, лучше всего отделить вашу модель (положение шахт и состояний плиток и т. Д.) От другого класса вдали от вашего пользовательского интерфейса.

 Смежные вопросы

  • Нет связанных вопросов^_^