- 最後登錄
- 2024-8-24
- 在線時間
- 2 小時
- 註冊時間
- 2017-11-8
- 閱讀權限
- 30
- 精華
- 0
- UID
- 7621878
- 帖子
- 3
- 積分
- 1335 點
- 潛水值
- 40670 米
| 本帖最後由 z810520 於 2019-6-13 08:56 AM 編輯
小弟是Java新手,正在試著寫一個踩地雷的程式,裡面用到Swing跟MouseListener。
我希望當我按的按鈕的周圍沒有地雷時程式能夠自動把周圍也踩過,但我用的DoClick()無法如我預期的運作,我上網查了相關資料,但還是沒看出問題點,還請各位幫忙,謝謝。
- import java.awt.event.*;
- import java.awt.*;
- import javax.swing.*;
- public class NewMineSweeperOnSwing {
-
- private static void createAndShowGUI() {
- JFrame.setDefaultLookAndFeelDecorated(true);
- JFrame frame = new JFrame("MineSweeper");//大標題
- frame.setSize(500,500);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
- frame.setVisible(true);
- JPanel p = new JPanel();
- p.setLayout(new BorderLayout());
-
- int h = 10, w = 10, m = 10;
- Board board = new Board(h, w, m);
-
- JPanel top = new JPanel();
- top.add(board.jl);
- frame.add(top);
-
- JPanel field = new JPanel();
- field.setLayout(new GridLayout(h, w));
-
- for(int i = 0; i < h; i++){//setting field
- for(int j = 0; j < w; j++){
- board.getBlock(i,j).addMouseListener(new sweep2(board, i, j));
-
- field.add(board.getBlock(i,j));
- }
- }
-
- for(int i = 0; i < m; i++){//setting mines
- int x = (int)(Math.random()*h);
- int y = (int)(Math.random()*m);
- if(board.getBlock(x,y).getNumber() != -1){
- board.getBlock(x,y).setNumber(-1);
- System.out.print(" "+x+y);//take out later
- }
- else i--;
- }
-
- for(int i = 0; i < h; i++){//setting number of mines
- for(int j = 0; j < w; j++){
- if(board.getBlock(i,j).getNumber() != -1){
- int n = 0;
- for(int x = Math.max(0, i-1); x < Math.min(h,i+2); x++){
- for(int y = Math.max(0, j-1); y < Math.min(w,j+2); y++){
- if(((i != x) || (j != y)) && board.getBlock(x,y).getNumber() == -1) n++;
- }
- }
- board.getBlock(i,j).setNumber(n);
- }
- }
- }
-
- p.add(top, BorderLayout.NORTH);
- p.add(field, BorderLayout.CENTER);
- frame.setContentPane(p);
- }
- public static void main(String[] args) {
- //GUI
- javax.swing.SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- createAndShowGUI();
- }
- });
- }
- }
- @SuppressWarnings("serial") class Block extends JButton{
- private int number;//0~8 for number of mines around, -1 for mine
- private int status;//0 for covered, 1 for flagged, 2 for uncovered
-
- Block(){}//int = 0 by default
-
- public int getNumber(){return number;}
- public int getStatus(){return status;}
- public void setNumber(int n){number = n;}
- public void setStatus(int s){status = s;}
- }
- class Board{
- private Block[][] b;// all the blocks
- private int h, w, m, bl, r;//height, width, mines, blocks left, result : 0 for not finished, 1 for win, 2 for lose
- public JLabel jl;//label on top showing number of mines left
-
- Board(){}
- Board(int height, int width, int mines){
- h = height;
- w = width;
- m = mines;
- bl = h * w - m;
- b = new Block[h][w];
- jl = new JLabel(""+m);
-
- for(int i = 0; i < h; i++){//setting board
- for(int j = 0; j < w; j++){
- b[i][j] = new Block();
- }
- }
- }
-
- public int getHeight(){return h;}
- public int getWidth(){return w;}
- public int getMines(){return m;}
- public int getBlocksLeft(){return bl;}
- public Block[][] getBlock(){return b;}
- public Block getBlock(int i, int j){return b[i][j];}
- public int getResult(){return r;}
- public void setBlocksLeft(int n){bl = n;}
- public void setResult(int i){r = i;}
- }
- class sweep implements MouseListener{
- sweep(){}
-
- public void mouseClicked(MouseEvent e){}
- public void mouseEntered(MouseEvent e){}
- public void mouseExited(MouseEvent e){}
- public void mousePressed(MouseEvent e){}
- public void mouseReleased(MouseEvent e){}
-
- }
- class sweep2 extends sweep{
- int h, w, x, y;
- Board board;
- Block[][] b;
- JLabel l;
-
- sweep2(){}
- sweep2(Board board, int i, int j){
- x = i;
- y = j;
- this.board = board;
- b = board.getBlock();
- h = b.length;
- w = b[0].length;
- l = board.jl;
- }
-
- @Override public void mouseClicked(MouseEvent e) {
-
- if(board.getResult() == 0){//games not finished
-
- if (e.getButton() != MouseEvent.BUTTON3 && b[x][y].getStatus() == 0) {//left click on normal block(autoclick???)
- if(b[x][y].getNumber() != -1){//not bomb
- b[x][y].setStatus(2);
- b[x][y].setBackground(Color.WHITE);
- board.setBlocksLeft(board.getBlocksLeft() - 1);
-
- if(b[x][y].getNumber() == 0){//click all blocks around if they are not mines
- for(int i = Math.max(0, x-1); i < Math.min(h,x+2); i++){
- for(int j = Math.max(0, y-1); j < Math.min(w,y+2); j++){
- if((i != x) || (j != y)) b[i][j].doClick();
- }
- }
- }
- else//show number of mines around
- b[x][y].setText(""+b[x][y].getNumber());
- }
-
- else{//is bomb
- b[x][y].setText("B");
- b[x][y].setBackground(Color.RED);
- l.setText("(XP)");
- board.setResult(2);
- }
-
- if(board.getBlocksLeft() == 0){
- l.setText("(:D)");
- board.setResult(1);
- }
- }
-
- else if (e.getButton() == MouseEvent.BUTTON3) {//right click
- if(b[x][y].getStatus() == 0){
- b[x][y].setStatus(1);
- b[x][y].setText("F");
- int t = Integer.parseInt(l.getText());
- l.setText(t-1+"");
- }
- else if(b[x][y].getStatus() == 1){
- b[x][y].setStatus(0);
- b[x][y].setText("");
- int t = Integer.parseInt(l.getText());
- l.setText(t+1+"");
- }
- }
- }
- }
- }
複製代碼
補充內容 (2019-6-6 10:06 AM):
目前看來是doClick()無法觸發mouseListener,但我的程式會用到左鍵跟右鍵,所以不能用actionListener,有什麼建議嗎?
補充內容 (2019-6-13 08:56 AM):
已自行解決,只要new個新物件就好了... |
|