java 创建桌面宠物

java 同时被 2 个专栏收录
1 篇文章 0 订阅
10 篇文章 0 订阅

QQ宠物终于因为玩家稀少而挂掉了, 但是想一想还有点怀念(其实早就弃了) 再加上追了近三年, 数码宝贝tri 也算就此完结了, 再一次勾起了童年, 以及.....我为毛不能自己养数码宝贝呢(手动滑稽)

由于大学狗(天天在宿舍打游戏的那种)一枚, 所以本宅也就只会一点java Swing ,也就只能从此下手了

参考文章在这里

大概内容是用swing 的JLabel来加载 图片,通过线程来改变JLabel中的图片来实现动画,以及相关属性的配置

 

代码部分相对比较简单

//        创建并设置窗口
        JFrame frame = new JFrame("digimonDesktopBaby");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 框体透明
        frame.setUndecorated(true); // 取消窗口标题栏
        frame.setBackground(new Color(0,0,0,0));// 背景透明
        //设置位置并显示在最前端
        frame.setBounds(first_x,first_y,0,0);
        frame.setAlwaysOnTop(true);
        //设置取消窗体任务栏图标
        frame.setType(JFrame.Type.UTILITY);
        //设置托盘图标
        setTray(frame);
//        添加图片JLabel
        JLabel digimonLabel = MainFrame.loadPicture(0,0);
        MainFrame.animateNormal(digimonLabel);
        frame.getContentPane().add(digimonLabel);
//        添加移动事件
        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 当鼠标按下的时候获得窗口当前的位置
                origin.x = e.getX();
                origin.y = e.getY();
            }

//            @Override
//            public void mouseClicked(MouseEvent e) {
//                evolut(frame,digimonLabel);
//            }
        });
        frame.addMouseMotionListener(new MouseMotionAdapter() {
            // 拖动(mouseDragged 指的不是鼠标在窗口中移动,而是用鼠标拖动)
            public void mouseDragged(MouseEvent e) {
                // 当鼠标拖动时获取窗口当前位置
                Point p = frame.getLocation();
                // 设置窗口的位置
                // 窗口当前的位置 + 鼠标当前在窗口的位置 - 鼠标按下的时候在窗口的位置
                int x = p.x + e.getX() - origin.x;
                int y = p.y + e.getY()- origin.y;
                frame.setLocation(x, y);
                FileUtil.updateFile(configPath,configName,"pox",""+x);
                FileUtil.updateFile(configPath,configName,"poy",""+y);
            }
        });

    //设置托盘菜单
    private static void setTray(JFrame frame) {
        if (SystemTray.isSupported()) {// 判断系统是否支持系统托盘
            SystemTray tray = SystemTray.getSystemTray(); // 获取当前系统的托盘

            // 为托盘添加一个右键弹出菜单
            PopupMenu popMenu = new PopupMenu();

            MenuItem itemOpen = new MenuItem("打开");
            itemOpen.addActionListener(e -> frame.setVisible(true));

            MenuItem itemHide = new MenuItem("隐藏");
            itemHide.addActionListener(e -> frame.setVisible(false));

            MenuItem itemExit = new MenuItem("退出");
            itemExit.addActionListener(e -> System.exit(0));

            popMenu.add(itemOpen);
            popMenu.add(itemHide);
            popMenu.add(itemExit);

            // 设置托盘图标
            ImageIcon icon = new ImageIcon(publicUrl + "trayIcon.png");
            Image image = icon.getImage().getScaledInstance(icon.getIconWidth(), icon.getIconHeight(), Image.SCALE_DEFAULT);

            TrayIcon trayIcon = new TrayIcon(image, "桌面宠物", popMenu);
            trayIcon.setImageAutoSize(true); // 自适应尺寸,这个属性至关重要

            try {
                tray.add(trayIcon);
            } catch (AWTException e1) {
                e1.printStackTrace();
            }
        }
    }

以上部分是创建好窗体并设置相关信息以及绑定拖动事件

备注的应该还算详细

大概思路是 

创建Jframe -> 设置相关属相 -> 添加托盘菜单 -> 创建显示图片用的JLabel -> 设置相应属性并添加到JFrame

->JLabel绑定拖动事件

其中 animateNormal() 方法是新开一个线程让桌面上的宠物做出日常动作, 眨眨眼,打个哈欠等等 , 由于ps并不是太厉害,所以本宅的滚球兽暂时只能眨眨眼(不会截GIF)

嗯, 大概就是这样了  其中可添加的东西还很多, 以后随缘更新好了(手动滑稽)

(鸣人式教学)

 

/*************************************************************************************************/

更新

18/8/3

/*************************************************************************************************/

 

