Java 實現2048游戲之詳細教程


一、整體項目結構

使用Maven來管理項目結構

 

 

 

 

二、基本功能實現

(一)創建游戲窗口(靜態)

package com.baidu.czy;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.net.URI;
import java.net.URL;

import javax.swing.*;

//本類繼承自JFrame,創建游戲窗口,只需要new本類對象
public class GameStart extends JFrame  {

    File f;
    URI uri;
    URL url;
    private ActionEvent e;

    //  添加背景音樂
    public GameStart() { try { f = new File("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\bg1.wav"); uri = f.toURI(); url = uri.toURL();  //解析地址
 AudioClip aau; aau = Applet.newAudioClip(url); aau.loop(); //循環播放
        } catch (Exception e) { e.printStackTrace(); } }     private static final long serialVersionUID = 1L;

    //用於存放數據的二維數組,構成4*4網格的游戲界面數值,數組中的值就是其對應位置方格的值,0代表無值
    private int Numbers[][] = new int[4][4];

    public void init() {
        this.setTitle("2048游戲");
        this.setLocation(450, 100);
        this.setSize(800, 600);
        //自定義,不使用面板布局格式
        this.setLayout(null);


        //添加標簽
        JLabel jLabel = new JLabel("歡迎來到2048游戲!"); jLabel.setFont(new Font("華文行楷", Font.CENTER_BASELINE, 40)); jLabel.setForeground(new Color(0X0000FF)); jLabel.setBounds(20, 500, 400, 50); this.add(jLabel);         //添加圖片1( Public ImageIcon(String filename)//參數可以是絕對路徑也可以是相對路徑 )
        JLabel jLabel1 = new JLabel(new ImageIcon("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\c.png"));
        jLabel1.setBounds(400, 5, 400, 600);
        this.add(jLabel1);

        //添加圖片2
        JLabel jLabel13 = new JLabel(new ImageIcon("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\d.png"));
        jLabel13.setBounds(1, 80, 400, 600);
        this.add(jLabel13);


        // 開始游戲按鈕
        ImageIcon imgicon = new ImageIcon("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\start.png");
        JButton start = new JButton(imgicon);
        start.setFocusable(false);//設置此按鈕不可獲取焦點
        start.setBorderPainted(false);//設置此按鈕沒有邊框
        start.setFocusPainted(false);//設置不繪制邊框,設置 paintFocus屬性,對於要繪制的焦點狀態,該屬性必須為 true。paintFocus 屬性的默認值為 true。一些外觀沒有繪制焦點狀態;它們將忽略此屬性
        start.setContentAreaFilled(false);//設置不繪制邊框,設置 contentAreaFilled 屬性。如果該屬性為 true,則按鈕將繪制內容區域。如果希望有一個透明的按鈕,比如只是一個圖標的按鈕,那么應該將此屬性設置為 false。不要調用 setOpaque(false)。contentAreaFilled 屬性的默認值為 true。
        start.setBounds(5, 10, 120, 30);// 設置按鈕的x,y坐標位置和寬度與高度
        this.add(start);

        //后退一步按鈕
        ImageIcon backicon = new ImageIcon("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\backicon.png");
        JButton back = new JButton(backicon);
        back.setFocusable(false);
        back.setBorderPainted(false);
        back.setFocusPainted(false);
        back.setContentAreaFilled(false);
        back.setBounds(270, 10, 120, 30);// 設置按鈕的x,y坐標位置和寬度與高度
        this.add(back);

        // 關於按鈕
        ImageIcon imgicon2 = new ImageIcon("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\about.png");
        JButton about = new JButton(imgicon2);
        about.setFocusable(false);
        about.setBorderPainted(false);
        about.setFocusPainted(false);
        about.setContentAreaFilled(false);
        about.setBounds(160, 10, 70, 30);
        this.add(about);

        // 分數顯示
        JLabel scoreLabel = new JLabel("分數:0");
        scoreLabel.setBounds(5, 45, 120, 30);
        scoreLabel.setFont(new Font("幼圓", Font.CENTER_BASELINE, 18));
        scoreLabel.setForeground(new Color(0x000000));
        this.add(scoreLabel);

        //靜音按鈕
        JCheckBox isSoundBox = new JCheckBox("靜音");
        isSoundBox.setBounds(320, 45, 120, 30);
        isSoundBox.setFont(new Font("黑體", Font.CENTER_BASELINE, 18));
        isSoundBox.setFocusable(false);
        isSoundBox.setBorderPainted(false);
        isSoundBox.setFocusPainted(false);
        isSoundBox.setContentAreaFilled(false);
        this.add(isSoundBox);


        this.setDefaultCloseOperation(EXIT_ON_CLOSE);//使用 System exit 方法退出應用程序。僅在應用程序中使用。
        this.setResizable(false); //設置此窗體是否可由用戶調整大小。
        this.setVisible(true);// 顯示界面

        // 創建事件處理類,將事件源綁定監聽器
        ComponentListener cl = new ComponentListener(this, Numbers, scoreLabel, start, about, back, isSoundBox);
        start.addActionListener(cl);
        about.addActionListener(cl);
        back.addActionListener(cl);
        isSoundBox.addActionListener(cl);
        this.addKeyListener(cl);
    }

