Java开发扫雷小游戏

用原生的Java来开发了以下经典小游戏扫雷,作为初学Java的练手。

主要代码是有三个类:setting类存放游戏的一些设定,Map是new一个游戏开始的框架,MapFrame是游戏框架以及响应点击等方法。

以下是3个类的代码,初学者写的代码难免有许多不成熟的地方,请各位轻喷。

setting

 1 package map;
 2 
 3 public class Setting {
 4     public int row;
 5     public int col;
 6     public int mine;
 7     public Setting(int row,int col,int mine) {
 8         this.row=row;
 9         this.col=col;
10         this.mine=mine;
11     }
12 }

Map

 1 package map;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 import java.util.Random;
 6 
 7 public class Map {
 8     public static final int[] dx=new int[]{-1,-1,-1,0,1,1,1,0};
 9     public static final int[] dy=new int[]{-1,0,1,1,1,0,-1,-1};
10     public Setting setting;
11     public int[][] map;
12     
13     public Map() {
14         NewMap();
15     }
16     
17     public static void NewMap() {
18         Setting setting=new Setting(9,9,10);
19         EventQueue.invokeLater(()->{
20             JFrame frame=new MapFrame(setting);
21             frame.setTitle("Minesweeper");
22             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
23             frame.setVisible(true);
24         });        
25     }
26 }

MapFrame

  1 package map;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import java.awt.geom.*;
  6 
  7 import javax.swing.*;
  8 import javax.swing.border.Border;
  9 
 10 import java.util.LinkedList;
 11 import java.util.Queue;
 12 import java.util.Random;
 13 
 14 public class MapFrame extends JFrame {
 15     public int row,col,mine;
 16     public int[][] map;
 17     public boolean[][] visit;
 18     public JButton[][] mine_button;
 19     public static final int[] dx=new int[] {-1,0,1,0,-1,-1,1,1};
 20     public static final int[] dy=new int[] {0,1,0,-1,-1,1,1,-1};
 21     
 22     public int total_visit;
 23     
 24     public MapFrame(Setting setting) {
 25         this.row=setting.row; this.col=setting.col; this.mine=setting.mine; 
 26         this.map=calc_map(setting);
 27         mine_button=new JButton[row][col];
 28         visit=new boolean[row][col];
 29         total_visit=0;
 30         int fwidth=row/9*400,fheight=col/9*400+70;
 31         setSize(fwidth,fheight);
 32         JPanel TimeJpanel=new JPanel();
 33         JPanel MapJpanel=new JPanel();
 34         
 35         JLabel TimeText=new JLabel("Time : 0");
 36         TimeJpanel.add(TimeText);
 37         
 38         myTimer timer =new myTimer(TimeText);
 39         Timer timelistener =new Timer(1000,timer);
 40         timelistener.start();  //开始定时器
 41         
 42         MapJpanel.setPreferredSize(new Dimension(row/9*400,col/9*400));
 43         MapJpanel.setLayout(new GridLayout(row,col));
 44         for (int i=0;i<row*col;i++) {
 45             int x=i/this.col;
 46             int y=i%this.row;
 47             mine_button[x][y]=new JButton();
 48             mine_button[x][y].setBackground(new Color(81,168,221));
 49             mine_button[x][y].addActionListener(new click_listener(x,y));
 50             MapJpanel.add(mine_button[x][y]);
 51         }
 52         
 53         setLayout(new BorderLayout());
 54         add(TimeJpanel,BorderLayout.NORTH);
 55         add(MapJpanel,BorderLayout.SOUTH);        
 56     }
 57     
 58     class click_listener implements ActionListener {
 59         public int x,y;
 60         public click_listener(int x,int y) {
 61             this.x=x; this.y=y;
 62         }
 63         
 64         public void actionPerformed(ActionEvent event) {
 65             if (visit[this.x][this.y]) return;
 66             int num=map[this.x][this.y];
 67             if (num!=-1) {
 68                 mine_button[this.x][this.y].setBackground(Color.WHITE);
 69                 if (num==0) whitebfs(this.x,this.y);
 70                 else {
 71                     if (!visit[this.x][this.y]) total_visit++; visit[this.x][this.y]=true;
 72                     mine_button[this.x][this.y].setText(""+num);
 73                 }
 74                 if (total_visit+mine==row*col) {
 75                     //游戏成功
 76                     int selection=JOptionPane.showConfirmDialog(null,"你成功排掉所有雷,是否重新开始?","游戏成功",
 77                             JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
 78                     if (selection==JOptionPane.YES_OPTION) {
 79                         //重新开始游戏
 80                         dispose();
 81                         Map.NewMap();
 82                     }
 83                 }
 84             } else {
 85                 //游戏失败
 86                 mine_button[this.x][this.y].setIcon(new ImageIcon("./Image/mine.jpg"));
 87                 int selection=JOptionPane.showConfirmDialog(null,"你踩到雷了,是否重新开始?","游戏失败",
 88                         JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
 89                 if (selection==JOptionPane.YES_OPTION) {
 90                     //重新开始游戏    
 91                     dispose();
 92                     Map.NewMap();
 93                 }
 94             }
 95         }
 96     
 97         public void whitebfs(int x,int y) {
 98              Queue<Integer> q=new LinkedList<>();
 99              q.offer(x*col+y);
100              while (q.size()>0) {
101                  int now=q.poll();
102                  x=now/col; y=now%col;
103                  if (!visit[x][y]) total_visit++; visit[x][y]=true;
104                  mine_button[x][y].setBackground(Color.WHITE);
105                  around(x,y);
106                  for (int i=0;i<4;i++) {
107                      int tx=x+dx[i],ty=y+dy[i];
108                      if (tx<0 || tx>=row || ty<0 || ty>=col) continue;
109                      if (visit[tx][ty]) continue;
110                      if (map[tx][ty]!=0) continue;
111                      q.offer(tx*col+ty);
112                  }
113              }
114         }
115         
116         public void around(int x,int y) {
117             for (int i=0;i<8;i++) {
118                 int tx=x+dx[i],ty=y+dy[i];
119                 if (tx<0 || tx>=row || ty<0 || ty>=col) continue;
120                 if (map[tx][ty]>0) {
121                     if (!visit[tx][ty]) total_visit++; visit[tx][ty]=true;
122                     mine_button[tx][ty].setBackground(Color.WHITE);
123                     if (map[tx][ty]>0)mine_button[tx][ty].setText(""+map[tx][ty]);
124                 }
125             }
126         }
127     }
128     
129     /**
130      * 计时器
131      */
132     class myTimer implements ActionListener {
133         JLabel text;
134         long start;
135         public myTimer(JLabel text) {
136             this.text=text;
137             start=System.currentTimeMillis();
138         }
139         public void actionPerformed(ActionEvent event) {
140             text.setText("Time : "+(System.currentTimeMillis()-start)/1000);
141         }
142     }
143     
144     /**
145      * 计算map数字大小
146      */
147     public int[][] calc_map(Setting setting) {
148         int[][] map=new int[setting.row+2][setting.col+2];
149         for (int i=0;i<=setting.row+1;i++)
150             for (int j=0;j<=setting.col+1;j++)
151                 map[i][j]=0;
152         
153         int now_mine=0;
154         Random rand=new Random(System.currentTimeMillis());
155         while (now_mine<setting.mine) {
156             int mine_x=rand.nextInt(setting.row);
157             int mine_y=rand.nextInt(setting.col);
158             if (map[mine_x][mine_y]==0) {
159                 map[mine_x][mine_y]=-1;
160                 now_mine++;
161             }
162         }
163         
164         for (int i=1;i<=setting.row;i++)
165             for (int j=1;j<=setting.col;j++) {
166                 if (map[i][j]==-1) continue;
167                 for (int k=0;k<8;k++) map[i][j]+=(map[i+dx[k]][j+dy[k]]==-1 ? 1 : 0);
168             }    
169         
170         return map;
171     }
172 }

猜你喜欢

转载自www.cnblogs.com/clno1/p/12451128.html