几天下来又把代码整理了一下, 将整个程序分割成了两大部分: 显示部分和宠物对象

显示部分只负责显示及响应事件, 宠物对象负责相关属性的设置

/******
显示用窗口类
********/
public class MainFrame {
    //初始化
    private static void createAndShowGUI() {
//        创建并设置窗口
        frame = new JFrame("digimonDesktopPet");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 框体透明
        frame.setUndecorated(true); // 取消窗口标题栏
        frame.setBackground(new Color(0,0,0,0));// 背景透明
        //设置位置并显示在最前端
        frame.setBounds(first_x,first_y,0,0);
        frame.setAlwaysOnTop(true);
        //设置取消窗体任务栏图标
        frame.setType(JFrame.Type.UTILITY);
        //设置托盘图标
        setTray();
        //添加显示用的JLabel
        label = new JLabel();
        frame.getContentPane().add(label);
//        添加移动事件
        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 当鼠标按下的时候获得窗口当前的位置
                origin.x = e.getX();
                origin.y = e.getY();
            }

//            @Override
//            public void mouseClicked(MouseEvent e) {
//                digimon.startEat();
//            }
        });
        frame.addMouseMotionListener(new MouseMotionAdapter() {
            // 拖动(mouseDragged 指的不是鼠标在窗口中移动,而是用鼠标拖动)
            public void mouseDragged(MouseEvent e) {
                // 当鼠标拖动时获取窗口当前位置
                Point p = frame.getLocation();
                // 设置窗口的位置
                // 窗口当前的位置 + 鼠标当前在窗口的位置 - 鼠标按下的时候在窗口的位置
                int x = p.x + e.getX() - origin.x;
                int y = p.y + e.getY()- origin.y;
                frame.setLocation(x, y);
                更新配置文件
                FileUtil.updateFile(configPath,configName,"pox","" + x);
                FileUtil.updateFile(configPath,configName,"poy","" + y);
            }
        });
//        拖动文件路过JFrame时
//        张嘴
        /**
         ******
         ** 添加监听器 DragSourceListener
         ** 作用是拖动文件到窗体上而没松开左键
         *****
         **/
//        拖动文件到JFrame时
//        删除文件 假装是被吃掉并播放相应动画
        new DropTarget(frame, DnDConstants.ACTION_MOVE, new DropTargetAdapter()
        {
            public void drop(DropTargetDropEvent dtde){
                //暂停常规动画播放并开始播放删除文件的相应动画
                FileUtil.deleteFile(dtde);
                digimon.startEat();
            }
        });

//        显示
        frame.pack();
        frame.setVisible(true);
    }
    //设置托盘菜单
    private static void setTray() {
        if (SystemTray.isSupported()) {// 判断系统是否支持系统托盘
            SystemTray tray = SystemTray.getSystemTray(); // 获取当前系统的托盘

            // 为托盘添加一个右键弹出菜单
            PopupMenu popMenu = new PopupMenu();

            MenuItem itemOpen = new MenuItem("打开");
            itemOpen.addActionListener(e -> frame.setVisible(true));

            MenuItem itemHide = new MenuItem("隐藏");
            itemHide.addActionListener(e -> frame.setVisible(false));

            MenuItem itemExit = new MenuItem("退出");
            itemExit.addActionListener(e -> System.exit(0));

            popMenu.add(itemOpen);
            popMenu.add(itemHide);
            popMenu.add(itemExit);

            // 设置托盘图标
            ImageIcon icon = new ImageIcon("res/icon/trayIcon.png");
            Image image = icon.getImage().getScaledInstance(icon.getIconWidth(), icon.getIconHeight(), Image.SCALE_DEFAULT);

            TrayIcon trayIcon = new TrayIcon(image, "桌面宠物", popMenu);
            trayIcon.setImageAutoSize(true); // 自适应尺寸,这个属性至关重要

            try {
                tray.add(trayIcon);
            } catch (AWTException e1) {
                e1.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        // 显示应用 GUI 窗口
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
                digimon = new Digimon();
                digimon.setName("滚球兽");
                digimon.setLabel(label);
                digimon.setFrame(frame);
                digimon.startNormal();
            }
        });
    }

    //    全局变量,表示窗口初始位置
    private static int first_x = 1100;
    private static int first_y = 300;

    // 全局的位置变量,用于表示鼠标在窗口上的位置
    private static Point origin = new Point();
    //配置文件路径及名称
    private static String configPath = "config";
    private static String configName = "config.txt";

    private static Digimon digimon;
    private static JFrame frame;
    private static JLabel label;
}

其实和最开始代码类似, 只是稍作整理并没有太大变化

而宠物对象也是