    // 重寫窗體
    @Override
    //paint是Java中AWT畫圖方法
    public void paint(Graphics g) {
        //調用父類的構造方法
        super.paint(g);
        //設置畫筆顏色
        g.setColor(new Color(0x66FF66));
        //填充整個4*4圓角矩形區域,使用當前顏色填充指定的圓角矩形
        g.fillRoundRect(15, 110, 370, 370, 15, 15);// 大矩形框

        g.setColor(new Color(0xFFFAFA));
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                //填充每一個4*4小方格區域
                g.fillRoundRect(25 + i * 90, 120 + j * 90, 80, 80, 15, 15);// 小矩形框
            }
        }

        // 調整數字的位置並上色
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                //如果小方格上數字不為0,則說明有值,進行繪制背景色與數字
                if (Numbers[j][i] != 0) {
                    int FontSize = 30;
                    int MoveX = 0, MoveY = 0;
                    switch (Numbers[j][i]) {
                        case 2:
                            g.setColor(new Color(0xFF0000));
                            FontSize = 30;
                            MoveX = 0;
                            MoveY = 0;
                            break;
                        case 4:
                            g.setColor(new Color(0xede0c8));
                            FontSize = 30;
                            MoveX = 0;
                            MoveY = 0;
                            break;
                        case 8:
                            g.setColor(new Color(0xf2b179));
                            FontSize = 30;
                            MoveX = 0;
                            MoveY = 0;
                            break;
                        case 16:
                            g.setColor(new Color(0xf59563));
                            FontSize = 29;
                            MoveX = -5;
                            MoveY = 0;
                            break;
                        case 32:
                            g.setColor(new Color(0xf67c5f));
                            FontSize = 29;
                            MoveX = -5;
                            MoveY = 0;
                            break;
                        case 64:
                            g.setColor(new Color(0xf65e3b));
                            FontSize = 29;
                            MoveX = -5;
                            MoveY = 0;
                            break;
                        case 128:
                            g.setColor(new Color(0xedcf72));
                            FontSize = 28;
                            MoveX = -10;
                            MoveY = 0;
                            break;
                        case 256:
                            g.setColor(new Color(0xedcc61));
                            FontSize = 28;
                            MoveX = -10;
                            MoveY = 0;
                            break;
                        case 512:
                            g.setColor(new Color(0xedc850));
                            FontSize = 28;
                            MoveX = -10;
                            MoveY = 0;
                            break;
                        case 1024:
                            g.setColor(new Color(0xedc53f));
                            FontSize = 27;
                            MoveX = -15;
                            MoveY = 0;
                            break;
                        case 2048:
                            g.setColor(new Color(0xedc22e));
                            FontSize = 27;
                            MoveX = -15;
                            MoveY = 0;
                            break;
                        default:
                            g.setColor(new Color(0x000000));
                            break;
                    }
                    //數字不為0的小方格覆蓋原色,根據不同的值上不同的色
                    g.fillRoundRect(25 + i * 90, 120 + j * 90, 80, 80, 15, 15);// 小矩形框覆蓋上色
                    g.setColor(new Color(0x000000));
                    g.setFont(new Font("Kristen ITC", Font.PLAIN, FontSize));
                    //繪制字符串,參數分別為:要繪制的字符串,字符串繪制的x坐標,y坐標
                    g.drawString(Numbers[j][i] + "", 25 + i * 90 + 30 + MoveX,
                            120 + j * 90 + 50 + MoveY);
                }
            }
        }
    }


}

(二)實現監聽(具體功能的實現)

package com.baidu.czy;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import javax.swing.*;


public class ComponentListener extends KeyAdapter implements ActionListener {


