事先聲明:本人是一位剛接觸Java不久的菜鳥,所以代碼寫的略顯臃腫,敬請諒解!這個掃雷是我在暑假時做的,靈感來源於csdn上某位大神的博客,不過我個人實在不喜歡他的代碼實現,於是我自己寫了一個實現上不同的掃雷。
這是那位大牛那篇掃雷的博客鏈接:http://blog.csdn.net/su20145104009/article/details/52152514,有興趣的可以去瀏覽下。
程序:主界面上和Windows經典的那款掃雷很像,正上方有一個笑臉按鈕,用於游戲重啟,下面是雷區,用一個繼承於JButton組件的類型實現。笑臉按鈕兩側,一側用JLabel顯示剩余雷數,一側用JLabel顯示使用的時間。菜單欄上有難度設置,也是仿制windows經典掃雷的難度設置,即9*9,16*16,30*16三種級別。之所以叫乞丐版主要是左右同時敲擊鼠標不能敲開周圍的塊而且沒有排名並且記錄的那個功能。
P.S.:用的好端端的edge瀏覽器TMD崩了,我真他們是CTM,我本來寫的一大堆程序解釋瞬間消失,算了我還是直接講最主要算法吧。(這一下弄得我實在是沒有熱情再寫那么詳細了,我明明已經快寫完了。第一次草稿保存的是如上內容,晚上修改的后面的所有全沒了。網頁崩了而我的系統屁事兒沒有依舊飛快運轉。。。。我可是在熬夜寫這個啊)
主要難點在於如何判斷點擊后如何判斷九宮格的位置,要引入兩個值,edgeU和edgeD(不偏不倚這兩個值我還真的給他們起名為edge,看着就來氣),在雷區內總有些位置很尷尬它們周圍並沒有形成完全的九宮格,不過沒有關系。因為在整個區域內只用兩條豎邊很特殊,它們的前一個或者后一個不一定在它們的左邊或者右邊,這個時候利用上面那兩個值就很管用了,具體怎么用的我不想講了,請自己去看代碼吧(熱情實在是被澆滅了。。。)在判斷完九宮格內雷數后,你還要展開周圍沒有雷的地方(被展開的周圍如有空位置也要一起展開),具體實現也請看代碼。
1 import javax.swing.ImageIcon; 2 import javax.swing.JButton; 3 import javax.swing.JFrame; 4 import javax.swing.JLabel; 5 import javax.swing.JMenu; 6 import javax.swing.JMenuBar; 7 import javax.swing.JMenuItem; 8 import javax.swing.JPanel; 9 import java.awt.Font; 10 import java.awt.GridLayout; 11 import java.awt.event.ActionEvent; 12 import java.awt.event.ActionListener; 13 import java.util.ArrayList; 14 import java.awt.event.MouseEvent; 15 import java.awt.event.MouseListener; 16 import java.util.Random; 17 18 public class Main extends JFrame implements MouseListener{ 19 private int screenwide; 20 private int screenhigh; 21 private int colNum; 22 private int rowNum; 23 private int mineNum; 24 private int restNum; 25 private int min = 0;//分鍾 26 private int sec = 0;//秒鍾 27 private JLabel label1;//顯示時間用 28 private JLabel label2;//顯示剩余雷數 29 private JButton button;//笑臉按鈕,用於重新開始 30 private String gameState = "run";//游戲運行狀態 31 private boolean isfirst = true;//判斷是否是第一次按下 32 //難度選擇菜單 33 private JMenuBar menuBar; 34 private JMenu menu; 35 private JMenuItem low; 36 private JMenuItem mid; 37 private JMenuItem high; 38 //核心模塊 39 private ArrayList<Bub>list = new ArrayList<Bub>(0); 40 public boolean isFirst() { 41 return isfirst; 42 } 43 public void initMenu() { 44 menuBar = new JMenuBar(); 45 menu = new JMenu("難度設置"); 46 low = new JMenuItem("初級(10)"); 47 mid = new JMenuItem("中級(40)"); 48 high = new JMenuItem("高級(99)"); 49 low.addActionListener(new ActionListener() { 50 public void actionPerformed(ActionEvent e) { 51 dispose(); 52 new Main(10); 53 } 54 }); 55 mid.addActionListener(new ActionListener() { 56 public void actionPerformed(ActionEvent e) { 57 dispose(); 58 new Main(40); 59 } 60 }); 61 high.addActionListener(new ActionListener() { 62 public void actionPerformed(ActionEvent e) { 63 dispose(); 64 new Main(99); 65 } 66 }); 67 menu.add(low); 68 menu.add(mid); 69 menu.add(high); 70 menuBar.add(menu); 71 setJMenuBar(menuBar); 72 } 73 class stopwatch extends Thread{ 74 public void run() { 75 while(gameState.equals("run")) { 76 try { 77 Thread.sleep(1000); 78 }catch(InterruptedException e) { 79 e.printStackTrace(); 80 } 81 sec++; 82 if(sec==60) { 83 sec=0; 84 min++; 85 } 86 if(min==0&&sec<10)label1.setText("00:0"+new Integer(sec).toString()); 87 if(min==0&&sec>=10)label1.setText("00:"+new Integer(sec).toString()); 88 if(min>0&&sec<10)label1.setText(new Integer(min).toString()+":0"+new Integer(sec).toString()); 89 if(min>0&&sec>=10)label1.setText(new Integer(min).toString()+":"+new Integer(sec).toString()); 90 } 91 } 92 } 93 public Main(int num) { 94 super("掃雷"); 95 mineNum = num; 96 restNum = mineNum; 97 if(mineNum == 10) { 98 screenwide = 200; 99 screenhigh = 290; 100 colNum = 9; 101 rowNum = 9; 102 } 103 if(mineNum == 40) { 104 screenwide = 340; 105 screenhigh = 430; 106 colNum = 16; 107 rowNum = 16; 108 } 109 if(mineNum == 99) { 110 screenwide = 620; 111 screenhigh = 430; 112 colNum = 30; 113 rowNum = 16; 114 } 115 initMenu(); 116 setSize(screenwide,screenhigh); 117 setLayout(null); 118 setLocationRelativeTo(null); 119 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 120 121 button = new JButton(new ImageIcon("D:\\學習文檔\\smile1.jpg")); 122 button.setBounds(screenwide/2-20, 5, 20, 20); 123 button.addActionListener(new ActionListener() { 124 public void actionPerformed(ActionEvent e) { 125 dispose(); 126 new Main(mineNum); 127 } 128 }); 129 add(button); 130 label1 = new JLabel("剩余時間"); 131 label1.setBounds(10,5,60,20); 132 add(label1); 133 134 label2 = new JLabel("剩余:"+restNum); 135 label2.setBounds(screenwide-70,5,60,20); 136 add(label2); 137 JPanel p = new JPanel(); 138 p.setLayout(new GridLayout(rowNum,colNum,0,0)); 139 for(int i = 0;i<rowNum*colNum;++i) { 140 Bub bub = new Bub(); 141 bub.showImg(13); 142 bub.addMouseListener(this); 143 list.add(bub); 144 p.add(bub); 145 } 146 p.setBounds(0,40,colNum*20,rowNum*20); 147 add(p); 148 this.setVisible(true); 149 } 150 public static void main(String[]args) { 151 new Main(10); 152 } 153 class Result extends JFrame { 154 /** 155 * 156 */ 157 private static final long serialVersionUID = 7899366376251467187L; 158 159 public Result(String con) { 160 super("游戲結果"); 161 setSize(250,150); 162 setLocationRelativeTo(null); 163 JButton button = new JButton("確定"); 164 setLayout(null); 165 JLabel label3 = new JLabel(); 166 button.addActionListener(new ActionListener() { 167 public void actionPerformed(ActionEvent e) { 168 dispose(); 169 } 170 }); 171 label3.setFont(new Font("微軟雅黑",Font.BOLD,15)); 172 if(con.equals("win")) label3.setText("用時"+min+"分"+sec+"秒"); 173 if(con.equals("lose"))label3.setText("繼續努力!"); 174 label3.setBounds(70, 5, 100, 40); 175 add(label3); 176 button.setBounds(80, 50, 70, 40); 177 add(button); 178 setVisible(true); 179 } 180 } 181 @Override 182 public void mouseClicked(MouseEvent arg0) { 183 // TODO 自動生成的方法存根 184 185 } 186 187 @Override 188 public void mouseEntered(MouseEvent arg0) { 189 // TODO 自動生成的方法存根 190 191 } 192 193 @Override 194 public void mouseExited(MouseEvent arg0) { 195 // TODO 自動生成的方法存根 196 197 } 198 199 @Override 200 public void mousePressed(MouseEvent arg0) { 201 // TODO 自動生成的方法存根 202 203 } 204 public boolean judge(int index) { 205 if(index>=0&&index<list.size()) { 206 if(list.get(index).getreal()==1)return true; 207 } 208 return false; 209 } 210 public boolean judgeLimit(int index) { 211 if(index>=0&&index<list.size()) return true; 212 return false; 213 } 214 public void show(int index) { 215 Bub tmp1 = list.get(index);//當前點擊位置的在鏈表中的索引 216 int cnt = 0; //四周雷數的記錄值 217 boolean edgeU = (index%colNum!= 0); //判斷是否在右邊界 218 boolean edgeD = ((index+1)%colNum!= 0); //判斷是否在左邊界 219 if(judge(index-colNum))tmp1.setface(++cnt); 220 if(judge(index+colNum))tmp1.setface(++cnt); 221 if(judge(index-1)&&edgeU)tmp1.setface(++cnt); 222 if(judge(index+1)&&edgeD)tmp1.setface(++cnt); 223 if(judge(index-colNum+1)&&edgeD)tmp1.setface(++cnt); 224 if(judge(index+colNum+1)&&edgeD)tmp1.setface(++cnt); 225 if(judge(index-colNum-1)&&edgeU)tmp1.setface(++cnt); 226 if(judge(index+colNum-1)&&edgeU)tmp1.setface(++cnt); 227 if(cnt==0) { 228 tmp1.setface(0); 229 tmp1.showImg(0); 230 if(!judge(index-colNum)&&judgeLimit(index-colNum)&&!list.get(index-colNum).getOpen())show(index-colNum);//為了避免這里的遞歸陷入了死循環,要對相鄰的按鈕進行判斷,如果已經處於翻開狀態,就不用在進一步操作 231 if(!judge(index+colNum)&&judgeLimit(index+colNum)&&!list.get(index+colNum).getOpen())show(index+colNum); 232 if(!judge(index-1)&&edgeU&&judgeLimit(index-1)&&!list.get(index-1).getOpen())show(index-1); 233 if(!judge(index+1)&&edgeD&&judgeLimit(index+1)&&!list.get(index+1).getOpen())show(index+1); 234 if(!judge(index-colNum+1)&&edgeD&&judgeLimit(index-colNum+1)&&!list.get(index-colNum+1).getOpen())show(index-colNum+1); 235 if(!judge(index+colNum+1)&&edgeD&&judgeLimit(index+colNum+1)&&!list.get(index+colNum+1).getOpen())show(index+colNum+1); 236 if(!judge(index-colNum-1)&&edgeU&&judgeLimit(index-colNum-1)&&!list.get(index-colNum-1).getOpen())show(index-colNum-1); 237 if(!judge(index+colNum-1)&&edgeU&&judgeLimit(index+colNum-1)&&!list.get(index+colNum-1).getOpen())show(index+colNum-1); 238 } 239 else tmp1.showImg(cnt); 240 } 241 @Override 242 public void mouseReleased(MouseEvent e) { 243 Bub tmp = (Bub)e.getSource(); 244 int index = list.indexOf(tmp); 245 if(this.gameState.equals("over"))return; 246 else { 247 if(e.getButton()==MouseEvent.BUTTON1) { 248 if(tmp.getface()!=11&&tmp.getface()!=12) { 249 if(isfirst) { 250 tmp.setreal(1); 251 Random r = new Random(); 252 int len = list.size(); 253 for(int i = 1;i<=mineNum;++i) { 254 while(true) { 255 int des = r.nextInt(len); 256 if(list.get(des).getreal()!=1) { 257 list.get(des).setreal(1); 258 list.get(des).showImg(13); 259 break; 260 } 261 } 262 } 263 tmp.setreal(0); 264 isfirst = false; 265 show(index); 266 new stopwatch().start(); 267 } 268 else if(tmp.getreal()!=1){ 269 show(index); 270 } 271 else if(tmp.getreal()==1) { 272 for(Bub bub:list) { 273 if(bub.getreal()==1)bub.showImg(9); 274 if(bub.getreal()==0&&bub.getface()==11) { 275 bub.setface(10);bub.showImg(10); 276 } 277 } 278 gameState = "over"; 279 button.setIcon(new ImageIcon("D:\\學習文檔\\smile3.jpg")); 280 new Result("lose"); 281 282 } 283 } 284 } 285 if(e.getButton()==MouseEvent.BUTTON3) { 286 if(tmp.getface()==13) { 287 tmp.setface(11); 288 tmp.showImg(11); 289 restNum--; 290 } 291 else if(tmp.getface()==11) { 292 tmp.setface(12); 293 tmp.showImg(12); 294 restNum++; 295 } 296 else if(tmp.getface()==12) { 297 tmp.setface(13); 298 tmp.showImg(13); 299 } 300 } 301 if(restNum==0) { 302 int total = 0; 303 for(Bub bub1:list) { 304 if(bub1.getface()==11&&bub1.getreal()==1)total++; 305 } 306 if(total==mineNum) { 307 gameState = "over"; 308 button.setIcon(new ImageIcon("D:\\學習文檔\\smile2.jpg")); 309 new Result("win"); 310 } 311 } 312 label2.setText("剩余:"+restNum); 313 } 314 } 315 }
1 import javax.swing.ImageIcon; 2 import javax.swing.JButton; 3 4 public class Bub extends JButton{ 5 6 private int face=13; //表面上的圖形顯示 7 private int real=0; //有無雷,有雷為1,無雷為0 8 private boolean isOpen = false;//表明當前按鈕的狀態,true表示已經翻開,false表示還未翻開 9 private ImageIcon[]img = new ImageIcon[14]; 10 public Bub() { 11 super(); 12 img[0] = new ImageIcon("D:\\學習文檔\\0mine.jpg"); 13 img[1] = new ImageIcon("D:\\學習文檔\\1mine.jpg"); 14 img[2] = new ImageIcon("D:\\學習文檔\\2mine.jpg"); 15 img[3] = new ImageIcon("D:\\學習文檔\\3mine.jpg"); 16 img[4] = new ImageIcon("D:\\學習文檔\\4mine.jpg"); 17 img[5] = new ImageIcon("D:\\學習文檔\\5mine.jpg"); 18 img[6] = new ImageIcon("D:\\學習文檔\\6mine.jpg"); 19 img[7] = new ImageIcon("D:\\學習文檔\\7mine.jpg"); 20 img[8] = new ImageIcon("D:\\學習文檔\\8mine.jpg"); 21 img[9] = new ImageIcon("D:\\學習文檔\\mine.jpg"); 22 img[10] = new ImageIcon("D:\\學習文檔\\mineerr.jpg"); 23 img[11] = new ImageIcon("D:\\學習文檔\\flag.jpg"); 24 img[12] = new ImageIcon("D:\\學習文檔\\flag2.jpg"); 25 img[13] = new ImageIcon("D:\\學習文檔\\bg.jpg"); 26 } 27 public int getface() { 28 return face; 29 } 30 public int getreal() { 31 return real; 32 } 33 public void setface(int c) { 34 face = c; 35 } 36 public void setreal(int c) { 37 real = c; 38 } 39 public void setOpen(boolean swit) { 40 isOpen = swit; 41 } 42 public boolean getOpen() { 43 return isOpen; 44 } 45 public void showImg(int c) { 46 this.setIcon(img[c]); 47 if(c!=13)isOpen = true; 48 } 49 }
水品有限,代碼寫得很臃腫,僅限個人娛樂