zoukankan      html  css  js  c++  java
  • 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, "游戏规则:
    "
                        + "1、开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4
    "
                        + "2、玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动
    "
                        + "3、玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并
    "
                        + "4、合并所得的所有新生成数字相加即为该步的有效得分
    "
                        + "5、玩家选择的方向行或列前方有空格则出现位移
    "
                        + "6、每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4)
    "
                        + "7、棋盘被数字填满,无法进行有效移动,判负,游戏结束
    "
                        + "8、棋盘上出现2048,判胜,游戏结束。
    "
                );
            } 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, "恭喜你赢了!
    您的最终得分为:" + score);
                }
    
                if (NumCounter == 16 && NumNearCounter == 0) {
                    //移动后满格并且没有可合并的小格子,游戏结束relive:复活一次
                    relive = true;
                    JOptionPane.showMessageDialog(UI, "没地方可以合并咯!!"
                            + "
    很遗憾,您输了~>_<~" + "
    悄悄告诉你,游戏有起死回生功能哦,不信你“退一步”试试?"
                            + "
    说不定能扭转乾坤捏 (^_~)");
                }
                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();
    
        }
    }

     三、运行结果

  • 相关阅读:
    Linux之RPM 软件包管理
    软件开发模型之优缺点
    软件开发模型之迭代模型
    软件工程之软件开发模型类型
    软件开发模型之边做边改模型
    软件开发模型之螺旋模型
    软件开发模型之快速原型模型
    软件工程之软件开发模型介绍和选择
    卡内基的沟通原则
    软件开发模型之增量模型
  • 原文地址:https://www.cnblogs.com/my-program-life/p/10987657.html
Copyright © 2011-2022 走看看