单击“确定”按钮后再次出现消息对话框

发布于 2024-08-17 07:18:10 字数 14968 浏览 8 评论 0原文

在得到之前的良好帮助后,我已经完成了我的扫雷游戏。然而,有一个问题我想不通。游戏本身运行良好,但是,我可以选择让用户更改难度设置(初级、中级、高级),这让我感到悲伤。用户从 JMenuBar 中选择“游戏”,然后从下拉菜单中选择“更改难度”。这会调用 selectDifficulty() 方法,该方法会打开一个 JOptionMessageBox,该 JOptionMessageBox 使用 JRadioButtons 让用户选择 4 个选项之一(第 4 个选项是自定义选项 - 但到目前为止我还没有实现)。当用户第一次更改难度模式时,该对话框似乎工作正常。然而,当用户第二次或更多次尝试改变难度时,游戏会执行该设置,然后再次出现对话框并提示用户重新选择难度。有时这种情况会重复两次,然后消失,有时会重复 4 或 5 次。 我将不胜感激任何帮助,因为我不知道为什么会发生这种情况。

另外,我也希望得到一些关于如何改进难度设置更改的建议。按照目前的情况,代码删除了 JPanel 和雷区(由按钮组成),并使用新的难度设置重新实例化按钮/Japanels。有没有办法提高效率?

有一个逻辑类和一个 GUI 玻璃。上述两个问题都存在于 GUI 类中。

private void selectDifficulty() {

    group.add(b1);
    group.add(b2);
    group.add(b3);
    group.add(b4);
    b1.setSelected(true);

    Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
    JOptionPane.showMessageDialog(null, array);

        if (b1.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 1;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 1;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 1;
            }
            start(9,9);

        }else if (b2.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 2;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 2;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 2;
            }
            start(15,15);
        }else if (b3.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 3;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 3;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 3;
            }     
            start(20,20);
        }             
}    

完整代码: GUI类

import java.awt.* ;
import java.awt.event.* ;
import javax.swing.* ;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;


public class MineSweeperGUI extends JFrame implements MouseListener {          

MinesweeperLogic logicClass = new MinesweeperLogic();
JButton newGameButton = new JButton ("New Game");
JMenuItem optionsButton = new JMenuItem ("Change Difficulty");
JRadioButton b1 = new JRadioButton ("Beginner: 9 X 9 Grid (10 Mines)");
JRadioButton b2 = new JRadioButton ("Intermediate: 15 X 15 Grid (36 Mines)");
JRadioButton b3 = new JRadioButton ("Advanced:  20 X 20 Grid (80 Mines)");
JRadioButton b4 = new JRadioButton ("Custom");
ButtonGroup group = new ButtonGroup();
JMenuItem aboutButton = new JMenuItem ("About Minesweeper");
JPanel p = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
int w, h, rw = 0, rh = 0, mode = 1;


public void MineSweeper(int width, int height) {
    //setupI(); 
    w = width;
    h = height;    
    logicClass.startNewGame(w, h);
    GridLayout layout = new GridLayout (w, h);
    p2.setLayout(new BorderLayout());
    p.setLayout(layout);
    p2.add(p, BorderLayout.CENTER);
    for(int x = 0 ; x < w ; x++) {
        for(int y = 0 ; y < h ; y++) {
            logicClass.label[x][y] = new Button();
            logicClass.label[x][y].setPreferredSize(new Dimension(20,20));
            logicClass.label[x][y].setBackground(new Color(33,58,156));
            logicClass.label[x][y].addMouseListener (this);
            p.add(logicClass.label[x][y]);
        }
    }       
    JMenuBar mb = new JMenuBar();
    JMenu m = new JMenu("Game");
    JMenu m2 = new JMenu("Help");
    m.add(optionsButton);
    m2.add(aboutButton);
    mb.add(m);
    mb.add(m2);

    p2.add(p3, BorderLayout.PAGE_START);
    newGameButton.setPreferredSize (new Dimension(87, 20));
    newGameButton.setFont(new Font("sansserif",Font.BOLD,11));
    newGameButton.setForeground(Color.black);
    newGameButton.setBackground(new Color(235,52,52));
    Border thickBorder = new LineBorder(Color.black, 2);
    newGameButton.setBorder(thickBorder);


    p3.add(newGameButton);
    newGameButton.addMouseListener(this);

    optionsButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            selectDifficulty();
        }
    });

    this.setJMenuBar(mb);
    this.add(p2);
    this.pack();
    this.setVisible(true);

}


private void start(int width, int height){
    p2.remove(p);
    for(int x = 0 ; x < rw ; x++) {
        for(int y = 0 ; y < rh ; y++) {
            p.remove(logicClass.label[x][y]);
        }
    }
    p2.remove(p3);
    p3.remove(newGameButton);
    this.remove(p2);
    MineSweeper(width, height);
}        

private void lose() {
  JOptionPane.showMessageDialog(this, "GAME OVER - YOU LOSE!  Starting New Game", "Game Over", JOptionPane.INFORMATION_MESSAGE);
  newGame();
}

private void win() {
  JOptionPane.showMessageDialog(this, "YOU WIN! Starting New Game", "CONGRATULATIONS", JOptionPane.INFORMATION_MESSAGE);
  newGame();
}


private void newGame() {
   if(mode==1){
       rw = 9;
       rh = 9;
       start(9,9);
    }else if(mode==2){
       rw = 15;
       rh = 15;
       start(15,15);
    }else{
       rw = 20;
       rh = 20;
       start(20,20);
    }
}


public void mouseClicked(MouseEvent e) {
   if(e.getSource() == newGameButton) {    
       if(e.getButton() == e.BUTTON1) {
           newGame();
        }
    }

   for (int x = 0 ; x < w; x++) {
       for (int y = 0 ; y < h; y++) {
           if(e.getSource() == logicClass.label[x][y]) {    
                if(e.getButton() == e.BUTTON1) {
                    if(logicClass.openCell(x, y) == false) {
                        lose();
                    } else {
                        for (int q = 0; q < w; q++) {
                            for (int j = 0; j < h; j++) {
                                if (logicClass.label[q][j].getBackground()==Color.green) {
                                    win();
                                }
                            }
                        }
                    }
               }else if(e.getButton() == e.BUTTON3) {
                   logicClass.markCell(x, y);
                    }
                }       
            }  
        }
     }

 private void selectDifficulty() {

    group.add(b1);
    group.add(b2);
    group.add(b3);
    group.add(b4);
    b1.setSelected(true);

    Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
    JOptionPane.showMessageDialog(null, array);

        if (b1.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 1;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 1;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 1;
            }
            start(9,9);

        }else if (b2.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 2;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 2;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 2;
            }
            start(15,15);
        }else if (b3.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 3;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 3;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 3;
            }     
            start(20,20);
        }             
}    

public static void main(String[]args) {
    MineSweeperGUI guiClass = new MineSweeperGUI();
    guiClass.MineSweeper(9,9);
}

public void mouseEntered(MouseEvent e) {}

public void mousePressed(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}
}    

逻辑类: 导入 java.awt.* ;

