天天看點

java GUI記憶紙牌遊戲(memorize game)

Project制作

首先,一個小程式的制作要考慮的首先是程式界面的布局;其次是算法的設計,實作基本功能;然後再添加其他功能。然後就是Bug以及細節的處理;最後就是制作嵌入幫助開發系統。

一:界面布局篇

1:登陸視窗:

使用的布局管理器:GirdBagLayout(網格組布局管理器也可用Box箱式管理器),在這個視窗需要對開始遊戲和退出設定滑鼠監聽,如果開始遊戲卻沒輸入名字,會彈出請出入名字,有名字後開始遊戲,會将這個名字傳遞到主視窗中。在監聽函數中完成傳遞。

2:遊戲界面:

java GUI記憶紙牌遊戲(memorize game)

這個界面需要考慮如何将頁面作何很像或是做好。這就需要對java布局的深入了解。

如果認為這是一個邊界布局取中間和下面那就錯了,這樣元件會緊貼邊界排布,影響美觀。

頂層容器取中:如何在四周留下空隙呢,處理方式有三種,首先使用邊界布局管理器,将所有的元件放在中間是必須的,剩下的就是對邊界的處理。

方式一:在各個邊界添加new JLabel(” ”)中間有空格的JLabel填充一定區域。

方式二:在設定布局的時候,bordelayout(int,int)設定你需要的邊界值。這樣邊界就會有空系。但是,這是在兩邊界使用的情況下,為此,需要在各個邊界添加new JLabel(),或new JLabel(””)中間無空格的空label。這樣邊界就被名義上的調用而存在,就會滿足bordelayout(int,int)兩相鄰邊界的空隙。

方式三:将各個邊界使用setpreferredsize()設定固定各個邊界的大小。

本人推薦使用第二種,操作簡單,也比較精确。

次層容器取中下,在container的容器取中之後,還剩紙牌和三個按鈕,紙牌是要統一操作,四個按鈕要統一操作。頂層容器的中間添加JPanel容器,JPanel容器再次使用邊界布局,隻使用中間和下兩個部分就可以将兩種按鈕分開。

三層容器:第三層容器的中間部分可以添加一個網格布局的Jpanel,此JPanel在添加按鈕。下部分可以添加一個網格布局的Jpanel或Box布局的Box容器。(此方案采用網格布局)

這樣梳理三層容器各個所取的部分和布局方式。就可以實作舒心的布局。

二:算法實作篇

實作遊戲算法的大緻分為為:随機布局和翻牌判斷

随機布局:

① 要将八張牌和一張牌背放到與檔案相同的scr檔案夾中。用String數組存下位址(編号要順序排才能用上數組),用imageicon/icon數組順序存入牌,(16個,背面可單獨存)。這樣順序的1234567812345678十六張牌的圖示數組就存好了。

② 開始實作随機放牌,建立16位imageicon/icon數組,還要建立一個Integer類型的list集合,用來儲存随機圖篇對應的數字(個人能力還達不到比較圖示,是以把圖的比較轉化為數%8的比較),将随機過後的牌順序放入,這是一個抽象的放牌位置。隻是按鈕數組的執行翻牌的時候對應的調用此圖示數組。(按鈕數組的初始化是背面圖檔)。代碼如下:

public void suiji()
  { boolean b=false;
    Random r=new Random();
    for(int i=0;i<16;i )
    {
      int randomint=r.nextInt(16);
      for(int j=0;jlisttime=new ArrayList<>();
for(int i=0;i<16;i )
 {listtime.add(i);}
    for(int i=0;i<16;i )
    {
      int randomint=r.nextInt(listtime.size());
 int team=listtime.get(randomint);
 listtime.remove(randomint);
      random[i]=image[team];list.add(team);
    }
  }      

(本人采用的是第二這種方案。)

随機布局就完成了,在類中繼承Actionlistenner接口,從寫監聽函數。點選的按鈕對應調用seticon()相同位置的随機排序後的icon/imageicon數組,就可以完成了。

翻牌判斷:

可以建立一個list1集合裝載所有點選的按鈕記号。當這個集合的size()為偶數時,執行判斷,有兩個結果,兩張牌相同時,消失,兩張牌不同,把圖示設定成牌背面圖檔。這裡,牌的判斷就用到之前儲存随機數字的集合,調用%8看是否相等。

相等的情況:兩張牌消失。就用到按鈕的一些屬性

jbutton[list1.get(list1.size()-2)].setIcon(null);
 jbutton[list1.get(list1.size()-2)].setContentAreaFilled(false);// 透明
 jbutton[list1.get(list1.size()-2)].setBorderPainted(false);// 取消邊框
 jbutton[list1.get(list1.size()-2)].setFocusPainted(false); // 取消焦點
 jbutton[list1.get(list1.size()-2)].setEnabled(false);
 jbutton[list1.get(list1.size()-1)].setIcon(null);
 jbutton[list1.get(list1.size()-1)].setContentAreaFilled(false);// 透明
 jbutton[list1.get(list1.size()-1)].setBorderPainted(false);// 取消邊框
 jbutton[list1.get(list1.size()-1)].setFocusPainted(false); // 取消焦點
 jbutton[list1.get(list1.size()-2)].setEnabled(false);      

當然,要建立一個int類型數字判斷是否結束,當消失一張牌這個int類型值就加一。當等于16時結束停止。

兩張牌的判斷是翻開就進行的,如果不做處理,就會遇到一種情況,相同時,還沒看清是否相同就消失了,不相同時,沒看見翻得是什麼就傳回去了。為了避免這種情況,要在裡面添加線程,讓無論消失還是翻過去都要在0.3秒後執行。

三:其他功能篇

我們添加的其他功能有時間記錄,Score記錄(i/o),提示功能,背景音樂,結束事件,重新開始。

① 時間記錄:我們将時間放在title上顯示,用線程控制,start的時候開始,消失16張牌的時候線程結束。

② Score記錄:

要實作分數的記錄和姓名的記錄,需要用到IO流的知識。其中的BufferedReader和BufferedWriter滿足此程式的使用要求,建立io()函數,每點選一次score就調用一次。Io()函數中首先建立file檔案,判斷D盤有沒有這個檔案,如果沒有,就再D盤建立一個tet檔案,先讀取該檔案的内容,按照每行放入String數組中,再彈出視窗顯示成績的排名資訊。讀取過後再存入放在數組中的内容。(隻能先讀取在寫入,否則檔案将會被清空)

如果遊戲結束,會自動調用io()儲存記錄,但是不彈出視窗(可用布爾或其他數值控制)。将資料的數組後一位添加(int)time s 姓名

,這裡的排序就需要用到字元串分割,spit(”s”),用前面的有效時間做比較,排序。檔案寫入的時候寫入不超過三個記錄。

③ 提示功能:提示功能就是基數次的時候會生效,在前面的list集合中找到數值%8相等并且數值不等的那個數,在對應的按鈕上放一個線程讓他消失0.3秒在回來,做一個提示作用。

④ 背景音樂和點選鈴聲:

背景音樂的添加和圖示有點類似但是略有不同,背景音樂的實作方法如下:

public AudioClip music;//背景音樂
 URL url=Memorize.class.getResource(“music/fade2.wav”);//源
 {music=Applet.newAudioClip(url);}      

music.play();開始

如果循環需要添加:

try {
 Thread.sleep(40);
 } catch (InterruptedException e1) {
 e1.printStackTrace();
 }
 music.loop();      

此外,這種循環點選窗體X音樂還會繼續播放,需要設定一個關閉的監聽時間。在主類中implements actionlisterner。在重載函數中添加

addWindowListener(new WindowAdapter(){
 public void windowClosing(WindowEvent e){
 System.exit(0); } });      

點選的鈴聲:

這個程式添加兩種點選鈴聲,一是在按鈕上的滑鼠點選事件中直接添加鈴聲1.play();二是在container的容器上添加滑鼠點選事件,點選到沒有按鈕的區域會播放另一種鈴聲。

⑤ 結束事件:當十六張牌全部消失時,在放了16個按鈕的那個面闆上使用removeall();函數,再将面闆的布局改為絕對布局,使用線程1和算法制作出所有的牌從左往右的飛過效果,頂層容器的背景也閃爍更換,(控制線程慢慢減慢)就可以達到一個由快到慢的過程。線程1結束在執行線程2,name 恭喜你赢了字畫從上面移到中間,結束時下方出現重新開始按鈕和退出按鈕。這裡用到線程的加入join()。

⑥ 重新開始,設定restart()函數,将面闆再次改為網格布局,重新随機化,将變化的數值再次初始化。

四:bug和細節處理篇

一個小程式就要不産生任何Bug優化所能優化的東西。具體處理有:

1:圖示處理:一個小程式的制作就應該完全是自己的元素,JAVA咖啡圖示應該抛去

java GUI記憶紙牌遊戲(memorize game)

核心就是在設定窗體的時候使用seticonimage()函數。

2:防變形處理:如果你沒有使用特殊的布局或者處理時,你的窗體拉伸或導緻很醜,很影響美觀,你可以使用固定視窗不可拉伸。對應的函數為setResizable(false);

3:位置處理:如果一個小程式點選出現在左上角的邊框總有點不好看。可以設定窗體居中,對應的函數為:

setLocationRelativeTo(null)注意:這個函數要在setsize()的後面。因為要設定好大小在整個窗體居中,如果先劇中在設定大小就會導緻這個窗體從中心點開始向右下方延伸。

4.按鈕控制的嚴謹性,①在start開始前點圖圖檔不會産生滑鼠點選事件②圖檔被翻開的時候就不會被再次點選,處理不好會導緻連續點兩次一個圖檔,圖檔會自己消失。③當再判斷消失或者翻回去的時候要注意讓點選事件不在生效,(因為再判斷的時候他線上程内你手速太快點選其他按鈕,那麼操作的最近兩個按鈕就發生了變化)這個可以使用控制start的那個boolean值進行判斷。

5:界面有圖形的變換時要用好repaint();函數,即使重繪界面。否則,會出現一些類似“卡主”的界面

java GUI記憶紙牌遊戲(memorize game)

(重新開始遊戲沒使用repaint()函數的結果)

6:如果使用線程計時器,如果單純的計時倒無所謂,如果這個時間需要使用,需要對線程控制好,控制好休眠前自加還是休眠後自加。

7:線程的生命周期要控制好,設定好限制條件,該結束的時候就結束,避免占用不必要的資源。

8:視窗的退出,disopose()關閉目前視窗,system.exit(0);關閉所有,是以當開始遊戲的時候使用dispose();所有的退出使用exit(0);

9:按鈕過多的時候寫監聽就不要用内部類實作,代碼會太長。改用接口匿名會簡潔的多。

五:幫助系統處理篇

③ 将幫助檔案嵌入到GUI程式中。

方法一使用的方法:使用cmd指令打開

代碼如下:

public void help()
 {
 File file = new File(“doc/help.chm”);
 Runtime ce=Runtime.getRuntime();
 try {
 ce.exec("cmd /c start " file.getAbsolutePath());
 } catch (IOException e) {
 e.printStackTrace();
 }
 }      

這裡建立file檔案建立相對路徑,編譯時相對與projiect内部檔案夾,導出時相對jar程式。這個,就不用将doc檔案放置再固定檔案,而是相對放置就可以使用,在編譯的過程中,路徑名稱不能包括空格,否則會識别不出,在運作jar檔案時,檔案夾名稱也不可以改動。(很多程式的内部檔案是不可以改動的。)

方法二使用的方法:也可用借助java.awt.desktop打開

代碼如下:

public void help()
 {File file = new File(“doc/help.chm”);
 try { 
 Desktop.getDesktop().open(file);
 } catch (IOException e) {
 // TODO 自動生成的 catch 塊
 e.printStackTrace();
 }}      

這種方法可以識别父類路徑中有空格的情況,符合更多需要。此程式從方案一優化到方案二。

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class chushi extends JFrame implements ActionListener{
 static String name=null;
  //boolean A=false;
   JButton a=new JButton("開始遊戲");
   JButton b=new JButton("退 出");
  // JButton jb2=new JButton("确定");
   JTextField jtex=new JTextField(10);
   ImageIcon imageicon=new ImageIcon(this.getClass().getResource("image/tubiao.png"));
public chushi()
  {
   this.setIconImage(imageicon.getImage());
    Container c=this.getContentPane();
    this.setTitle("memorize game");
    this.setSize(450, 250);
    this.setLocationRelativeTo(null);
    c.setLayout(new GridBagLayout());
    GridBagConstraints d=new GridBagConstraints();//gridbag參數
     d.gridx=0;//橫方向
     d.gridy=0;//縱方向
     d.weighty=0.1;
     d.anchor=d.SOUTH;//應該是對齊方式吧
     //d.gridheight=2;
     JLabel lab=new JLabel("歡迎來到memorize遊戲",JLabel.CENTER);
     lab.setFont(new Font("宋體",1,30));
     lab.setForeground(Color.red);
     c.add(lab,d);d.anchor=d.CENTER;
     //需要一行
     JPanel jp4=new JPanel();
     jp4.setLayout(new FlowLayout());
     JLabel lab2=new JLabel("請輸入你的名字",JLabel.CENTER);
     lab2.setFont(new Font("宋體",1,16));
    /// jtex.setFocusable(false); // 取消焦點
     jp4.add(lab2); 
     //wenben
     jp4.add(jtex);
     
    // jp4.add( jb2);
     d.gridy=1;
     c.add(jp4,d);
     d.gridy=2;
    
     c.add(a,d);
     d.gridy=3;
     c.add(b,d);
     a.addActionListener(this);b.addActionListener(this);//jb2.addActionListener(this);
     this.setVisible(true);
     this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  }

public void actionPerformed(ActionEvent e) {
    // TODO 自動生成的方法存根
    if(e.getSource()==a)
    {
      if(jtex.getText().equals("")) {JOptionPane.showMessageDialog(this,"請輸入姓名!");
      jtex.setFocusable(true); }
      else {new Memorize().name=jtex.getText();dispose();}
     
    }
    if(e.getSource()==b) {System.exit(0);}
    //if(e.getSource()==jb2) {A=true;name=jtex.getText();}
  }
}      
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
 
public class Memorize extends JFrame implements ActionListener{
  static Thread jishi;int time=-1;//計時
  public AudioClip music;//背景音樂
  public AudioClip lingsheng,lingsheng2;//點選的鈴聲
  URL url=Memorize.class.getResource("music/fade2.wav");//源
  {music=Applet.newAudioClip(url);
   lingsheng=Applet.newAudioClip(Memorize.class.getResource("music/lingsheng.wav"));
   lingsheng2=Applet.newAudioClip(Memorize.class.getResource("music/lingsheng2.wav"));
  }
  String shijianjilu[][];//io流
   String jilu[];//io
   boolean judgleB=false;//io
   boolean tanchu=false;//
  String name="";
  static boolean A=false;//控制start
  static boolean a[]=new boolean[16];//是否應該消失
   boolean b[]=new boolean[16];//為true時不可在點選
  static int B=0;//計算已經消失的牌數
 static  Listlist1=new ArrayList<>();//存放了點選按鈕的編号
  //中間闆塊所需要的部件
 static  List list=new ArrayList<>();//存放了随機過後的數字順序
 
  ImageIcon imageicon=new ImageIcon(this.getClass().getResource("image/beimian.jpg"));
  Image beimian=imageicon.getImage();
  String sousename[]=new String[8];//牌的名字
  ImageIcon image[]=new ImageIcon[16];//16張牌 icon也可以
  ImageIcon random[]=new ImageIcon[16];//使用過随機數後的圖示數組
 static  JButton jbutton[]=new JButton[16];
  //下面闆塊所需要的部件
  JButton start=new JButton("Start"); //start按鈕
  JButton score=new JButton("Score"); //score按鈕
  JButton hint=new JButton("hint");
  JButton help=new JButton("Help"); //help按鈕
  JButton restart=new JButton("重新開始");
  JButton exit =new JButton("退出");
  //中間 //中間上網格 //中間下網格
  JPanel jp=new JPanel();JPanel jp2=new JPanel();JPanel jp1=new JPanel();
  
  Container c=this.getContentPane();
  /**
   * 構造函數
   **/
public Memorize()
  {
   
    fuzhi();//指派sousename和image數組
    suiji();//指派random數組
    addjubutton();
    c.setLayout(new BorderLayout(30,20));
    c.setBackground(new Color(250,100,120));
    //this.setResizable(false);
    this.setTitle("memorize game");
    this.setIconImage(beimian);
    this.setSize(800, 900);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setResizable(false);
    jp.setLayout(new BorderLayout(20,20));
    jp1.setLayout(new GridLayout(4,4,40,20));//中間
    jp2.setLayout(new GridLayout(1,4,20, 0));//下面
    
    c.add(new JLabel(""),BorderLayout.NORTH);
    c.add(new JLabel(""),BorderLayout.WEST);
    c.add(new JLabel(""),BorderLayout.EAST);
    c.add(new JLabel(""),BorderLayout.SOUTH);
    c.add(jp,BorderLayout.CENTER);
    jp.setOpaque(false);//設定面闆為透明必須有
    jp2.setOpaque(false);//jp2(下面設定為透明)
    jp1.setOpaque(false);
    jp.add(jp1,BorderLayout.CENTER);
    jp.add(jp2,BorderLayout.SOUTH);
    jp2.add(start);
    jp2.add(score);
    jp2.add(hint);
    jp2.add(help);
    hint.addActionListener(this);
    help.addActionListener(this);
    start.addActionListener(this);
    score.addActionListener(this);
    restart.addActionListener(this);
    exit.addActionListener(this);
    c.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        lingsheng2.play();
      }
    });
    addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
      System.exit(0);
      }
      });
  
    //end();
  }