//数码兽基类
public class Digimon {
    private String name; //名字
//    public String level;   //等级
//    public String type; //类型
//    public String attribute;//属性
//    public int size; //动作图数

    public void setLabel(JLabel label) {
        this.label = label;
    }

    public void setFrame(JFrame frame) {
        this.frame = frame;
    }

    @Override
    public String toString() {
        return "Digimon{" +
                "name='" + name + '\'' +
//                ", level='" + level + '\'' +
//                ", type='" + type + '\'' +
//                ", attribute='" + attribute + '\'' +
//                ", size=" + size +
                ", pox=" + pox +
                ", poy=" + poy +
                '}';
    }

    public int getPoy() {
        return poy;
    }
    public void setPoy(int poy) {
        this.poy = poy;
    }
    public int getPox() {
        return pox;
    }
    public void setPox(int pox) {
        this.pox = pox;
    }
    private void init(){
        //        初始化默认显示的图片
        String normalPath = imgPath + this.getName()+"/normal.png";
        AnimateUtil.changeJLabelImg(frame,label,new ImageIcon(normalPath));
    }

    public Digimon(String name, String level, String type, String attribute) {
        this.name = name;
//        this.level = level;
//        this.type = type;
//        this.attribute = attribute;
    }
    public Digimon() {
        this.name = "unname";
//        this.level = "幼年期";
//        this.type = "undefind";
//        this.attribute = "unknown";

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

//    public int getSize() {
//        return size;
//    }
//
//    public void setSize(int size) {
//        this.size = size;
//    }
//    public String getLevel() {
//        return level;
//    }
//
//    public void setLevel(String level) {
//        this.level = level;
//    }
//
//    public String getType() {
//        return type;
//    }
//
//    public void setType(String type) {
//        this.type = type;
//    }

//    public String getAttribute() {
//        return attribute;
//    }
//
//    public void setAttribute(String attribute) {
//        this.attribute = attribute;
//    }

    //行为
    //进化
    public Digimon evolut(){
        return this;
    }
    //动作
    //常规
    private void normal(){
        init();
//         默认动作
        ImageIcon[] icon = new ImageIcon[5];
        int index =0;
        for(int i = 1; i < 6;i++){
            String path = imgPath + this.getName()+"/zhayan ("+ i +").png";
            icon[index++] = new ImageIcon(path);
        }
        normalThread = AnimateUtil.animate(frame,label,icon,500);
    }
    public void startNormal() {
        if(normalThread == null){
            normal();
        }
        normalThread.flag = true;
        AnimateUtil.playTimer(normalThread).start();
    }
    public void stopNormal(int n) {
        normalThread.flag = false;
    }
    //eat
    private void eat(){
//        初始化默认显示的图片
        String normalPath = imgPath + this.getName()+"/normal.png";
        AnimateUtil.changeJLabelImg(frame,label,new ImageIcon(normalPath));
//         默认动作
        ImageIcon[] icon = new ImageIcon[7];
        int index =0;
        for(int i = 1; i < 8;i++){
            String path = imgPath + this.getName()+"/eat"+ i +".png";
            icon[index++] = new ImageIcon(path);
        }
        eatThread = AnimateUtil.animate(frame,label,icon,1000);
    }
    public void startEat(){
        stopNormal(2000);
        if(eatThread == null){
            System.out.println("建立eat动画线程");
            eat();
        }
        eatThread.flag = true;
        AnimateUtil.playNTimes(eatThread,2,this).start();
        eatThread.flag = false;
    }

    private static Behave normalThread = null;
    private static Behave eatThread = null;

    private int pox;
    private int poy;
    private JLabel label = null;
    private JFrame frame = null;
    private final static String imgPath = "res/img/";
    private final static String configPath = "config";
    private final static String configName = "config.txt";
}

        显示动画的方式就是通过开子线程来控制JLabel更换图片, 以上的实现方法感觉在逻辑上有些混乱, 刚开始想的是 写一个线程类,从开始一直运行, 有一个startActivity(Thread thread) 之类的方法来显示某种动作的动画thread ,但是有点懵, 写的是将所有动作在第一次实现时创建好,并通过flag;来控制显示与否(应该很占资源), 就先这样吧 = =

 

 

--------------------分--------------割--------------线-----------

没想到吧  我又要更新了

程序因为重装系统忘记备份, 所以, 你懂的.....()神烦)

但是, 也有一些感想吧, 一年前P都不懂还敢写文章(笑)

现在来看, 如果是为了自己做一个桌面宠物玩的话, 除了java Swing , 基于H5一套的Electron好像是更好的选择具体情况静候我下次更新(手动滑稽)

  • 9
    点赞
  • 9
    评论
  • 52
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值