用java的robot類以及Gui 製作一個遊戲(陰陽師)腳本

**

用java的robot類以及Gui 製作一個遊戲(陰陽師)腳本

**

  由於陰陽師這個遊戲肝度太大,就決定寫一個腳本來模擬玩家的重複性操作.所以我就決定用java中的robot類中的一些方法來模擬鼠標點擊,移動等功能,具體方法見下圖.
 因爲一個好看的界面能讓人看着更加的舒服,所以就決定用java中的GUI來設計一個操作界面,功能更能很好的展現方便使用.

具體思路

 腳本的一個難題就是如何防止被封號,我的看法是使腳本的操作更加符合人的操作:禁止點擊鼠標速度過快,過多,禁止點擊同一位置,禁止每一次點擊鼠標按下釋放時間一致;
  而另一個難題就是如何讓鼠標點擊該點的位置,判斷什麼時候結束是麼時候點擊開始,這裏不能用記錄每一個操作的座標,這樣不僅不方便還可能出錯.所以我用了從一個大圖片中找到小圖片並且返回中心座標的這個思路(借鑑大佬).
 廢話不多說,看圖看代碼

功能

魂土,日輪,逢魔,癡卷,地域鬼王,日常任務功能正在開發

腳本運行圖

 目前功能就這麼多,此外還增加了腳本置頂功能,可以持續關注運行狀態
目前就添加了這些功能,此外我還增加了腳本置頂功能

代碼

查圖功能:

//全屏截圖
	  public BufferedImage getFullScreenShot() {
		  BufferedImage bfImage = null;
		        try {
		            Robot robot = new Robot();
                    bfImage = robot.createScreenCapture(new Rectangle(x, y, width, height));
	    	           } catch (AWTException e) {
	               e.printStackTrace();
		           }
		           return bfImage;
		  
	  }
//從本地文件讀取目標圖片
	  public BufferedImage getBfImageFromPath(String keyImagePath) {
		           BufferedImage bfImage = null;
		           try {
		               bfImage = ImageIO.read(new File(keyImagePath));
		           } catch (IOException e) {
		               e.printStackTrace();
		           }
		           return bfImage;
		       }
//     判斷屏幕截圖上目標圖範圍內的全部點是否全部和小圖的點一一對應
	  public boolean isMatchAll(int y, int x) {
		           int bigpY = 0;
		           int bigpX = 0;
		           int judeg= 0;
		           for(int smallpY=0; smallerY<keyImgHeight; smallpY++) {
		               bigpY = y+smallpY;
		               for(int smallpX=0; smallpX<keyImgWidth; smallpX++) {
		                   bigpX = x+smallerX;
		                   if(biggerY>=scrShotImgHeight || bigpX>=scrShotImgWidth) {
		                       return false;
		                   }
		                   xor = keyImageRGBData[smallpY][smallpX]^screenShotImageRGBData[bigpY][bigpX];
		                   if(judeg!=0) {
		                       return false;
		                   }
		              }
		               bigpX = x;
		           }
		           return true;
		       }
 //查到圖片的中心位置並賦值給a,b
	  public void printFindData() {
		           for(int y=0; y<keyImgHeight/2; y++) {
		               for(int x=0; x<keyImgWidth/2; x++) {
		                  if(x==keyImgWidth/2-1&&y==keyImgHeight/2-1)
		                   a=this.findImgData[y][x][0];b=this.findImgData[y][x][1];
		               }
		           }
		       }

