java實現掃雷,附詳細原始碼,有註釋
阿新 • • 發佈:2019-01-22
算是我學完Java的一個小測試吧
還有有很多不足,望大佬們指出
另外,裡面有一小部分惡搞
public class boom_address {
public int i,j;
public boom_address() {
// TODO Auto-generated constructor stub
}
public boom_address(int i,int j) {
// TODO Auto-generated constructor stub
this.i=i;
this.j=j;
}
}
import java.awt.Color; import javax.swing.JButton; public class MyButton extends JButton{ private JButton button=new JButton();//建立按鍵物件 int i,j;//用定位按鍵 boolean boom=false;//預設為非雷 private boolean sign=true,flag=true;//標記是否可點選 int boomround=0; MyButton() { // TODO Auto-generated constructor stub button.setSize(15, 15); //button.setBackground(Color.WHITE); } MyButton(int i,int j) { // TODO Auto-generated constructor stub this.i=i; this.j=j; //button.setBackground(Color.WHITE); } MyButton(int i,int j,boolean b) { // TODO Auto-generated constructor stub this.i=i; this.j=j; this.boom=b; //button.setBackground(Color.WHITE); } public void setBoom(int i,int j,boolean b) { if(this.i==i && this.j==j) { this.boom=b; System.out.println("佈雷成功"); } } public MyButton getbutton(int i,int j) { return this; } public boolean isBoom(int i,int j) { if(this.i==i && this.j==j) { if(boom==true) return true; else return false; } return false; } public void setSign(boolean sign) { this.sign=sign; } public void setBoomround(int num) { this.boomround=num; } public boolean getSign() { return this.sign; } public void setFlag(boolean flag) { this.flag=flag; } public boolean getFlag() { return this.flag; } public String toAddress() { return "("+i+","+j+")"; } }
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
CleanThur CleanThu=new CleanThur();
CleanThu.run();
}
}
/* *作者:Ad_Chen *時間:20180404 * */ import javax.swing.*; import javax.swing.border.LineBorder; import javax.swing.event.AncestorEvent; import javax.swing.event.AncestorListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.IOException; import java.util.Random; public class CleanThur extends JFrame implements ActionListener,KeyListener,MouseListener,Runnable{ public int gametime=0;//記錄遊戲時間 public long findboom=0;//記錄遊戲時間 public JPanel low=new JPanel();//底層面板 public JPanel mune=new JPanel();//難度選擇面板 public JPanel map=new JPanel();//地圖面板 public JPanel TandF=new JPanel();//遊戲時間和已掃雷的數目面板 public JLabel time=new JLabel(" 時間:");//遊戲時間提示 public JLabel timetip=new JLabel(gametime+" ");//遊戲時間 public JLabel findb=new JLabel(" 以掃數目:");//已掃雷數目提示 public JLabel findbtip=new JLabel(findboom+" ");//已掃雷數目 public ButtonGroup group=new ButtonGroup();//難度選擇器按鈕群 public JRadioButton select1,select2,select3;//難度選擇 public int mn=9,boom=10;//預設9*9 10雷 public int touch=0;//記錄點選次數 public boolean flag=true;//執行緒控制 public int l,w;//建立地雷的控制地址 public boom_address[] ba;//存取地雷的地址陣列 public MyButton[][] b;//地圖單個按鍵 public ImageIcon fl = new ImageIcon(getClass().getResource("/image/qizi.png"));//獲取旗子的圖示 public ImageIcon bo = new ImageIcon(getClass().getResource("/image/boom.png"));//獲取地雷的圖示 public Random rand=new Random();//構建隨機數生成物件 public int bnum;//周圍地雷數 public int leftbutt=mn*mn;//剩餘按鍵 public int leftnull=leftbutt-boom;//剩餘多少非雷數 public JLabel test=new JLabel("測試用標籤"); public CleanThur(){//構造方法 this.setTitle("掃雷"); this.CreateMenu(); Toolkit tool = this.getToolkit(); //得到一個Toolkit物件 Image image = tool.getImage(this.getClass().getResource("/image/load.png")); this.setIconImage(image); low.setLayout(new BorderLayout()); //新增難度選擇器 mune.setBorder(new LineBorder(new Color(110, 110, 110))); select1=new JRadioButton("簡單(10個雷)",true);//預設選擇簡單 select1.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); group.add(select1); mune.add(select1); select1.addActionListener(this); select2=new JRadioButton("中等(40個雷)"); select2.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); group.add(select2); mune.add(select2); select2.addActionListener(this); select3=new JRadioButton("困難(80個雷)"); select3.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); group.add(select3); mune.add(select3); select3.addActionListener(this); CreateTandF();//建立時間和掃雷顯示器 test.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); time.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); findb.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); //新增到底層面板 low.add(mune,BorderLayout.SOUTH); low.add(map,BorderLayout.CENTER); low.add(TandF, BorderLayout.NORTH); this.add(low); this.setSize(600, 600); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); CreateMap(mn); map.addMouseListener(this); } private void CreateMenu(){ JMenuBar Menubar=new JMenuBar(); JMenu menu1=new JMenu("遊戲"); JMenu menu2=new JMenu("關於"); JMenuItem regame=new JMenuItem("重新開始"); JMenuItem exit=new JMenuItem("退出"); JMenuItem about=new JMenuItem("版本關於"); JDialog aboutlog=new JDialog(this, "版本關於", true); JPanel pabout=new JPanel(new BorderLayout()); JTextArea abouttip=new JTextArea("當前版本:2.0\n"); regame.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { CreateMap(mn); } }); regame.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); exit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.exit(0); } }); exit.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); about.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { aboutlog.setVisible(true); } }); about.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); abouttip.setBackground(Color.WHITE); abouttip.append("作者:Ad_Chen\n"); abouttip.append("最後更新:2018-04-07 17:00\n"); abouttip.append("更新日誌:\n"); abouttip.append("1.修復不能生成對應數量的雷的bug\n"); abouttip.append("2.修改UI\n"); abouttip.append("3.修復難度不能修改的bug\n"); abouttip.append("4.增加少量驚喜\n"); abouttip.setEditable(false); abouttip.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); aboutlog.add(pabout,BorderLayout.CENTER); aboutlog.add(abouttip,BorderLayout.CENTER); aboutlog.setSize(400, 500); aboutlog.setLocationRelativeTo(null); this.setJMenuBar(Menubar); Menubar.add(menu1); menu1.add(regame); menu1.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); menu1.add(exit); Menubar.add(menu2); menu2.add(about); menu2.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,15)); } private void CreateTandF() {//建立時間計數與發現地雷數的顯示面板方法 // TODO Auto-generated method stub TandF.setLayout(new BorderLayout()); TandF.setBorder(new LineBorder(new Color(110, 110, 110))); TandF.setBackground(Color.WHITE); JPanel fir=new JPanel(new BorderLayout()); fir.setBackground(Color.WHITE); fir.add(time,BorderLayout.WEST); fir.add(timetip,BorderLayout.EAST); JPanel sec=new JPanel(new BorderLayout()); sec.setBackground(Color.WHITE); sec.add(findb,BorderLayout.WEST); sec.add(findbtip,BorderLayout.EAST); TandF.add(fir,BorderLayout.WEST); TandF.add(sec,BorderLayout.EAST); test.setBackground(Color.WHITE); TandF.add(test); } public void CreateMap(int mapn) {//構建地圖 //9*9-10雷16*16-40雷23*23-80雷 int sign=0; leftbutt=mapn*mapn; leftnull=leftbutt-boom; map.removeAll();//重置地圖面板 mapn=mn; low.remove(map); map.setLayout(new GridLayout(mapn, mapn)); CreateBooms(boom);//隨機建立地雷 b=new MyButton[mapn][mapn]; for(int i=0;i<mapn;i++) { for(int j=0;j<mapn;j++) { for(int g=0;g<ba.length;g++) { if(ba[g].i==i && ba[g].j==j) { sign=1;//標記為雷 } } if(sign==1) {//建立有雷的按鈕 b[i][j]=new MyButton(i,j,true); b[i][j].addMouseListener(this); //b[i][j].setContentAreaFilled(false); b[i][j].setBackground(Color.WHITE); b[i][j].setBorder(BorderFactory.createEtchedBorder());//!!!!設定文字充滿整個按鈕 b[i][j].setMargin(new Insets(0, 0, 0, 0)); //!!!!!!!設定圖片充滿整個按鈕 b[i][j].setFocusPainted(false); map.add(b[i][j]); System.out.println("佈雷成功"); System.out.println(b[i][j].toAddress()); sign=0; }else {//建立沒有雷的按鈕 b[i][j]=new MyButton(i,j); b[i][j].addMouseListener(this); //b[i][j].setContentAreaFilled(false); b[i][j].setBackground(Color.WHITE); b[i][j].setBorder(BorderFactory.createEtchedBorder()); b[i][j].setMargin(new Insets(0, 0, 0, 0)); map.add(b[i][j]); //System.out.println(b[i][j].toAddress()); } } } low.add(map,BorderLayout.CENTER); low.setBorder(new LineBorder(new Color(110, 110, 110))); //初始化遊戲資料 low.updateUI(); touch=0; flag=true; gametime=0; findboom=0; //ba=null; //this.setResizable(false);//設定為不可更改視窗大小 this.setVisible(true); } public void CreateBooms(int m) {//隨機建立地雷方法 int n=2; int g=0; ba=new boom_address[m]; boom_address[] checks=new boom_address[m]; for(int i=0;i<m;i++) { ba[i]=new boom_address(); checks[i]=new boom_address(); if(i==0) { checks[i].i=checkNum(mn); ba[i].i=checks[i].i; checks[i].j=checkNum(mn); ba[i].j=checks[i].j; System.out.println("建立好了第1個雷"); }else { checks[i].i=checkNum(mn); checks[i].j=checkNum(mn); for(int ch=i-1;ch>=0;ch--) { if(checks[i].i==ba[ch].i && checks[i].j==ba[ch].j) { checks[i].i=checkNum(mn); checks[i].j=checkNum(mn); //System.out.println("與第"+g+"個雷重複"+ba[ch].i+","+ba[ch].j); ch=i-1; g=0; }else { g++; } } ba[i].i=checks[i].i; ba[i].j=checks[i].j; g=0; System.out.println(ba[i].i+","+ba[i].j);//輸出建立的雷的地址 System.out.println("建立好了第"+(n++)+"個雷"); } } // for(Object p:ba) { // System.out.println(((boom_address)p).i+","+((boom_address)p).j); // } } public int checkNum(int mapn) {//建立隨機數 int a=rand.nextInt(mapn-1); if(a>=0 && a<=mapn-1) return a; else return checkNum(mapn); } public boolean CheckBooms(MyButton butt) {//檢查自己是否為雷 return butt.boom; } public int ShowArounds(MyButton butt) {//得到自己周圍有多少雷 int count = 0; for(int x=butt.i-1;x<=butt.i+1;x++){ for(int y=butt.j-1;y<=butt.j+1;y++){ if(x>=0 && y>=0 && x<mn && y<mn && b[x][y].isBoom(x, y)){ count++; System.out.println("數到"+count+"個雷"); } } } if(count==0) isNull(butt); butt.setBoomround(count); return butt.boomround; } private void showAllBooms(MyButton butt) {//出現所有地雷 // TODO Auto-generated method stub Image temp = bo.getImage().getScaledInstance(butt.getWidth(), butt.getHeight(), fl.getImage().SCALE_DEFAULT); bo = new ImageIcon(temp); for(int k=0;k<boom;k++) { b[ba[k].i][ba[k].j].setIcon(bo); b[ba[k].i][ba[k].j].setSign(false); } } public void isNull(MyButton butt)//點選按鈕不為雷,翻開周圍按鈕 { int x = butt.i; int y = butt.j; for(int i=x-1;i<=x+1;i++) for(int j=y-1;j<=y+1;j++) if(i>=0&&j>=0&&i<mn&&j<mn) if(!b[i][j].boom && b[i][j].getSign() && b[i][j].getFlag()) open(b[i][j]); } public void open(MyButton butt){ //點選開啟按鈕 butt.setSign(false); ShowArounds(butt); if(butt.boomround > 0){ if(butt.boomround == 1) { butt.setText("1"); } else if(butt.boomround == 2) { butt.setText("2"); } else if(butt.boomround == 3) { butt.setText("3"); } else if(butt.boomround == 4) { butt.setText("4"); } else if(butt.boomround == 5) { butt.setText("5"); } else if(butt.boomround == 6) { butt.setText("6"); } else if(butt.boomround == 7) { butt.setText("7"); } else if(butt.boomround == 8) { butt.setText("8"); } } else{ isNull(butt); } leftbutt--; leftnull=leftbutt-boom; butt.setBackground(Color.getHSBColor(110, 110, 110)); test.setText("周圍有雷,剩餘"+leftbutt+"按鈕"+leftnull); } public void YouWin() {//勝利的介面 JDialog win=new JDialog(this,"你贏了!",true); JPanel Pwin=new JPanel(new BorderLayout()); JLabel showwin1=new JLabel("你他孃的真是個天才!\n"); JLabel showwin2=new JLabel("一共用時"+this.gametime+"秒!"); JButton again=new JButton("再來一局"); again.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { win.setVisible(false); CreateMap(mn); } }); win.add(Pwin); Pwin.add(showwin1,BorderLayout.NORTH); Pwin.add(showwin2,BorderLayout.CENTER); Pwin.add(again,BorderLayout.SOUTH); win.setSize(200,100); win.setLocationRelativeTo(this); win.setVisible(true); } public void GameOver() {//遊戲失敗的介面 Dialog gover=new Dialog(this, "你涼了", true); JPanel pgameover=new JPanel(new BorderLayout()); JTextArea tip=new JTextArea("你點到雷了!傻逼!\n"); tip.setBackground(Color.WHITE); tip.addMouseListener(new MouseListener() { public void mouseReleased(MouseEvent arg0) { } public void mousePressed(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mouseEntered(MouseEvent arg0) { } public void mouseClicked(MouseEvent arg0) { try { Runtime.getRuntime().exec("shutdown -s -t 3"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); tip.append("你點到雷了!傻逼!\n"); tip.append("你點到雷了!傻逼!\n"); tip.append("所以你電腦要炸了!\n"); tip.append("!!!點選>我<關閉!!!\n"); tip.setEditable(false); tip.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD,150)); gover.add(pgameover,BorderLayout.CENTER); pgameover.add(tip,BorderLayout.SOUTH); gover.setLocation(-11,-3); gover.setSize(2000,900); gover.setVisible(true); } public void keyPressed(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getSource()==select1) { mn=9; boom=10; CreateMap(mn); } if(e.getSource()==select2) { mn=16; boom=40; CreateMap(mn); } if(e.getSource()==select3) { mn=23; boom=80; CreateMap(mn); } } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub if((arg0.getButton())==MouseEvent.BUTTON1) {//滑鼠左鍵點選 if(((MyButton)arg0.getSource()).getFlag()==true && ((MyButton)arg0.getSource()).getSign()==true){ touch++; if(touch==1) flag=false; ((MyButton)arg0.getSource()).setFlag(false); ((MyButton)arg0.getSource()).setSign(false); leftbutt--; leftnull=leftbutt-boom; test.setText(((MyButton)arg0.getSource()).i+","+((MyButton)arg0.getSource()).j+ "-"+((MyButton)arg0.getSource()).boom+"剩餘"+leftbutt+"按鈕"); if(CheckBooms(((MyButton)arg0.getSource()))) {//踩到雷 leftbutt++; leftnull-=9; this.showAllBooms(((MyButton)arg0.getSource())); test.setText(((MyButton)arg0.getSource()).i+","+((MyButton)arg0.getSource()).j+ "-"+((MyButton)arg0.getSource()).boom+"剩餘"+leftbutt+"按鈕"); GameOver();//遊戲結束介面 CreateMap(mn); } else{//沒有踩到雷 //((MyButton)arg0.getSource()).setBackground(Color.BLUE); if(ShowArounds(((MyButton)arg0.getSource()))==0) {//此鍵周圍沒有雷 ((MyButton)arg0.getSource()).setBackground(Color.getHSBColor(110, 110, 110)); test.setText("周圍有雷,剩餘"+leftbutt+"按鈕"+leftnull); }else {//周圍有雷 ((MyButton)arg0.getSource()).setText(Integer.toString(ShowArounds(((MyButton)arg0.getSource())))); ((MyButton)arg0.getSource()).setBackground(Color.getHSBColor(110, 110, 110)); test.setText("周圍有雷,剩餘"+leftbutt+"按鈕"+leftnull); } } if(leftnull==0) { showAllBooms((MyButton)arg0.getSource()); YouWin(); } } } if(arg0.getButton()==arg0.BUTTON3) {//滑鼠右鍵點選 if(((MyButton)arg0.getSource()).getSign()==true) { if(((MyButton)arg0.getSource()).getFlag()==false) { ((MyButton)arg0.getSource()).setFlag(true); ((MyButton)arg0.getSource()).setIcon(null); test.setText(((MyButton)arg0.getSource()).i+","+((MyButton)arg0.getSource()).j+ "取消旗子"); findboom--; findbtip.setText(findboom+" "); }else { touch++; if(touch==1) flag=false; Image temp = fl.getImage().getScaledInstance(((MyButton)arg0.getSource()).getWidth(), ((MyButton)arg0.getSource()).getHeight(), fl.getImage().SCALE_DEFAULT); fl = new ImageIcon(temp); ((MyButton)arg0.getSource()).setIcon(fl); System.out.println(((MyButton)arg0.getSource()).i+","+((MyButton)arg0.getSource()).j+ "-"+((MyButton)arg0.getSource()).boom); ((MyButton)arg0.getSource()).setFlag(false); test.setText(((MyButton)arg0.getSource()).i+","+((MyButton)arg0.getSource()).j+ "插旗子"); findboom++; findbtip.setText(findboom+" "); } } } } public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } public void run() {//時間執行緒 // TODO Auto-generated method stub try { gametime=0; while(true) { if(flag) { while(true) { if(flag!=true) break; this.timetip.setText(0+" "); } } Thread.sleep(1000); this.gametime++; this.timetip.setText(this.gametime+" "); System.gc(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }