java 创建桌面宠物
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); // 添加圖片JLabelJLabel digimonLabel = MainFrame.loadPicture(0,0);MainFrame.animateNormal(digimonLabel);frame.getContentPane().add(digimonLabel); // 添加移動事件frame.addMouseListener(new MouseAdapter() {@Overridepublic 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();//添加顯示用的JLabellabel = new JLabel();frame.getContentPane().add(label); // 添加移動事件frame.addMouseListener(new MouseAdapter() {@Overridepublic 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() {@Overridepublic 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;}@Overridepublic 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;}//eatprivate 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好像是更好的選擇具體情況靜候我下次更新(手動滑稽)
總結
以上是生活随笔為你收集整理的java 创建桌面宠物的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台式计算机主要有哪些硬件组成,计算机的硬
- 下一篇: 如何用STC32产生SPWM波