/**
 * 設定标題,用于線程中重複設定個性标題
 **/
public void settile()
{
  this.setTitle("memorize game-用時" time "s");
  }
/**
 * 計時器,标題的計時和最後的時間結束截取
 **/
public void jishi()
{
  jishi=new Thread(new Runnable() {
    public void run()
    {
      while(B<16) { 
        time ;
        settile();
        try {Thread.sleep(1000);}//休眠1S
        
        catch(Exception e) {e.printStackTrace();}
        }
    }
  });
  jishi.start();
  }
/**
 * 使用String的特性指派icon/imageicon數組
 **/
public void fuzhi()
  {
    for(int i=0;i<16;i )
    {
      sousename [i%8]="image/" (i%8 1) ".jpg"; //簡化代碼
      image[i]=new ImageIcon(this.getClass().getResource(sousename[i%8]));
    }
  }
/**
 * 随機排序位置
 **/
public void suiji()
{ Random r=new Random();
 Listlisttime=new ArrayList<>();
for(int i=0;i<16;i )
 {listtime.add(i);}
  for(int i=0;i<16;i )
  {
    int randomint=r.nextInt(listtime.size());
 int team=listtime.get(randomint);
 listtime.remove(randomint);
    random[i]=image[team];list.add(team);
  }
}
/**
 * 當開始的時候和重新開始的時候需要重新添加按鈕
 **/
public void addjubutton()
{
  for(int i=0;i<16;i )
  {
    jbutton[i]=new JButton(imageicon);
    jbutton[i].addActionListener(this);
    jp1.add(jbutton[i]);
  }
  }
/**
 * 結束事件,利用兩個線程的動畫
 **/
public void end()
  {
   
   jp1.removeAll();
   
    jp1.setLayout(null);
    JLabel jl=new JLabel(name ",恭喜你赢了",JLabel.CENTER);
    //jl.setForeground(Color.black);
    jl.setFont(new Font("宋體",0,24));
    jp1.add(jl);
    jp1.setOpaque(false);
    JLabel label[]=new JLabel[16];
    for(int j=0;j<16;j ) 
    {label[j]=new JLabel(image[j]);jp1.add(label[j]);label[j].setBounds(0, 120 j/8*280, 150, 200);}
    //jp.add(jp1,BorderLayout.CENTER);
    Random r=new Random();//背景更換
    Color color[]={Color.ORANGE,Color.red,Color.yellow,Color.cyan,Color.pink};
    Thread d0=new Thread(new Runnable() {
      
      int i=0;
      int count=0;
      public void run() {
        while(i<8)
        {if(count/10%5==0) {
          int randomint=r.nextInt(5);
          c.setBackground(color[randomint]);}
          label[i].setBounds(count, 120, 150, 200);
          label[i 8].setBounds(count, 400, 150, 200);
          repaint();
          count=count 10;
          if(count>800) {i ;count=0;}
        try {  Thread.sleep(2 i);}
         catch(InterruptedException e){System.out.println("目前線程被中斷");break;}
        }
      }
    });
    Thread d1=new Thread(new Runnable() {
      int count=0;
       public void run() {
         
         while(count<350) { 
           c.setBackground(new Color(250,100,120));
           jl.setBounds(180, count, 400, 100); jl.setFont(new Font("宋體",0,24 count/20));
          if(count0==0) { jl.setForeground(color[count/15%5]);}
          count=count 2; 
          if(count==348) {
            jp1.add(restart);restart.setBounds(200, 450, 150, 40);
           jp1.add(exit);exit.setBounds(400, 450, 150, 40);
          restart.setFont(new Font("宋體",1,22));exit.setFont(new Font("宋體",1,22));}
           try {Thread.sleep(10);d0.join();}
           catch(InterruptedException e){System.out.println("目前線程被中斷");break;}
         } 
       }});
    d0.start();d1.start();
      
    setVisible(true);  
  }
/**
 * 儲存成績和姓名的函數
 **/
public void io()//結束時調用
{
   //String jilu[]=new String[4];
  shijianjilu=new String[4][];//io流
  
  jilu=new String[4];
  int geshu=0;
   File file=new File("word.txt");
   if(!file.exists()) {try {
    file.createNewFile();}
   catch (IOException e) {
    // TODO 自動生成的 catch 塊
    e.printStackTrace();}}
   try 
   {//先讀取
     FileReader fi=new FileReader(file);
     BufferedReader bffi=new BufferedReader(fi);
     String s=null;int exam=0;
     while((s=bffi.readLine())!=null)
     {
       jilu[exam ]=s;
       //System.out.println(s);
      
     }
     if(B==16&&judgleB==false) { jilu[exam]=time "s" "姓名:" name;exam ;judgleB=true;}
      geshu=exam;
      
      
     if(exam==0&&tanchu) {tanchu=false;
      JOptionPane.showMessageDialog(this, "you will be the NO.1!"); }
     if(exam==1&&tanchu) { tanchu=false;JOptionPane.showMessageDialog(this,"top1玩家用時:" jilu[0]); }
     for(int j=0;j Integer.parseInt(shijianjilu[1][0]))
     {
       String temp=jilu[0];jilu[0]=jilu[1];jilu[1]=temp;
     }if(tanchu) {tanchu=false;JOptionPane.showMessageDialog(this,"top1玩家用時:" jilu[0] 
         "\ntop2玩家用時:" jilu[1]);}
    }
     if(exam==3) 
     {//paixu
     if(Integer.parseInt(shijianjilu[1][0])> Integer.parseInt(shijianjilu[2][0]))
     {
       String temp=jilu[1];jilu[1]=jilu[2];jilu[2]=temp;
       if(Integer.parseInt(shijianjilu[0][0])> Integer.parseInt(shijianjilu[2][0]))
       {
         String temp2=jilu[0];jilu[0]=jilu[1];jilu[1]=temp2;
       }
       if(tanchu) {tanchu=false;JOptionPane.showMessageDialog(this,"top1玩家用時:" jilu[0] 
           "\ntop2玩家用時:" jilu[1]);}
     }
    }
     bffi.close();
     fi.close();
   } catch (Exception e) {
      // TODO 自動生成的 catch 塊
      e.printStackTrace();
    
    }
   if(geshu!=0) {
   try {FileWriter writer=new FileWriter(file);
 BufferedWriter bfwriter=new BufferedWriter(writer);
 for(int i=0;i<2;i )
 {
   
   bfwriter.write(jilu[i]);
   bfwriter.newLine();
   // System.out.println(jilu[i]);
 }
 bfwriter.close();
 writer.close();
   }
catch(Exception e) {e.printStackTrace();}
   
  }}
/**
 * 判斷函數
 * 用于判斷是該消失還是翻回去
 * 判斷是否結束
 **/
public void judgle()
  {
    if(list1.size()%2==0) //最後那組資料用偶數判斷
    {
      A=false;
     Thread d1=new Thread(new Runnable() {
       public void run() {
         int count=0;
         while(count<3) {
    if(count==1&&list.get(list1.get(list1.size()-1))%8==list.get(list1.get(list1.size()-2))%8)
    { 
           jbutton[list1.get(list1.size()-1)].setIcon(null);
            
            jbutton[list1.get(list1.size()-1)].setContentAreaFilled(false);// 透明
            jbutton[list1.get(list1.size()-1)].setBorderPainted(false);// 取消邊框
            jbutton[list1.get(list1.size()-1)].setFocusPainted(false); // 取消焦點
            jbutton[list1.get(list1.size()-1)].setEnabled(false);
            jbutton[list1.get(list1.size()-2)].setIcon(null);
            jbutton[list1.get(list1.size()-2)].setContentAreaFilled(false);// 透明
            jbutton[list1.get(list1.size()-2)].setBorderPainted(false);// 取消邊框
            jbutton[list1.get(list1.size()-2)].setFocusPainted(false); // 取消焦點
            jbutton[list1.get(list1.size()-2)].setEnabled(false);
           a[list1.get(list1.size()-2)]=true;B ;
             a[list1.get(list1.size()-1)]=true;B ;
            // listhelp.remove(list1.get(list1.size()-2));
            // listhelp.remove(list1.get(list1.size()-1));
             A=true;
    }
           
    if(count==1&&list.get(list1.get(list1.size()-1))%8!=list.get(list1.get(list1.size()-2))%8)  
    { 
       if(a[list1.get(list1.size()-2)]==false)
        jbutton[list1.get(list1.size()-1)].setIcon(imageicon); b[list1.get(list1.size()-1)]=false;
        jbutton[list1.get(list1.size()-2)].setIcon(imageicon);b[list1.get(list1.size()-2)]=false;
        A=true;
    }
     if(count==2)
            {
            if(B==16)  {io();end();}
              
            }
           count ;
           try {Thread.sleep(300);}
           catch(InterruptedException e){System.out.println("目前線程被中斷");}
           } 
       }
     });  
     d1.start();
    }
  
  }
/**
 * 提示功能
 * 點選為奇數時可以提示另一張牌的位置。
 **/
public void hint() {
  if(list1.size()%2==1) {
    for(int i=0;i();//存放了點選按鈕的編号
   list=new ArrayList<>();
  jp1.removeAll();
  jp1.setLayout(new GridLayout(4,4,40,20));//中間
  io();
  suiji();
  addjubutton();
  repaint();
  setVisible(true);
}
/**
 * 重寫的滑鼠監聽函數 
 **/
public void actionPerformed(ActionEvent e) {
    // TODO 自動生成的方法存根
  lingsheng.play();
    if(e.getSource()==hint) { hint();  }
    if(e.getSource()==help) { help(); }
    if(e.getSource()==start)
     {if(!A){A=true;music.play();try {
      Thread.sleep(40);
     } catch (InterruptedException e1) {
       //TODO 自動生成的 catch 塊
      e1.printStackTrace();
     }
     music.loop(); jishi(); } } 
    if(e.getSource()==score) {tanchu=true;io();}//位置放錯會導緻第一次點選不出現
    if(A) //數組監聽
     {for(int i=0;i<16;i )    
     { if(e.getSource()==jbutton[i]) { 
      if(b[i]==false) {
      jbutton[i].setIcon(random[i]);list1.add(i); judgle(); b[i]=true; } }}
     }
    if(e.getSource()==restart) {restart();}
    if(e.getSource()==exit) {System.exit(0);}
  }
public static void main(String[] args)
{
  chushi kaishi=new chushi();  //執行開始界面  
}}