    private GameStart UI;// 界面對象
    private int Numbers[][];// 存放數據的數組
    private Random rand = new Random();
    private int BackUp[][] = new int[4][4];//用於備份數組,供回退時使用
    private int BackUp2[][] = new int[4][4];//用於備份數組,供起死回生時使用
    public JLabel lb;   //分數標簽
    int score = 0;
    int tempscore, tempscore2;//記錄回退的分數值
    public JButton bt, about, back;
    public JCheckBox isSoundBox;
    //是否勝利,true:勝利,false:失敗
    private boolean isWin = false;
    //是否復活,true:使用復活,false:不使用復活
    private boolean relive = false;
    //是否可以回退,true:不可回退,false:可以回退  (是否已經進行過一次回退了)
    private boolean hasBack = false;
    //是否播放音樂,true:播放音效,false:不播放音效
    private boolean isSound = true;
    //事件
    private ActionEvent e;



    public ComponentListener(GameStart UI, int[][] Numbers, JLabel lb, JButton bt, JButton about, JButton back, JCheckBox isSoundBox) {
        this.UI = UI;
        this.Numbers = Numbers;
        this.lb = lb;
        this.bt = bt;
        this.about = about;
        this.back = back;
        this.isSoundBox = isSoundBox;
    }

   @Override
   public void actionPerformed(ActionEvent e) {
          if (e.getSource() == bt ) {
              //游戲開始
              isWin = false;
              //各個小格賦初值0
              for (int i = 0; i < 4; i++)
                  for (int j = 0; j < 4; j++)
                      Numbers[i][j] = 0;
                      //游戲開始,分數為0
                      score = 0;
                      lb.setText("分數:" + score);
                      //生成4個0-3之間的隨機數
                      int r1 = rand.nextInt(4);
                      int r2 = rand.nextInt(4);
                      int c1 = rand.nextInt(4);
                      int c2 = rand.nextInt(4);
                      //由r1,c1;r2,c2組成兩個初始值,所以初始值的坐標不能重復
                      while (r1 == r2 && c1 == c2) {
                          r2 = rand.nextInt(4);
                          c2 = rand.nextInt(4);
                      }
                      // 生成初始數字(2或者4)
                      int value1 = rand.nextInt(2) * 2 + 2;
                      int value2 = rand.nextInt(2) * 2 + 2;

                      // 把數字存進對應的位置
                      Numbers[r1][c1] = value1;
                      Numbers[r2][c2] = value2;
                      //數字更改,重新繪制圖形,為此組件創建圖形上下文
                      UI.paint(UI.getGraphics());




        } else if (e.getSource() == about) {
            //點擊了關於標簽
            JOptionPane.showMessageDialog(UI, "游戲規則:\n"
                    + "1、開始時棋盤內隨機出現兩個數字,出現的數字僅可能為2或4\n"
                    + "2、玩家可以選擇上下左右四個方向,若棋盤內的數字出現位移或合並,視為有效移動\n"
                    + "3、玩家選擇的方向上若有相同的數字則合並,每次有效移動可以同時合並,但不可以連續合並\n"
                    + "4、合並所得的所有新生成數字相加即為該步的有效得分\n"
                    + "5、玩家選擇的方向行或列前方有空格則出現位移\n"
                    + "6、每有效移動一步,棋盤的空位(無數字處)隨機出現一個數字(依然可能為2或4)\n"
                    + "7、棋盤被數字填滿,無法進行有效移動,判負,游戲結束\n"
                    + "8、棋盤上出現2048,判勝,游戲結束。\n"
            );
        } else if (e.getSource() == back && hasBack == false) {
            System.out.println("回退");
            //點擊了回退一步標簽,而且只能回退一次,只有再執行一次上下左右操作才可以再次回退
            hasBack = true;
            //判斷本次回退是回退上一步,還是復活,回退上上步
            if (relive == false) {
                //替換上一步的分數
                score = tempscore;
                lb.setText("分數:" + score);
                for (int i = 0; i < BackUp.length; i++) {
                    Numbers[i] = Arrays.copyOf(BackUp[i], BackUp[i].length);
                }
            } else {
                //選擇了起死回生
                score = tempscore2;
                lb.setText("分數:" + score);
                for (int i = 0; i < BackUp2.length; i++) {
                    Numbers[i] = Arrays.copyOf(BackUp2[i], BackUp2[i].length);
                }
                //再給一次復活的機會
                relive = false;
            }
            //重新繪制
            UI.paint(UI.getGraphics());
        } else if (e.getSource().equals(isSoundBox)) {
            //是否選中靜音復選框
            if (isSoundBox.isSelected()) {
                isSound = false;
            } else {
                isSound = true;
            }
        }
    }




