2016-09-26 40 views
1

我已经在这段代码上工作了好几个小时,终于完成了Ver。一旦我找出如何增加用右键点击地雷的能力,我会加入一个地雷计数器和一个计时器。我了解到JButtons不承认右键点击,所以我必须使用MouseEvent。从那里,我迷路了。有人能给我一个正确的方向吗?用于扫雷的GUI游戏的标记按钮

这是我目前有:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 

public class MineSweeper implements ActionListener { 

    JFrame frame = new JFrame("Mine Sweeper"); 
    JButton reset = new JButton("Reset"); 
    JButton[][] buttons = new JButton[20][20];//button array 
    JButton[] flags = new JButton[20]; 
    int[][] counts = new int[20][20]; 
    Container grid = new Container(); //grid for buttons 
    int MineNum = 50;//number of mines 
    final int MINE = 10;//int value to identify a mine 



    public MineSweeper() { 
     frame.setSize(500, 500); 
     frame.setLayout(new BorderLayout()); 
     frame.add(reset, BorderLayout.NORTH); 
     reset.addActionListener(this); 
     //Grid of Buttons 
     grid.setLayout(new GridLayout(20,20)); 
     for (int a = 0; a<buttons.length; a++) { 
      for (int b = 0; b < buttons[0].length; b++) { 
       buttons[a][b] = new JButton("▒"); 
       buttons[a][b].addActionListener(this); 
       buttons[a][b].addMouseListener(new MouseAdapter() { 
        @Override 
        public void mousePressed(MouseEvent e) { 
         if (e.getButton() == MouseEvent.BUTTON3) { 
          mineFlagger(true); 
         } 
        } 
       }); 
       grid.add(buttons[a][b]); 
      } 
     } 
     frame.add(grid, BorderLayout.CENTER); 
     makeRandomMines(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 

    public void mineFlagger (boolean flag){ 
     for (int i = 0; i < buttons.length; i++) { 
      for (int j = 0; j < buttons[0].length; j++) { 
       if(flag == true) { 
        buttons[i][j].setText("F"); 
       } 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new MineSweeper(); 
    } 

    public void makeRandomMines() { 
     //initializes list of random pairs 
     ArrayList<Integer> list = new ArrayList<Integer>(); 
     for (int x = 0; x < counts.length; x++) { 
      for (int y = 0; y < counts[0].length; y++) { 
       list.add(x * 100 + y);//changed y to x 
      } 
     } 
     //resets the counts in case reset button is pressed & picks random mines 
     counts = new int[20][20]; 
     for (int i = 0; i < MineNum; i++) { 
      int choice = (int) (Math.random() * list.size()); 
      counts[list.get(choice)/100][list.get(choice) % 100] = MINE; 
      list.remove(choice); 
     } 
     //neighbor counts(how many mines are touching this square.) 
     for (int x = 0; x < counts.length; x++) { 
      for (int y = 0; y < counts[0].length; y++) { 
       int neighborCount = 0; 
       if (counts[x][y] != MINE) { 
        if(x > 0 && y > 0 && counts[x - 1][y - 1] == MINE) { //a mine is up & left 
         neighborCount++; 
        } 
        if(y > 0 && counts[x][y - 1] == MINE) { //a mine is up 
         neighborCount++; 
        } 
        if(x < counts.length - 1 && y > 0 && counts[x + 1][y - 1] == MINE) { // a mine is left 
         neighborCount++; 
        } 
        if(x > 0 && counts[x - 1][y] == MINE) { //left 
         neighborCount++; 
        } 
        if(x < counts.length - 1 && counts[x + 1][y] == MINE) { //mine is right 
         neighborCount++; 
        } 
        if(x > 0 && y < counts[0].length - 1 && counts[x - 1][y + 1] == MINE) { //mine is down 
         neighborCount++; 
        } 
        if(y < counts[0].length - 1 && counts[x][y + 1]== MINE) {//mine is up right 
         neighborCount++; 
        } 
        if(x < counts[0].length - 1 && y < counts[0].length - 1 && counts[x + 1][y + 1]== MINE) {//mine is down left 
         neighborCount++; 
        } 
        counts[x][y] = neighborCount; 
       } 
      } 
     } 
    } 

    public void lostGame() { 
     for (int x = 0; x < buttons.length; x++) { 
      for (int y = 0; y < buttons[0].length; y++) { 
       if (buttons[x][y].isEnabled()) { 
        if (counts[x][y] != MINE) { 
         buttons[x][y].setText(counts[x][y] + ""); 
         buttons[x][y].setEnabled(false); 
        } 
        else { 
         buttons[x][y].setText("✪"); 
         buttons[x][y].setEnabled(false); 
        } 
       } 
      } 
     } 
     JOptionPane.showMessageDialog(null, "You Lose!\n" + "You clicked on a mine!", "BOOM!", JOptionPane.INFORMATION_MESSAGE); 
    } 

    public void checkWin() { 
     boolean winner = true; 

     for (int x = 0; x < counts.length; x++) { 
      for (int y = 0; y < counts[0].length; y++) { 
       if (counts[x][y] != MINE && buttons[x][y].isEnabled()) { 
        winner = false; 
       } 
      } 
     } 
     if (winner == true) { 
      JOptionPane.showMessageDialog(frame, "You win!"); 
     } 
    } 

    public void zeroCleaner(ArrayList<Integer> toClear) { 
     if (toClear.size() == 0) { 
      return; 
     } 
     else { 
      int x = toClear.get(0)/100; 
      int y = toClear.get(0) % 100; 
      toClear.remove(0); 
      if(x > 0 && y > 0 && buttons[x-1][y-1].isEnabled()) { //up and left 
       buttons[x - 1][y - 1].setText(counts[x-1][y-1] + ""); 
       buttons[x - 1][y - 1].setEnabled(false); 
       if (counts[x - 1][y - 1] == 0) { 
        toClear.add((x-1) * 100 + (y-1)); 
       } 
      } 
      if (y > 0 && buttons[x][y-1].isEnabled()) { // up 
       buttons[x][y - 1].setText(counts[x][y-1] + ""); 
       buttons[x][y - 1].setEnabled(false); 
       if (counts[x][y - 1] == 0) { 
        toClear.add(x * 100+(y - 1)); 
       } 
      } 
      if (x < counts.length - 1 && y > 0 && buttons[x+1][y-1].isEnabled()) { //up right 
       buttons[x + 1][y - 1].setText(counts[x+1][y-1] + ""); 
       buttons[x + 1][y - 1].setEnabled(false); 
       if (counts[x + 1][y - 1] == 0) { 
        toClear.add((x + 1)*100+(y - 1)); 
       } 
      } 
      if(x > 0 && y > 0 && buttons[x-1][y].isEnabled()) { //left 
       buttons[x - 1][y].setText(counts[x-1][y] + ""); 
       buttons[x - 1][y].setEnabled(false); 
       if (counts[x-1][y] == 0) { 
        toClear.add((x-1)*100+y); 
       } 
      } 
      if (x < counts.length - 1 && buttons[x+1][y].isEnabled()) { //right 
       buttons[x + 1][y].setText(counts[x+1][y] + ""); 
       buttons[x + 1][y].setEnabled(false); 
       if (counts[x + 1][y] == 0) { 
        toClear.add((x + 1)*100+y); 
       } 
      } 
      if(x > 0 && y < counts[0].length - 1 && buttons[x-1][y+1].isEnabled()) { //down and left 
       buttons[x - 1][y + 1].setText(counts[x-1][y+1] + ""); 
       buttons[x - 1][y + 1].setEnabled(false); 
       if (counts[x-1][y+1] == 0) { 
        toClear.add((x-1)*100+(y+1)); 
       } 
      } 
      if (y < counts[0].length - 1 && buttons[x][y+1].isEnabled()) { // down 
       buttons[x][y + 1].setText(counts[x][y+1] + ""); 
       buttons[x][y + 1].setEnabled(false); 
       if (counts[x][y + 1] == 0) { 
        toClear.add(x * 100+(y + 1)); 
       } 
      } 
      if (x < counts.length - 1 && y < counts[0].length - 1 && buttons[x+1][y+1].isEnabled()) { //down right 
       buttons[x + 1][y + 1].setText(counts[x+1][y+1] + ""); 
       buttons[x + 1][y + 1].setEnabled(false); 
       if (counts[x + 1][y + 1] == 0) { 
        toClear.add((x + 1)*100+(y + 1)); 
       } 
      } 
      zeroCleaner(toClear); 
     } 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
     if(event.getSource().equals(reset)) { 
     //Resets the playing field 
      for (int x = 0; x < buttons.length; x++) { 
       for (int y = 0; y < buttons[0].length; y++) { 
        buttons[x][y].setEnabled(true); 
        buttons[x][y].setText("▒"); 
       } 
      } 
      makeRandomMines(); 
     } 
     else { 
      for (int x = 0; x < buttons.length ; x++) { 
       for (int y = 0; y < buttons[0].length; y++) { 
        if(event.getSource().equals(buttons[x][y])) { 
         if (counts[x][y]== MINE) { 
          lostGame(); 
         } 
         else if(counts[x][y] == 0) { 
          buttons[x][y].setText(counts[x][y]+ ""); 
          buttons[x][y].setEnabled(false); 
          ArrayList<Integer> toClear = new ArrayList<>(); 
          toClear.add(x*100+y); 
          zeroCleaner(toClear); 
          checkWin(); 
         } 
         else { 
          buttons[x][y].setText(counts[x][y]+ ""); 
          buttons[x][y].setEnabled(false); 
          checkWin(); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

我不明白你的问题。您已经有了检查哪个按钮被按下的代码:'e.getButton()== MouseEvent.BUTTON3' – Jhonny007

+0

@ Jhonny007'MouseEvent.BUTTON3'不明确。 Button3可能因鼠标/操作系统等而异......另外,他问的是如何将检测到的右键点击与其悬停的按钮绑定。因为如他所说,按钮不能直接检测到右键单击。 – Cutter

+1

可能重复 - 'http://stackoverflow.com/questions/2006188/right-click-on-jbutton' – Cutter

回答

1

这应该解决您的问题:

for (int a = 0; a<buttons.length; a++) { 
    for (int b = 0; b < buttons[0].length; b++) { 
     buttons[a][b] = new JButton("▒"); 
     buttons[a][b].addActionListener(this); 
     final int finalB = b; 
     final int finalA = a; 
     buttons[a][b].addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       if (SwingUtilities.isRightMouseButton(e)) { 
        mineFlagger(true, finalA, finalB); 
       } 
      } 
     }); 
     grid.add(buttons[a][b]); 
    } 
} 


public void mineFlagger (boolean flag, int x, int y){ 
    buttons[x][y].setText("F"); 
} 

编辑:用于切换的标志(懒惰实现)

if (SwingUtilities.isRightMouseButton(e)) { 
    mineFlagger(finalA, finalB); 
} 

public void mineFlagger(int x, int y) { 
    if(buttons[x][y].getText().equals("F")) { 
     buttons[x][y].setText("▒"); 
    } else if (buttons[x][y].getText().equals("▒")){ 
     buttons[x][y].setText("F"); 
    } 
} 
+0

这工作!谢谢!我怎么能做到这一点,当再次右键单击它恢复正常? – baileyr12

+0

我也为这个问题添加了一个解决方案,尽管这不是一个很好的方法。 – Jhonny007

0

如果导入“javax.swing.SwingUtilities中的”你可以使用一些工具方法:

SwingUtilities.isRightMouseButton(MouseEvent anEvent) 

然后在按下鼠标右键,获取鼠标的位置,找到该位置的按钮,然后使用该事件将该特定按钮上的图片更改为标志图片。

你可以使用:

MouseInfo.getPointerInfo().getLocation() 

要获得鼠标相对于屏幕上的位置。