GamejFrame.java


import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
  
public class GamejFrame extends JFrame implements KeyListener,ActionListener {
    //jFrame表示一个界面或者窗体
    //子类也表示界面或者窗体
    //规定:gamejframe这个界面表示的就是游戏的主界面
    //以后跟游戏相关的所有逻辑都写在这个类里面

    //记录空白方块的位置
    int x = 0;
    int y = 0;
    int[][] Arr = new int[4][4];
    int[][] Win = {
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,0},
    };
    int step =0;
    int index = ((new Random()).nextInt(7) + 1);
  

    //创建选项下条目的对象
    JMenuItem replay = new JMenuItem("重新游戏");
    JMenuItem relogin = new JMenuItem("重新登录");
    JMenuItem close = new JMenuItem("关闭游戏");
  
    JMenuItem account = new JMenuItem("V我50");
  
    public GamejFrame(){
        //初始化界面
        initjFrame();
        //初始化菜单
        initjmenuBar();
        //初始化图片
        //先打乱图片
        Arr = upsetIcon();
        intiImage();
        //初始化按钮
        intijbt();
        //设置窗口可见
        this.setVisible(true);
    }
  
    private void intijbt() {
//        //创建按钮对象
//        JButton jbt = new JButton("点我");
//        //设置位置和大小
//        jbt.setBounds(300,500,100,50);
//        //创建事件监听
//        jbt.addActionListener(new ActionListener() {
//            @Override
//            public void actionPerformed(ActionEvent e) {
//                System.out.println("按钮被点击");
//            }
//        });
//        //把按钮添加到界面中
//        this.add(jbt);
    }
  

    private void intiImage() {
        //清除已经有的图片
        this.getContentPane().removeAll();
        //判断胜利并添加胜利图片
        if(iswin()){
            JLabel jlabel = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\win.png"));
            jlabel.setBounds(203,283,197,73);
            this.add(jlabel);
        }
        //添加步数显示
        JLabel stepCont = new JLabel("步数:"+ step);
        stepCont.setBounds(50,30,100,20);
        this.add(stepCont);
        //输出图片
        //用随机图片
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                //首先需要创建一个图片对象
                //new ImageIcon("D:\\Documents\\java_study\\java_study\\Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\animal\\animal1\\1.jpg");
                //然后再创建一个jLabel管理容器对象
                JLabel jlabel = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\animal\\animal"+index+"\\"+Arr[i][j]+".jpg"));
                //设置图片位置需要在添加之前
                jlabel.setBounds(j*105+84, i*105+134, 105, 105);
                //给图片设置边框
                jlabel.setBorder(new BevelBorder(0));
                //最后把管理容器添加到界面中
                this.add(jlabel);
            }
        }
        JLabel jlabel = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\background.jpg"));
        jlabel.setBounds(40,40,508,560);
        this.add(jlabel);
        //刷新界面
        this.getContentPane().repaint();
    }
  
    private boolean iswin() {
        for (int i = 0; i < Win.length; i++) {
            for (int i1 = 0; i1 < Win.length; i1++) {
                if(Win[i][i1] != Arr[i][i1]){
                    return false;
                }
            }
        }
        return true;
    }
  
    private void initjmenuBar() {
        ////////////////////////在游戏窗口中添加菜单//////////////////////
        //首先创建菜单bar对象,其中每一个菜单按钮都是jMenu对象
        //需要几个按钮就要创建几个jMenu对象
        //在jMenu下拉框中每一个独立选项都是jMenuitem对象,需要再创建
  
  
        //初始化菜单
        JMenuBar jMenuBar = new JMenuBar();
  
        //创建菜单上选项的对象
        JMenu functionjMenu = new JMenu("功能");
        JMenu aboutjMenu = new JMenu("关于");
  
        //将每一个条目添加到选项中
        functionjMenu.add(replay);
        functionjMenu.add(relogin);
        functionjMenu.add(close);
  
        aboutjMenu.add(account);

        //给条目绑定事件
        replay.addActionListener(this);
        relogin.addActionListener(this);
        close.addActionListener(this);
        account.addActionListener(this);
  
        //再将菜单选项添加到菜单中
        jMenuBar.add(functionjMenu);
        jMenuBar.add(aboutjMenu);
  
        //给整个界面设置菜单(将菜单放入主界面)
        this.setJMenuBar(jMenuBar);
    }
  
    private void initjFrame() {
        this.setSize(603,680);
        // 设置标题
        this.setTitle("拼图小游戏 By QCQC");
        // 设置置顶
        this.setAlwaysOnTop(true);
        //        // 设置可见                设置可见应该在最后
        //        this.setVisible(true);
        //设置窗口初始化位置在屏幕中心
        this.setLocationRelativeTo(null);
        //点击叉叉之后程序并未停止,需要设置窗口关闭模式:
        //     0为什么都不做,1为界面隐藏(默认),2为所有界面关闭才退出程序(必须所有的窗口都是这个属性),3为只要关闭其中一个程序则虚拟机结束
        this.setDefaultCloseOperation(3);
        //取消默认的居中放置,这样才能自己指定坐标
        this.setLayout(null);
        //给整个窗体添加键盘监听
        this.addKeyListener(this);
    }
    private int[][] upsetIcon(){
        //产生一个顺序数组
        int[] tempArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        //遍历每一个元素,与随机的元素交换
        for (int i = 0; i < tempArr.length; i++) {
            int temp = tempArr[i];
            int rndnum = (new Random().nextInt(15));
            tempArr[i] = tempArr[rndnum];
            tempArr[rndnum] = temp;
        }
        //将一维数组转换为二维数组
        int[][] Arr = new int[4][4];
        for (int i = 0; i < tempArr.length; i++) {
            if (tempArr[i] != 0) {
                Arr[i / 4][i % 4] = tempArr[i];
            }else{
                x = i % 4;
                y = i / 4;
            }
        }
        return Arr;
    }
    @Override
    public void keyTyped(KeyEvent e) {
  
    }
    @Override
    public void keyPressed(KeyEvent e) {
        //如果已经胜利,所有按键无效
        if(iswin()){
            return;
        }
        System.out.println("按键按下");
        int code = e.getKeyCode();
        if(code == 65){
            //移除所有图片
            this.getContentPane().removeAll();
            //添加新图片
            JLabel all = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\animal\\animal"+index+"\\"+"all.jpg"));
            all.setBounds(83,134,420,420);
            this.getContentPane().add(all);
            //重新添加背景
            JLabel jlabel = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\background.jpg"));
            jlabel.setBounds(40,40,508,560);
            this.add(jlabel);
            this.repaint();
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        //如果已经胜利,所有按键无效
        if(iswin()){
            return;
        }
        //获取按键码
        int code = e.getKeyCode();
        if(code == 37){
            System.out.println("向左移动");
            //x -1 ,y不变,但是要考虑x大于0
            if(x-1 < 0){
                x = 0;
            }else{
                Arr[y][x] = Arr[y][x-1];
                Arr[y][x-1] = 0;
                x--;
                step++;
            }
        }else if(code == 38){
            System.out.println("向上移动");
            if(y-1 < 0){
                y = 0;
            }else{
                Arr[y][x] = Arr[y-1][x];
                Arr[y-1][x] = 0;
                y--;
                step++;
            }
        }else if(code == 39){
            System.out.println("向右移动");
            if(x+1 > 3){
                x = 3;
            }else{
                Arr[y][x] = Arr[y][x+1];
                Arr[y][x+1] = 0;
                x++;
                step++;
            }
        }else if(code == 40){
            System.out.println("向下移动");
            if(y+1 > 3){
                y = 3;
            }else{
                Arr[y][x] = Arr[y+1][x];
                Arr[y+1][x] = 0;
                y++;
                step++;
            }
        }else if(code == 87){
            for (int i = 0; i < Win.length; i++) {
                for (int i1 = 0; i1 < Win.length; i1++) {
                    Arr[i][i1] = Win[i][i1];
                }
            }
        }
        intiImage();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if(obj == replay){
            index = ((new Random()).nextInt(7) + 1);
            Arr = upsetIcon();
            step = 0;
            intiImage();
        }else if(obj == relogin){
  
        }else if(obj == close){
            System.exit(0);
        }else if(obj == account){
            //移除所有图片
            this.getContentPane().removeAll();
            //添加新图片
            JLabel vivo = new JLabel(new ImageIcon("Day16\\src\\com\\qcqc\\javaStudy\\puzzleGame\\image\\vivo50.png"));
            vivo.setBounds(0,0,583,800);
            this.getContentPane().add(vivo);
            this.repaint();
        }
    }
}