    // 鍵盤監聽,監聽游戲焦點的←,↑,→,↓;方向鍵鍵值:左:37上:38右:39下:40
    public void keyPressed(KeyEvent event) {

        int Counter = 0;// 記錄數字有效移動位數,判斷是否移動了
        int NumCounter = 0;// 記錄當前有數字的小方格數量,判斷是否已滿
        int NumNearCounter = 0;// 記錄相鄰格子數字相同的對數

        hasBack = false;
        //每次進行真正的移位合並操作之前,記錄前一步

        //記錄上上步
        if (BackUp != null || BackUp.length != 0) {
            tempscore2 = tempscore;// 先把分數備份好
            // 下面的for循環調用java.util.Arrays.copyOf()方法復制數組,實現備份
            for (int i = 0; i < BackUp.length; i++) {
                BackUp2[i] = Arrays.copyOf(BackUp[i], BackUp[i].length);
            }
        }
        //記錄上步
        tempscore = score;// 先把分數備份好
        // 下面的for循環調用java.util.Arrays.copyOf()方法復制數組,實現備份
        for (int i = 0; i < Numbers.length; i++) {
            BackUp[i] = Arrays.copyOf(Numbers[i], Numbers[i].length);
        }

        if (isWin == false) {
            switch (event.getKeyCode()) {

                case 37:
                    // 向左移動
                    /*
                    (1)在移動的過程中,判斷與其相鄰的格子,如果相鄰的格子為空,則移動,並將當前的格子清0
                    (2)移動后,若格子相鄰並且數值相等,則求和並且清0
                     */
                    if (isSound == true) {
                        new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\move.wav").start();// 播放移位音樂
                    }
                    //經過這個循環,把每行有值的格子,都被搬到最左邊了,同一行右側有值的格子,覆蓋左側值為0的格子
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                //per相當於是相鄰位置
                                int pre = l - 1;
                                while (pre >= 0 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    //移動后清0
                                    Numbers[h][pre + 1] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    //表盤當前左側相鄰相等的值會相加,造成左邊值為【和】,相鄰右邊值為【0】
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (l + 1 < 4
                                    && (Numbers[h][l] == Numbers[h][l + 1])     //相鄰兩列數值相加,並要求兩列不同時為0
                                    && (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\merge.wav").start();
                                //數值合並
                                Numbers[h][l] = Numbers[h][l] + Numbers[h][l + 1];
                                Numbers[h][l + 1] = 0;
                                Counter++;
                                score += Numbers[h][l];
                                if (Numbers[h][l] == 2048) {
                                    isWin = true;
                                }
                            }
                    //經過這個循環,把每行有值的格子,都被搬到最左邊了,同一行右側有值的格子,覆蓋左側值為0的格子
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l - 1;
                                while (pre >= 0 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre + 1] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    break;

                case 39:// 向右移動
                    if (isSound == true)
                        new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\move.wav").start();
                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l + 1;
                                while (pre <= 3 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre - 1] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }

                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (l + 1 < 4
                                    && (Numbers[h][l] == Numbers[h][l + 1])
                                    && (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\merge.wav").start();
                                Numbers[h][l + 1] = Numbers[h][l]
                                        + Numbers[h][l + 1];
                                Numbers[h][l] = 0;
                                Counter++;
                                score += Numbers[h][l + 1];
                                if (Numbers[h][l + 1] == 2048) {
                                    isWin = true;
                                }
                            }
                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l + 1;
                                while (pre <= 3 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre - 1] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    break;

                case 38:
                    // 向上移動
                    if (isSound == true)
                        new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\move.wav").start();
                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h - 1;
                                while (pre >= 0 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre + 1][l] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (h + 1 < 4
                                    && (Numbers[h][l] == Numbers[h + 1][l])
                                    && (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\merge.wav").start();
                                Numbers[h][l] = Numbers[h][l] + Numbers[h + 1][l];
                                Numbers[h + 1][l] = 0;
                                Counter++;
                                score += Numbers[h][l];
                                if (Numbers[h][l] == 2048) {
                                    isWin = true;
                                }
                            }

                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h - 1;
                                while (pre >= 0 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre + 1][l] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    break;

                case 40:
                    // 向下移動
                    if (isSound == true)
                        new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\move.wav").start();
                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h + 1;
                                while (pre <= 3 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre - 1][l] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (h + 1 < 4
                                    && (Numbers[h][l] == Numbers[h + 1][l])
                                    && (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\\JavaProject\\HandleGame2048(2)\\src\\main\\resources\\res\\merge.wav").start();
                                Numbers[h + 1][l] = Numbers[h][l]
                                        + Numbers[h + 1][l];
                                Numbers[h][l] = 0;
                                Counter++;
                                score += Numbers[h + 1][l];
                                if (Numbers[h + 1][l] == 2048) {
                                    isWin = true;
                                }
                            }

                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h + 1;
                                while (pre <= 3 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre - 1][l] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    break;

            }
            //移位,合並,移位完成后,判斷是否有可重復值
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    //判斷相鄰左右位置有沒有重復值
                    if (Numbers[i][j] == Numbers[i][j + 1]
                            && Numbers[i][j] != 0) {
                        NumNearCounter++;
                    }
                    //判斷相鄰上下位置有沒有重復值
                    if (Numbers[i][j] == Numbers[i + 1][j]
                            && Numbers[i][j] != 0) {
                        NumNearCounter++;
                    }
                    if (Numbers[3][j] == Numbers[3][j + 1]//第四行只需要判斷是否與右邊有重復
                            && Numbers[3][j] != 0) {
                        NumNearCounter++;
                    }
                    if (Numbers[i][3] == Numbers[i + 1][3]//第四列只需要判斷與下邊是否有重復
                            && Numbers[i][3] != 0) {
                        NumNearCounter++;
                    }
                }
            }
            //判斷不為0的空余格子數
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (Numbers[i][j] != 0) {
                        NumCounter++;
                    }
                }
            }
            System.out.println(Counter);

            //有效移位數>0,則補充一個新的2或者4
            if (Counter > 0) {
                lb.setText("分數:" + score);
                //隨機產生0~3的數字,選中位置
                int r1 = rand.nextInt(4);
                int c1 = rand.nextInt(4);
                while (Numbers[r1][c1] != 0) {
                    r1 = rand.nextInt(4);
                    c1 = rand.nextInt(4);
                }
                //產生2或4
                int value1 = rand.nextInt(2) * 2 + 2;
                Numbers[r1][c1] = value1;
            }

            if (isWin == true) {
                UI.paint(UI.getGraphics());
                JOptionPane.showMessageDialog(UI, "恭喜你贏了!\n您的最終得分為:" + score);
            }

            if (NumCounter == 16 && NumNearCounter == 0) {
                //移動后滿格並且沒有可合並的小格子,游戲結束relive:復活一次
                relive = true;
                JOptionPane.showMessageDialog(UI, "沒地方可以合並咯!!"
                        + "\n很遺憾,您輸了~>_<~" + "\n悄悄告訴你,游戲有起死回生功能哦,不信你“退一步”試試?"
                        + "\n說不定能扭轉乾坤捏 (^_~)");
            }
            UI.paint(UI.getGraphics());
        }

    }

}