public class MinesweeperLogic {

public int width, height;
private int w, h, maxBombs;
private boolean mine[][]; 
private boolean flag[][];
private boolean isClicked[][];
private boolean isZero[][];
private boolean marked;
MineSweeperGUI guiClass;
Button[][] label;
private int surBombs;
private String temp;
private double mineRatio;


public void startNewGame(int width, int height) {
    w = width;
    h = height;
    label = new Button[w][h];
    mine = new boolean[w][h];
    flag = new boolean[w][h];
    isClicked = new boolean[w][h];
    isZero = new boolean[w][h];
    if ( (w*h) <= 81) {
        mineRatio = 0.13;
    }else if ( (w*h) <= 255) {
        mineRatio = 0.16;
    }else {
        mineRatio = 0.2;
    }
    maxBombs = (int) Math.floor (w * h * mineRatio);
    for (int i = 0; i < maxBombs; i++) {
        int x = (int) (Math.random() * w);
        int y = (int) (Math.random() * h);
        if (mine[x][y] == false) {
            mine[x][y] = true;
            isClicked[x][y] = false;
            flag[x][y] = false;
            isZero[x][y] = false;
        } else {
            i--;
        }
    }       
}


int getWidth() {
    return w;
}


int getHeight() {
    return h;
}


boolean openCell(int x, int y) {                
    isClicked[x][y] = true;
    if (mine[x][y] == true   &&   flag[x][y] == false) {
        lose();
        return false;
    } else if (getValue(x, y) > 0   &&   flag[x][y] == false) {
        temp = Integer.toString (getValue(x, y));
        label[x][y].setLabel (temp);
        label[x][y].setBackground (new Color (111,184,252));
        checkWin();
        return true;
    } else if (getValue(x, y) == 0   &&   flag[x][y] == false) {
        for (int q = x-1; q <= x+1; q++) {                       
            if(q < 0   ||   q >= w) {                                        
            continue;
            }
            for (int i = y-1; i <= y+1; i++) {
                if(i < 0   ||   i >= h   ||   flag[q][i] == true) { // makes sure that it wont have an error for buttons next to the wall
                continue;
                }
                label[q][i].setBackground(new Color (111,184,252));
                if (getValue(q, i) != 0) { // opens surrounding cells that have mines around them (max 8 cells)
                temp = Integer.toString (getValue(q, i));
                label[q][i].setLabel (temp);
                isClicked[q][i] = true;
                } else {
                    for (int k = x-1; k <= x+1; k++) {
                        if(k < 0   ||   k >= w) {
                        continue;
                        }
                            for (int m = y-1; m <= y+1; m++) {
                                if (m < 0   ||   m >= h   ||   flag[k][m] == true) { // makes sure that it wont have an error for buttons next to the wall
                                continue;
                                }
                                if (isClicked[k][m] == false   &&   getValue(k, m) == 0) { // recursively continues to open all surrounding cells with no mines around them
                                    openCell(k, m);
                                }
                            }
                        }
                    }
                }
            }
            checkWin(); 
            return true;
            } else {
                return true;
            }
      }           


boolean markCell(int x, int y) {
    if (flag[x][y] == true) {
        flag[x][y] = false;
        label[x][y].setLabel ("");
        label[x][y].setForeground (Color.black);
        label[x][y].setFont (new Font (null, Font.PLAIN, 12));
        return false;
    }
    if (isClicked[x][y] == false && flag[x][y] == false) {
        flag[x][y] = true;
        label[x][y].setFont (new Font ("sansserif", Font.BOLD, 14));
        label[x][y].setLabel ("<|");
        label[x][y].setForeground (Color.red);
    }
    if (mine[x][y] == true) {
        return true;
    } else {
        return false;
    }
}


boolean isOpen(int x, int y) {
    if (isClicked[x][y] == false) {
        return false;
       } else {
           return true;
       }
}


boolean isMarked(int x, int y) {
    if (flag[x][y] == true) {
        return true;
       } else {
           return false;
       }
}


int getValue(int x, int y) {
     if (mine[x][y] == true) {
         return -1;
       } else {
           return neighborBombs(x, y);
       }
   }


private int neighborBombs(int x, int y) {  // checks surrounding 8 squares for number of bombs (it does include itself, but has already been checked for a bomb so it won't matter)
      surBombs = 0;
          for (int q = x-1; q <= x+1; q++) {
              if (q < 0   ||   q >= w) {
                  continue;
              }
                  for (int i = y-1; i <= y+1; i++) {
                      if (i < 0   ||   i >= h) { // makes sure that it wont have an error for buttons next to the wall
                          continue;
                      }
                      if (mine[q][i] == true) {
                         surBombs++;
                      }
                  }   
              }          
       return surBombs;
      }


private void lose() {
    for (int q = 0; q < w; q++) {
        for (int j = 0; j < h; j++) {
            if (mine[q][j] == true) {
                if (label[q][j].getLabel().equals ("<|")) {
                    label[q][j].setBackground (Color.green);
                } else {
                    label[q][j].setBackground (Color.red);
                    label[q][j].setLabel ("*");
                    label[q][j].setForeground (Color.black);
                }


            }
        }
    }
 }


private void checkWin() {
    int count = 0;
    int count2 = 0;
    for (int i = 0; i < w; i++){
        for (int j = 0; j < h; j++) {
            if (isClicked[i][j] == true){
                count++;    
            }
            if (mine[i][j] == true){
                count2++;
            }
        }
    }
    if ( (count + count2) == (w * h) ){
        win();
    }
 }       


private void win() {
    for (int q = 0; q < w; q++) {
        for (int j = 0; j < h; j++) {
            if (mine[q][j] == true) {
                label[q][j].setBackground (Color.green);
                label[q][j].setForeground (Color.red);
                label[q][j].setFont (new Font ("sansserif", Font.BOLD, 14));
                label[q][j].setLabel ("<|");
            }
        }
    }
}
}

