**
用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,bpublic 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 blocke.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()来清理内存但效果不理想,
若大佬有方法或者新的思路或者意见可以私信或者评论留言
本人联系方式793665938@qq.com
本人第一次写,若有侵权请联系作者
只限于参考学习,持续更新中……