(三)實現線程播放音樂

package com.baidu.czy;


import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;



//播放聲音的線程
public class PlaySound extends Thread {
    private String filename;


    public PlaySound(String wavfile) {

        filename = "" + wavfile;
    }
    public void run() {
        File soundFile = new File(filename);
        AudioInputStream audioInputStream = null;
        try {
            //獲得音頻輸入流
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (Exception e1) {
            e1.printStackTrace();
            return;
        }
        //指定聲音流中特定數據安排
        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
        try {
            //從混頻器獲得源數據行
            auline = (SourceDataLine) AudioSystem.getLine(info);
            //打開具有指定格式的行,這樣可使行獲得所有所需的系統資源並變得可操作。
            auline.open(format);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        //允許數據行執行數據 I/O
        auline.start();
        int nBytesRead = 0;
        // 這是緩沖
        byte[] abData = new byte[512];
        try {
            while (nBytesRead != -1) {
                //從音頻流讀取指定的最大數量的數據字節,並將其放入給定的字節數組中
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0)
                    //通過此源數據行將音頻數據寫入混頻器
                    auline.write(abData, 0, nBytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }
    }
}

(四)測試類

package com.baidu.czy.test;

import com.baidu.czy.GameStart;

public class StartGameTest {
    public static void main(String[] args) {
         GameStart view = new GameStart();
         view.init();
         new GameStart();

    }
}

 三、運行結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM