java做拼图游戏并实现打包

package com.itheima.ui;

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这个界面表示的就是游戏的主界面
    //以后根义序相关的所有逻辑都写在这个类中


    //构造器 此处相当于空参构造 那么这里的his就找到APP中的当前对象new GameFrame 的地址值

    //创建二维数组 目的 用来管理数据

    int[][] data = new int[][]//正确数组  用于打乱
                  {{1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 0}
            };

    private int [] [] getWin(){//定义win数组总是会被修改 只好设置了GetWin方法 来防止数组被修改
        return new int[][]//正确数组  用于胜利判断
                {{1, 2, 3, 4},
                        {5, 6, 7, 8},
                        {9, 10, 11, 12},
                        {13, 14, 15, 0}
                };
    }




    //创建选项下面的条目对象
    JMenuItem replayItem = new JMenuItem("重新游戏");
    JMenuItem reLoginItem = new JMenuItem("重新登陆");
    JMenuItem CloseItem = new JMenuItem("关闭游戏 ");

    JMenuItem accountItem = new JMenuItem("微信号");


    //换图功能
    JMenuItem level_1 = new JMenuItem("换图——动物");
    JMenuItem level_2 = new JMenuItem("换图——姐姐");



        boolean CUse;
//定义一个图片 ;记录当前展示图片的路径
Random r = new Random();

    String path = "image\\animal\\animal"+(r.nextInt(8)+1) +"\\";




    //记录空白方块在二维数组中的位置
    int x = 3;
    int y = 3;

    //定义变量 用来统计步数
    int step = 0;


    public GameJFrame() {//setRootPane(createRootPane());空参中制动创建了一个隐藏的容器  在创建JFrame就自动创建了

        System.out.println(path);
        //初始化界面
        initJFrame();

        //初始化菜单
        initJMenuBar();

        //初始化数据 (打乱 )
        InitDate();

        //初始化图片
        InitImage();

        Victory();

        //显示界面 写在最后
        this.setVisible(true);//改变界面默认隐藏为显示 的属性
    }


    private void initJFrame() {//this也可以省略
        //设置宽高
        this.setSize(603, 680);//单位是像素
        //设置标题
        setTitle("拼图单鸡版 V1.0");
        //设置界面置顶
        this.setAlwaysOnTop(true);
        //设置窗口居中
        this.setLocationRelativeTo(null);
        //设置游戏的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//点击一个界面所有的界面都会关闭

        //取消默认的居中放置,只有取消了才会按照xy轴形式添加组件
        this.setLayout(null);

        //给整个界面添加键盘监听事件  !绑定
        this.addKeyListener(this);
    }


    //初始化菜单
    private void initJMenuBar() {
        //1.创建整个的菜单对象
        JMenuBar jMenuBar = new JMenuBar();

        //创建菜单上面的两个选项的对象
        JMenu funcJMenu = new JMenu("功能 ");
        JMenu change = new JMenu("换图 ");
        JMenu aboutJMenu = new JMenu("关于zky");


        //将每一个选项下面的条目添加到选项当中
        funcJMenu.add(replayItem);//重新游戏
        funcJMenu.add(reLoginItem);//重新登陆
        funcJMenu.add(CloseItem);//关闭游戏

        //换图
        change.add(level_1);
        change.add(level_2);


        aboutJMenu.add(accountItem);//微信号


        //给条目绑定事件
        replayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        CloseItem.addActionListener(this);
        accountItem.addActionListener(this);
        level_1.addActionListener(this);
        level_2.addActionListener(this);
        //将菜单里面两个选项添加到菜单当中
        jMenuBar.add(funcJMenu);
        jMenuBar.add(aboutJMenu);
        jMenuBar.add(change);

        //给整个界面设置菜单
        this.setJMenuBar(jMenuBar);
    }


    private void InitDate() {
        Random r = new Random();
        for (int i = 0; i < 5000; i++) {//随机操作5000次后取得随机二维数组
            int a = r.nextInt(4);//通过(random 0-3)来随机操作空白块
            if (a == 0) {//上
                //防止图片index超出的bug
                if (x == 3) {
                    continue;//边界数组超过范围直接跳出当前循环
                }
                //把要替换的图片赋值给空白
                data[x][y] = data[x + 1][y];
                //把被替换的图片变成空白 0
                data[x + 1][y] = 0;
                //空白已经被替换 所以坐标x轴++
                x++;
            } else if (a == 1) {//下
                if (x == 0) {
                    continue;
                }
                data[x][y] = data[x - 1][y];
                data[x - 1][y] = 0;
                x--;
            } else if (a == 2) {//左
                if (y == 3) {
                    continue;
                }
                data[x][y] = data[x][y + 1];
                data[x][y + 1] = 0;
                y++;
            } else {//右
                if (y == 0) {
                    continue;
                }
                data[x][y] = data[x][y - 1];
                data[x][y - 1] = 0;
                y--;
            }
        }
    }


    //初始化图片
    //        int number = 0;
    private void InitImage() {
        //清空已经清空的所有图片
        this.getContentPane().removeAll();
        if (Victory()) {
            JLabel winJLabel = new JLabel(new ImageIcon("image//win.png"));
            winJLabel.setBounds(203,283,197,73);
            this.getContentPane().add(winJLabel);

        }

        //绝对路径 :盘符开始
        //相对路径:相对当前项目而言


        //外循环
        for (int j = 0; j < 4; j++) {//统一修改某变量名称 shift+F6
            //内循环
            for (int i = 0; i < 4; i++) {

                //获得随机二维数组内的索引值用来打开图片
                int number = data[j][i];

                //创建一个图片ImageIcon的对象
                //    ImageIcon icon = new ImageIcon("C:\\Users\\11135\\Desktop\\javawork\\game\\image\\animal\\animal3\\1.jpg");

                //创建一个JLabel对象
                JLabel jLabel1 = new JLabel(new ImageIcon                                     //每迭代一次后number需要自增 第16张图找不到会自动生成空白
                        (path + number + ".jpg"));

                jLabel1.setBounds(105 * i + 83, 105 * j + 134, 105, 105);//加一些坐标偏移 让图片为中间偏下


                //给图片添加边界   raised凸起   LOWERED凹陷
                jLabel1.setBorder(new BevelBorder(BevelBorder.LOWERED));

                //最后把管理容器添加到界面里
//                    add(jLabel1);//默认把图片放在最中间
                this.getContentPane().add(jLabel1);//已经自动创建了 所以直接获取就可以了
            }
        }

        //添加背景图片
        ImageIcon bj = new ImageIcon("image\\background.png");//相对路径
        JLabel background = new JLabel(bj);//交给JLabel管理
        background.setBounds(40, 40, 508, 560);        //坐标 默认图片的坐标点都在左上角
        this.getContentPane().add(background);


        if(CUse){
            JLabel cheat_words = new JLabel("步数:都这样了你还要看步数?");
            cheat_words.setBounds(50,30,300,20);
            add(cheat_words);
        }
        else {
            JLabel stepCount = new JLabel("步数:" + step);
            stepCount.setBounds(50, 30, 100, 20);
            add(stepCount);
        }


        //刷新图片
        this.getContentPane().repaint();

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {

        int code = e.getKeyCode();
        if (code == 65) {//查看原图
            //把界面中所有的图片删除

            this.getContentPane().removeAll();
            JLabel all = new JLabel(new ImageIcon(path + "all.jpg"));
            all.setBounds(83, 134, 420, 420);
            this.getContentPane().add(all);
            ImageIcon bj = new ImageIcon("image\\background.png");//相对路径
            JLabel background = new JLabel(bj);//交给JLabel管理
            background.setBounds(40, 40, 508, 560);        //坐标 默认图片的坐标点都在左上角
            this.getContentPane().add(background);
            this.getContentPane().repaint();
        }
        if (Victory()){
            return;
        }


        //对上下左右进项进行判断


        if (code == 37) {//←
            if (y == 3) {
                return;
            }
            data[x][y] = data[x][y + 1];
            data[x][y + 1] = 0;
            y++;
            //每移动一次步数++
            step++;
            InitImage();


        } else if (code == 38) {//↑  now/original
            //防止图片移除的bug
            if (x == 3) {
                return;
            }
            //把要替换的图片赋值给空白
            data[x][y] = data[x + 1][y];
            //把被替换的图片变成空白 0
            data[x + 1][y] = 0;
            //空白已经被替换 所以坐标x轴++
            x++;
            step++;
            //调用方法 用最新的方法加载图片
            InitImage();

        } else if (code == 39) {//→
            if (y == 0) {
                return;
            }
            data[x][y] = data[x][y - 1];
            data[x][y - 1] = 0;
            y--;
            step++;
            InitImage();

        } else if (code == 40) {//↓
            if (x == 0) {
                return;
            }
            data[x][y] = data[x - 1][y];
            data[x - 1][y] = 0;
            x--;
            step++;
            InitImage();

        }


        //查看全部图片的功能

    }

    @Override
    public void keyReleased(KeyEvent e) {


        int code = e.getKeyCode();

        //对于这个e的理解 : 这个方法是重写了接口KeyListener内的抽象方法
        // 抽象方法传入的参数是KeyEvent类的e ,e就用来调用KeyEvent 里面的方法

//        System.out.println(code);//上下左右 38 40 37  39


        if (code == 65) {//松开A后正常显示全部图片
            InitImage();
        }
        else if (!Victory() &&code == 87) {//一键完成 松开W之后白块发生位移 重置白块位置
            data = getWin();
            CUse = true;

            //更改空白方块记录的位置
//            不调整会导致重新开局时实际白块位置和加载不同步(直接重置了数组)
            x = 3;
            y = 3;
            InitImage();
        }
    }

    public boolean Victory() {
        //判断数组中的数据和data是否相同

        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] != getWin()[i][j]) {
                    return false;//只要有一个数据不一样 返回false
                }
            }
        }
        return true;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if (obj == replayItem){
            //重新游戏
            //再次打乱二维数组中的数据 重新加载图片 计步器 作弊器常量请0
            step = 0;
            CUse = false;
            InitDate();
            InitImage();


        } else if (obj == reLoginItem) {
            //重新登陆
            this.setVisible(false);
            //打开登陆界面
            new LoginJFrame();


        } else if (obj == CloseItem) {
            //关闭游戏\
            System.exit(1);
        } else if (obj == accountItem) {
            //微信号

/*
关于JDialog的思考·

JDialog是一个页面 (弹窗)
设置了JLabel  后把JLabel(容器)添加到JDialog这个页面中 而后可以通过JLabel管理图片
通过JDialog来设置页面  下来多都是用JDialog来管理页面的操作


 */

            JDialog jDialog = new JDialog();
            JLabel jLabel = new JLabel(new ImageIcon("image//mamam.jpg"));
            //位置和宽高设置
            jLabel.setBounds(0,0,258,258);
            //乞丐
            jDialog.setTitle("赏俺一毛钱");
            //把图片添加到弹框之中
            jDialog.getContentPane().add(jLabel);//jDialog.add(jLabel);
            //弹框大小设置
            jDialog.setSize(344,344);
            //弹框置顶
            jDialog.setAlwaysOnTop(true);
            //弹框居中
            jDialog.setLocationRelativeTo(null);
            //弹框不关闭则无法关闭下面的界面
            jDialog.setModal(true);
            //让弹框显示出来
            jDialog.setVisible(true);

        } else if (obj == level_1) {//动物
            path = "image\\animal\\animal"+(r.nextInt(8)+1) +"\\";
            //传入路径后重新加载
            InitDate();
            InitImage();

        } else if (obj == level_2) {//姐姐
            path =  "image\\girl\\girl"+(r.nextInt(13)+1) + "\\";
            InitDate();
            InitImage();
        }
    }
}

在主程序中 new GameJFrame();运行 

后续的打包用了 exe4j和inno setup compiler

jdk调整成了jdk11

java的代码量感觉太大了 ...

你可能感兴趣的:(java,ui,开发语言)