魂土功能部分代碼:
就是用循環嵌套一直重複
其他功能也是類似

     public static void Zhuntu(){
		  String keyImagePath0 = "image\\dingwei.png";
	      test demo0 = new test(keyImagePath0);
	      demo0.printFindData();
	    if (a!=0||b!=0) { 
	    	width=960;
	    	height=570;
	    	Robot robot0;
			try {
				robot0 = new Robot();
				robot0.delay(1000);
				robot0.mouseMove(b, a);
				robot0.delay(200);
				robot0.mousePress(InputEvent.BUTTON1_MASK);
				robot0.mouseMove(66, 10);
				robot0.delay(200);
				robot0.mouseRelease(InputEvent.BUTTON1_MASK);
				robot0.delay(2000);
			} catch (AWTException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			txtrtn.setForeground(Color.BLACK );
			txtrtn.append("\t\n");
			txtrtn.append("定位成功,即將開始");
			txtrtn.setCaretPosition(txtrtn.getText().length());  
	        while(true) {
	       m:
	          while(true) {
	        	    final double d = Math.random();
			        final int i = (int)(d*5);
			        final int t = (int)(d*200);
			        final int z = (int)(d*50);
			        final int w = (int)(d*120);    
	          try {  
	          String keyImagePath = "image\\biaoji11.png";
	          test demo = new test(keyImagePath);
	          demo.printFindData();
	          int dwbj_x=b;
	          int dwbj_y=a;
	          if (a!=0||b!=0) {
	        	txtrtn.append("\t\n");
	  			txtrtn.append("進入魂土");
	        	Robot robot2=new Robot();
				robot2.delay(100+t);
				robot2.mouseMove(dwbj_x-630+z, dwbj_y+395+z);
				robot2.delay(200+t);
				robot2.mousePress(InputEvent.BUTTON1_MASK);
				robot2.delay(100+t);
				robot2.mouseRelease(InputEvent.BUTTON1_MASK);

				txtrtn.append("\t\n");
				txtrtn.append("標記大舅媽");
				try {
					Thread.sleep(23000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			    while(true) { 
			          String keyImagePath2 = "image\\jieshu11.png";
			          test demo2 = new test(keyImagePath2);
			          demo2.printFindData();
			          if (a!=0||b!=0) {
							Robot robot1=new Robot();
							robot1.delay(500+t);
							robot1.mouseMove(680+w,400+w);
							robot1.delay(200+t);
							robot1.mousePress(InputEvent.BUTTON1_MASK);
							robot1.delay(200+t);
							robot1.mouseRelease(InputEvent.BUTTON1_MASK);
							
							robot1.delay(800+t);
							robot1.mouseMove(680+w,400+w);
							robot1.delay(200+t);
							robot1.mousePress(InputEvent.BUTTON1_MASK);
							robot1.delay(200+t);
							robot1.mouseRelease(InputEvent.BUTTON1_MASK);
							
							robot1.delay(800+t);
							robot1.mouseMove(680+w,400+w);
							robot1.delay(200+t);
							robot1.mousePress(InputEvent.BUTTON1_MASK);
							robot1.delay(200+t);
							robot1.mouseRelease(InputEvent.BUTTON1_MASK);
							
							robot1.delay(800+t);
							robot1.mouseMove(680+w,400+w);
							robot1.delay(200+t);
							robot1.mousePress(InputEvent.BUTTON1_MASK);
							robot1.delay(200+t);
							robot1.mouseRelease(InputEvent.BUTTON1_MASK);
							txtrtn.append("\t\n");
							txtrtn.append("歐氣滿滿,出貨!!!!");
							
						    break m; 
					                   }
			               }
                  }
			} catch (AWTException e) {
				e.printStackTrace();
			}
	         }
	     }  
	    }else {
    		txtrtn.setForeground(Color.red );
    		txtrtn.append("\t\n");
    		txtrtn.append("無法定位陰陽師界面,請確保陰陽師界面在可視範圍內");
    		txtrtn.append("\t\n");
    		txtrtn.append("請停止再次啓動");
    		exit_judge=false;
		}

  }

GUI 界面部分代碼:
 GUI界面我是用的WindowBuilder插件完成的,此插件提供了可視化的操作界面,能更好的佈局,大家若需要請自行查找
 在設置按鈕時間時一定要創建線程執行具體操作.因爲這些方法都是循環,並不會立即停止,若不建立線程則按鈕點擊後,界面會卡着不動.按鈕也無法點擊

	public test() {
		//
		setForeground(Color.BLACK);
		setBackground(Color.WHITE);
		setIconImage(Toolkit.getDefaultToolkit().getImage("C:\\Users\\Lenovo\\eclipse-workspace\\\u9634\u9633\u5E08\\D.png"));
		setTitle("\u79C3\u5934\u4FDD\u62A4");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(1100, 0, 425, 385);
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.setBackground(Color.WHITE);
		setJMenuBar(menuBar);
		
		JMenu mnNewMenu = new JMenu("");
		mnNewMenu.setIcon(new ImageIcon("image\\set.jpg"));
		mnNewMenu.setHorizontalAlignment(SwingConstants.CENTER);
		menuBar.add(mnNewMenu);
		
		JMenuItem ontopItem=new JMenuItem();
		ontopItem.setBackground(Color.LIGHT_GRAY);
		ontopItem.setIcon(null);
		ontopItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (ONTOP_judge==true) {
					ONTOP_judge=false;
					setAlwaysOnTop(ONTOP_judge);
				}else {
					ONTOP_judge=true;
					setAlwaysOnTop(ONTOP_judge);
				}
			}
		});
		ontopItem.setText("\u7F6E\u9876");
		ontopItem.setSelected(true);
		mnNewMenu.add(ontopItem);
		contentPane = new JPanel();
		contentPane.setBackground(Color.GRAY);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JButton btnNewButton = new JButton("\u6316\u571F(\u961F\u5458)");
		btnNewButton.setForeground(Color.LIGHT_GRAY);
		btnNewButton.setBackground(SystemColor.activeCaption);
		
		btnNewButton.setFocusPainted(false);
		btnNewButton.setContentAreaFilled(false);
		btnNewButton.setToolTipText("自動點大舅媽,位置二號位");
	
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new Thread() {
					public void run() {
						Zhuntu();
					}
				}.start();
			}
		});

		btnNewButton_7.setContentAreaFilled(false);
		btnNewButton_7.setFocusPainted(false);
		btnNewButton_7.setBounds(21, 183, 93, 32);
		contentPane.add(btnNewButton_7);
		
		JButton btnNewButton_6 = new JButton("\u75F4");
		btnNewButton_6.setForeground(Color.LIGHT_GRAY);
		btnNewButton_6.setContentAreaFilled(false);
		btnNewButton_6.setFocusPainted(false);
		btnNewButton_6.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				 new Thread() {
						public void run() {
								exit_judge=true;
                                cj();
                                System.out.println("開始");
						}
					}.start();
			}
		});

		JLabel lblNewLabel = new JLabel("New label");
		lblNewLabel.setIcon(new ImageIcon("image/preview.gif"));
		lblNewLabel.setBounds(0, 0, 410, 261);
		contentPane.add(lblNewLabel);
		
		JPanel panel = new JPanel();
		panel.setBounds(0, 260, 434, 86);
		contentPane.add(panel);
		panel.setLayout(null);
		
		JScrollPane scrollPane = new JScrollPane();
		txtrtn = new JTextArea();
		txtrtn.setEditable(false);
		txtrtn.setLineWrap(true);
		txtrtn.setText("\u795D\u4F60\u597D\u8FD0!-------\u9F20\u6807\u60AC\u6D6E\u6709\u63D0\u793A");
		txtrtn.setToolTipText("");
		txtrtn.setBounds(0, 0, 434, 86);
		panel.add(scrollPane);
		
		scrollPane.setBounds(0, 0, 409, 107);
		scrollPane.setViewportView(txtrtn);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		txtrtn.paintImmediately(txtrtn.getBounds());

	}
	

 代碼太多無法全部顯示,如有需要請聯繫作者

缺點

 此腳本使用時必須保證遊戲界面不被遮擋,並且會影響你的鼠標的其他操作.
 此腳本使用時遊戲分辨必須不能變,並且電腦不能設置125%所在縮放,只能100%
 內存佔用有點大,和運行一個陰陽師差不多了,我嘗試用System.gc()來清理內存但效果不理想,
 若大佬有方法或者新的思路或者意見可以私信或者評論留言

本人聯繫方式[email protected]

本人第一次寫,若有侵權請聯繫作者
只限於參考學習,持續更新中…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章