After getting good help previously, I have completed my Minesweeper game. However, there is one problem that I can't figure out. The game itself works fine, however, I have an option for the user to change difficulty setting (beginner, intermediate, advanced) which is giving me grief. The user selects "Game" from the JMenuBar and then selects "Change Difficulty" from the drop down menu. This calls the method selectDifficulty() which opens a JOptionMessageBox which uses JRadioButtons to get the user to select one of the 4 options (the 4th being Custom - however I have not implemented that as of yet). The dialog box seems to work fine the first time the user changes difficulty mode. However, when the user attempts to change difficulty a 2nd time or more, the game implements the setting and then the dialogue box reappears and promts the user to select the difficulty again. This sometimes repeats twice before going away, and at other times up to 4 or 5 times.
I would appreciate any help as I do not know why this is happening.

Also, I would also appreciate some advice on how I could improve how the difficulty settings are change. As it stands, the code removes the JPanel and the minefield(made of Buttons) and re instantiates the buttons/Japanels with the new difficulty setting. Is there a way to make this more efficient?

There is a logic class and a GUI glass. Both of the above issues are present in the GUI class.

private void selectDifficulty() {

    group.add(b1);
    group.add(b2);
    group.add(b3);
    group.add(b4);
    b1.setSelected(true);

    Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
    JOptionPane.showMessageDialog(null, array);

        if (b1.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 1;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 1;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 1;
            }
            start(9,9);

        }else if (b2.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 2;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 2;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 2;
            }
            start(15,15);
        }else if (b3.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 3;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 3;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 3;
            }     
            start(20,20);
        }             
}    

COMPLETE CODE:
GUI CLASS

import java.awt.* ;
import java.awt.event.* ;
import javax.swing.* ;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;


public class MineSweeperGUI extends JFrame implements MouseListener {          

MinesweeperLogic logicClass = new MinesweeperLogic();
JButton newGameButton = new JButton ("New Game");
JMenuItem optionsButton = new JMenuItem ("Change Difficulty");
JRadioButton b1 = new JRadioButton ("Beginner: 9 X 9 Grid (10 Mines)");
JRadioButton b2 = new JRadioButton ("Intermediate: 15 X 15 Grid (36 Mines)");
JRadioButton b3 = new JRadioButton ("Advanced:  20 X 20 Grid (80 Mines)");
JRadioButton b4 = new JRadioButton ("Custom");
ButtonGroup group = new ButtonGroup();
JMenuItem aboutButton = new JMenuItem ("About Minesweeper");
JPanel p = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
int w, h, rw = 0, rh = 0, mode = 1;


public void MineSweeper(int width, int height) {
    //setupI(); 
    w = width;
    h = height;    
    logicClass.startNewGame(w, h);
    GridLayout layout = new GridLayout (w, h);
    p2.setLayout(new BorderLayout());
    p.setLayout(layout);
    p2.add(p, BorderLayout.CENTER);
    for(int x = 0 ; x < w ; x++) {
        for(int y = 0 ; y < h ; y++) {
            logicClass.label[x][y] = new Button();
            logicClass.label[x][y].setPreferredSize(new Dimension(20,20));
            logicClass.label[x][y].setBackground(new Color(33,58,156));
            logicClass.label[x][y].addMouseListener (this);
            p.add(logicClass.label[x][y]);
        }
    }       
    JMenuBar mb = new JMenuBar();
    JMenu m = new JMenu("Game");
    JMenu m2 = new JMenu("Help");
    m.add(optionsButton);
    m2.add(aboutButton);
    mb.add(m);
    mb.add(m2);

    p2.add(p3, BorderLayout.PAGE_START);
    newGameButton.setPreferredSize (new Dimension(87, 20));
    newGameButton.setFont(new Font("sansserif",Font.BOLD,11));
    newGameButton.setForeground(Color.black);
    newGameButton.setBackground(new Color(235,52,52));
    Border thickBorder = new LineBorder(Color.black, 2);
    newGameButton.setBorder(thickBorder);


    p3.add(newGameButton);
    newGameButton.addMouseListener(this);

    optionsButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            selectDifficulty();
        }
    });

    this.setJMenuBar(mb);
    this.add(p2);
    this.pack();
    this.setVisible(true);

}


private void start(int width, int height){
    p2.remove(p);
    for(int x = 0 ; x < rw ; x++) {
        for(int y = 0 ; y < rh ; y++) {
            p.remove(logicClass.label[x][y]);
        }
    }
    p2.remove(p3);
    p3.remove(newGameButton);
    this.remove(p2);
    MineSweeper(width, height);
}        

private void lose() {
  JOptionPane.showMessageDialog(this, "GAME OVER - YOU LOSE!  Starting New Game", "Game Over", JOptionPane.INFORMATION_MESSAGE);
  newGame();
}

private void win() {
  JOptionPane.showMessageDialog(this, "YOU WIN! Starting New Game", "CONGRATULATIONS", JOptionPane.INFORMATION_MESSAGE);
  newGame();
}


private void newGame() {
   if(mode==1){
       rw = 9;
       rh = 9;
       start(9,9);
    }else if(mode==2){
       rw = 15;
       rh = 15;
       start(15,15);
    }else{
       rw = 20;
       rh = 20;
       start(20,20);
    }
}


public void mouseClicked(MouseEvent e) {
   if(e.getSource() == newGameButton) {    
       if(e.getButton() == e.BUTTON1) {
           newGame();
        }
    }

   for (int x = 0 ; x < w; x++) {
       for (int y = 0 ; y < h; y++) {
           if(e.getSource() == logicClass.label[x][y]) {    
                if(e.getButton() == e.BUTTON1) {
                    if(logicClass.openCell(x, y) == false) {
                        lose();
                    } else {
                        for (int q = 0; q < w; q++) {
                            for (int j = 0; j < h; j++) {
                                if (logicClass.label[q][j].getBackground()==Color.green) {
                                    win();
                                }
                            }
                        }
                    }
               }else if(e.getButton() == e.BUTTON3) {
                   logicClass.markCell(x, y);
                    }
                }       
            }  
        }
     }

 private void selectDifficulty() {

    group.add(b1);
    group.add(b2);
    group.add(b3);
    group.add(b4);
    b1.setSelected(true);

    Object[] array = {new JLabel("Select Difficulty"),b1,b2,b3,b4};
    JOptionPane.showMessageDialog(null, array);

        if (b1.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 1;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 1;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 1;
            }
            start(9,9);

        }else if (b2.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 2;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 2;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 2;
            }
            start(15,15);
        }else if (b3.isSelected()) {
            if (mode == 1){
                rw = 9;
                rh = 9;
                mode = 3;    
            }else if(mode == 2){
                rw = 15;
                rh = 15;
                mode = 3;                    
            }else {
                rw = 20;
                rh = 20;
                mode = 3;
            }     
            start(20,20);
        }             
}    

public static void main(String[]args) {
    MineSweeperGUI guiClass = new MineSweeperGUI();
    guiClass.MineSweeper(9,9);
}

public void mouseEntered(MouseEvent e) {}

public void mousePressed(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}
}    

LOGIC CLASS:
import java.awt.* ;

public class MinesweeperLogic {

public int width, height;
private int w, h, maxBombs;
private boolean mine[][]; 
private boolean flag[][];
private boolean isClicked[][];
private boolean isZero[][];
private boolean marked;
MineSweeperGUI guiClass;
Button[][] label;
private int surBombs;
private String temp;
private double mineRatio;


public void startNewGame(int width, int height) {
    w = width;
    h = height;
    label = new Button[w][h];
    mine = new boolean[w][h];
    flag = new boolean[w][h];
    isClicked = new boolean[w][h];
    isZero = new boolean[w][h];
    if ( (w*h) <= 81) {
        mineRatio = 0.13;
    }else if ( (w*h) <= 255) {
        mineRatio = 0.16;
    }else {
        mineRatio = 0.2;
    }
    maxBombs = (int) Math.floor (w * h * mineRatio);
    for (int i = 0; i < maxBombs; i++) {
        int x = (int) (Math.random() * w);
        int y = (int) (Math.random() * h);
        if (mine[x][y] == false) {
            mine[x][y] = true;
            isClicked[x][y] = false;
            flag[x][y] = false;
            isZero[x][y] = false;
        } else {
            i--;
        }
    }       
}


int getWidth() {
    return w;
}


int getHeight() {
    return h;
}


boolean openCell(int x, int y) {                
    isClicked[x][y] = true;
    if (mine[x][y] == true   &&   flag[x][y] == false) {
        lose();
        return false;
    } else if (getValue(x, y) > 0   &&   flag[x][y] == false) {
        temp = Integer.toString (getValue(x, y));
        label[x][y].setLabel (temp);
        label[x][y].setBackground (new Color (111,184,252));
        checkWin();
        return true;
    } else if (getValue(x, y) == 0   &&   flag[x][y] == false) {
        for (int q = x-1; q <= x+1; q++) {                       
            if(q < 0   ||   q >= w) {                                        
            continue;
            }
            for (int i = y-1; i <= y+1; i++) {
                if(i < 0   ||   i >= h   ||   flag[q][i] == true) { // makes sure that it wont have an error for buttons next to the wall
                continue;
                }
                label[q][i].setBackground(new Color (111,184,252));
                if (getValue(q, i) != 0) { // opens surrounding cells that have mines around them (max 8 cells)
                temp = Integer.toString (getValue(q, i));
                label[q][i].setLabel (temp);
                isClicked[q][i] = true;
                } else {
                    for (int k = x-1; k <= x+1; k++) {
                        if(k < 0   ||   k >= w) {
                        continue;
                        }
                            for (int m = y-1; m <= y+1; m++) {
                                if (m < 0   ||   m >= h   ||   flag[k][m] == true) { // makes sure that it wont have an error for buttons next to the wall
                                continue;
                                }
                                if (isClicked[k][m] == false   &&   getValue(k, m) == 0) { // recursively continues to open all surrounding cells with no mines around them
                                    openCell(k, m);
                                }
                            }
                        }
                    }
                }
            }
            checkWin(); 
            return true;
            } else {
                return true;
            }
      }           


boolean markCell(int x, int y) {
    if (flag[x][y] == true) {
        flag[x][y] = false;
        label[x][y].setLabel ("");
        label[x][y].setForeground (Color.black);
        label[x][y].setFont (new Font (null, Font.PLAIN, 12));
        return false;
    }
    if (isClicked[x][y] == false && flag[x][y] == false) {
        flag[x][y] = true;
        label[x][y].setFont (new Font ("sansserif", Font.BOLD, 14));
        label[x][y].setLabel ("<|");
        label[x][y].setForeground (Color.red);
    }
    if (mine[x][y] == true) {
        return true;
    } else {
        return false;
    }
}


boolean isOpen(int x, int y) {
    if (isClicked[x][y] == false) {
        return false;
       } else {
           return true;
       }
}


boolean isMarked(int x, int y) {
    if (flag[x][y] == true) {
        return true;
       } else {
           return false;
       }
}


int getValue(int x, int y) {
     if (mine[x][y] == true) {
         return -1;
       } else {
           return neighborBombs(x, y);
       }
   }


private int neighborBombs(int x, int y) {  // checks surrounding 8 squares for number of bombs (it does include itself, but has already been checked for a bomb so it won't matter)
      surBombs = 0;
          for (int q = x-1; q <= x+1; q++) {
              if (q < 0   ||   q >= w) {
                  continue;
              }
                  for (int i = y-1; i <= y+1; i++) {
                      if (i < 0   ||   i >= h) { // makes sure that it wont have an error for buttons next to the wall
                          continue;
                      }
                      if (mine[q][i] == true) {
                         surBombs++;
                      }
                  }   
              }          
       return surBombs;
      }


private void lose() {
    for (int q = 0; q < w; q++) {
        for (int j = 0; j < h; j++) {
            if (mine[q][j] == true) {
                if (label[q][j].getLabel().equals ("<|")) {
                    label[q][j].setBackground (Color.green);
                } else {
                    label[q][j].setBackground (Color.red);
                    label[q][j].setLabel ("*");
                    label[q][j].setForeground (Color.black);
                }


            }
        }
    }
 }


private void checkWin() {
    int count = 0;
    int count2 = 0;
    for (int i = 0; i < w; i++){
        for (int j = 0; j < h; j++) {
            if (isClicked[i][j] == true){
                count++;    
            }
            if (mine[i][j] == true){
                count2++;
            }
        }
    }
    if ( (count + count2) == (w * h) ){
        win();
    }
 }       


private void win() {
    for (int q = 0; q < w; q++) {
        for (int j = 0; j < h; j++) {
            if (mine[q][j] == true) {
                label[q][j].setBackground (Color.green);
                label[q][j].setForeground (Color.red);
                label[q][j].setFont (new Font ("sansserif", Font.BOLD, 14));
                label[q][j].setLabel ("<|");
            }
        }
    }
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

太阳哥哥 2024-08-24 07:18:10

您在 start 的末尾调用 MineSweeper(width, height) (应该是小写,因为它是一个方法),您在 selectDifficulty 中调用它。

MineSweeper 会创建新的所有组件。 optionsButton 不是新创建的,因此您向其添加另一个 ActionListener。当您按下按钮时,每个 ActionListener 都会被调用,因此 selectDifficulty 被调用的次数越来越多。

最简单的解决方法是将此 ActionListener 添加到 MineSweeperGUI 的构造函数中,但您应该重构源代码,尽可能仅创建所有组件一次。至少整个菜单应该转到构造函数。

You call MineSweeper(width, height) (should be lowercase as it is a method) at the end of start, which you call in selectDifficulty.

MineSweeper creates all your components new. optionsButton is not created new, so you add another ActionListener to it. Every ActionListener is called when you press the button, so selectDifficulty is called more and more times.

The easiest workaround is to put adding this ActionListener into the constructor of MineSweeperGUI, but you should refactor your source to create all Components only once where possible. At least the whole menu should go to the constructor.

一张白纸 2024-08-24 07:18:10

尝试设置菜单组件(JMenuBar 和子组件)一次,而不是每次调用 MineSweeper 时。顺便说一句,我认为这是一个构造函数,所以它也可能会让其他 Java 开发人员感到困惑。

这是因为 actionPerformed 可能会被多次调用。

Try setting your menu component (JMenuBar and children) up once instead of each time MineSweeper is being called. I thought that was a constructor, btw, so it may confuse other Java developers too.

This is because the actionPerformed may be getting invoked more than once.

感性 2024-08-24 07:18:10

你把它变得非常复杂,Java是一种面向对象的语言,尝试根据这些对象的属性/操作将你的工作分成对象。

不管怎样,对于你的难度对话有两个建议。

  • 要么你把这 3 个困难放在菜单本身中。因此,下拉菜单具有初级、中级或困难模式,以及可打开 JPanel 对话框的自定义模式。
  • 或者你继续你的方法,但需要做一些改变。主要是将消息对话框从主 GUI 中分离出来并创建一个新类,比如 OptionsDialog 本身扩展了 JDialog。在 OptionsDialog 的构造函数中发送对父框架的引用。设置难度后,调用父级的方法来设置难度。

You are making it much complicated, Java is an object oriented language, try to separate your work into objects based on properties/actions of those objects.

Anyway, two suggestion for your difficulty dialog.

  • Either you put the 3 difficulties in the menu itself. So the drop down menu, has Beginner,Medium or Hard modes, with a custom mode that opens a JPanel dialog.
  • Or You keep on your method but will need to do some changes. Mainly split the message dialog off of they main GUI and create a new class, lets say OptionsDialog which extends JDialog by itself. In the constructor of the OptionsDialog send a reference to the parent frame. After setting the difficulty call a method on the parent to set the difficulty there.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文