工具:ADB

原理:

  1. 开始游戏后,使用ADB工具让手机截屏发送到电脑
  2. 分析图像中小人与目标中心点间的距离,根据一定比例计算出需要触屏的时间
  3. 使用ADB进行模拟点击(触屏)相应的时间,完成精准跳跃

程序代码:

  1. import java.awt.EventQueue;
  2. import java.awt.Graphics;
  3.  
  4. import javax.swing.JFrame;
  5. import javax.swing.JLabel;
  6. import java.awt.BorderLayout;
  7. import java.awt.Color;
  8.  
  9. import javax.imageio.ImageIO;
  10. import javax.swing.ImageIcon;
  11. import java.awt.event.MouseAdapter;
  12. import java.awt.event.MouseEvent;
  13. import java.awt.image.BufferedImage;
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.math.BigDecimal;
  17.  
  18. public class Skip {
  19. /*
  20. * 以下参数根据手机配置自行调整:
  21. */
  22. private final int time = 2800; //执行跳跃间隔时间(单位:ms)
  23. private final double scale = 2.04; //用于计算按下屏幕时间的比例,触屏时间=距离*scale
  24.  
  25. private JFrame frame; //窗体
  26. private JLabel lblNewLabel; //用于显示图片的Label
  27. private BufferedImage image; //手机截屏
  28. private int skipTime = 0; //跳跃次数
  29. /**
  30. * Launch the application.
  31. */
  32. public static void main(String[] args) {
  33. EventQueue.invokeLater(new Runnable() {
  34. public void run() {
  35. try {
  36. Skip window = new Skip(); //跳一跳类实例
  37. window.frame.setVisible(true); //设置窗体可见
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. });
  43. }
  44.  
  45. /**
  46. * Create the application.
  47. */
  48. public Skip() {
  49. initialize(); //初始化
  50. }
  51.  
  52. /**
  53. * Initialize the contents of the frame.
  54. */
  55. private void initialize() {
  56. image = Control.getScreen(); //截取第一个图片
  57. Control.getFoot(image); //寻找计算小人位置
  58. Control.getTarget(image); //寻找目标中心
  59. ImageIcon imageIcon = new ImageIcon(image); //以截图创建一个ImageIcon对象,供标签使用
  60.  
  61. frame = new JFrame(); //创建一个窗体
  62. frame.setBounds(100, 0, imageIcon.getIconWidth(), imageIcon.getIconHeight()); //设置窗体大小位置
  63. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗体时结束进程
  64.  
  65. lblNewLabel = new JLabel("手机屏幕"); //创建标签
  66. //给标签添加单机时间:单机后开始自动跳跃
  67. lblNewLabel.addMouseListener(new MouseAdapter() {
  68. @Override
  69. public void mouseClicked(MouseEvent e) {
  70. Thread skip = new Thread(new SkipRun());
  71. skip.start();
  72. }
  73. });
  74. lblNewLabel.setIcon(imageIcon); //设置标签图片
  75. frame.getContentPane().add(lblNewLabel, BorderLayout.CENTER); //添加标签到窗体中
  76. }
  77.  
  78. //单步跳跃
  79. protected void skip() {
  80. double distance = Control.getDistance(image); //计算距离
  81. Control.mouseon(Integer.parseInt(new BigDecimal(String.valueOf(distance * scale)).setScale(0, BigDecimal.ROUND_HALF_UP).toString())); //模拟触屏
  82. try {
  83. //记录本次图片
  84. ImageIO.write(image, "png", new File("debug" + skipTime++ + ".png"));
  85. } catch (IOException e) {
  86. e.printStackTrace();
  87. }
  88. }
  89.  
  90. //自动跳跃主线程
  91. class SkipRun implements Runnable{
  92.  
  93. @Override
  94. public void run() {
  95. //循环跳跃
  96. while(true) {
  97. skip();
  98. try {
  99. //小人跳跃需要花一定时间,在此等待3秒
  100. Thread.sleep(time);
  101. } catch (InterruptedException e1) {
  102. e1.printStackTrace();
  103. }
  104. //将当前手机屏幕显示在窗体中
  105. image = Control.getScreen();
  106. lblNewLabel.setIcon(new ImageIcon(image));
  107. }
  108. }
  109.  
  110. }
  111.  
  112. }
  113.  
  114. /**
  115. * 工具类,负责发送ADB命令、计算小人与目标距离
  116. */
  117. class Control {
  118. private static int footX = 0, footY = 0; //小人底部坐标
  119. private static int targetX = 0,targetY = 0; //目标方块中心坐标
  120. //获取截屏
  121. public static BufferedImage getScreen(){
  122. //截屏
  123. try {
  124. //手机截屏,存储到SD卡
  125. Process process = Runtime.getRuntime().exec("adb shell screencap /sdcard/screen.png");
  126. process.waitFor();
  127. //将截图传到电脑,以便接下来的分析
  128. process = Runtime.getRuntime().exec("adb pull /sdcard/screen.png screen.png");
  129. process.waitFor();
  130. } catch (IOException | InterruptedException e) {
  131. //异常处理
  132. e.printStackTrace();
  133. }
  134. //加载文件
  135. File file = new File("screen.png");
  136. if (file == null || !file.exists()) {
  137. System.out.println("获取截屏失败");
  138. return null;
  139. }
  140.  
  141. //加载图片
  142. BufferedImage image = null;
  143. try {
  144. image = ImageIO.read(file);
  145. } catch (IOException e) {
  146. e.printStackTrace();
  147. }
  148. return image;
  149. }
  150.  
  151. //长按屏幕
  152. public static void mouseon(int time) {
  153. try {
  154. Runtime.getRuntime().exec("adb shell input swipe 200 200 200 200 " + time);
  155. } catch (IOException e) {
  156. // TODO Auto-generated catch block
  157. e.printStackTrace();
  158. }
  159. }
  160.  
  161. //计算距离
  162. public static double getDistance (BufferedImage image) {
  163. getFoot(image); //获取小人坐标
  164. getTarget(image); //获取目标坐标
  165. return Math.sqrt((footX - targetX) * (footX - targetX) + (footY - targetY) * (footY - targetY));
  166. }
  167.  
  168. public static void getFoot(BufferedImage image){
  169.  
  170. Color footColor = new Color(54,60,102); //小人底部颜色
  171. int top = (int)(image.getHeight() * 0.5); //扫描范围顶部(X)
  172. int bottom = (int) (image.getHeight() * 0.7); //扫描范围底部(X)
  173. /*
  174. * 自底向上扫描小人脚下位置
  175. */
  176. for(int i = bottom;i > top;i--)
  177. {
  178. for(int j = 0;j < image.getWidth();j++)
  179. {
  180. //如果当前颜色与小人脚部颜色相近
  181. if(Math.abs(image.getRGB(j, i) - footColor.getRGB()) < 200) {
  182. footX = j;
  183. footY = i - 10; //自左向右扫描,原始结果会偏左,在此稍向右移
  184. i = top; //结束外层循环
  185. break;
  186. }
  187. }
  188. }
  189. /*
  190. * 用蓝色方块标记找到的小人位置
  191. */
  192. Graphics g = image.getGraphics();
  193. g.setColor(Color.BLUE);
  194. g.fillRect(footX - 5, footY - 5, 10, 10);
  195. }
  196.  
  197. public static void getTarget(BufferedImage image) {
  198.  
  199. /*
  200. * 第一步,找到目标方块上端顶点,该顶点的X坐标即中心的X坐标
  201. */
  202.  
  203. int top = (int)(image.getHeight() * 0.35); //扫描范围顶部
  204. int bottom = (int)(image.getHeight() * 0.49); //扫描范围底部
  205. Color headColor = new Color(56, 54, 71);
  206. /*
  207. * 自顶向下扫描目标方块顶端位置
  208. */
  209. for(int i = top;i < bottom;i++)
  210. {
  211. Color bgColor = new Color(image.getRGB(10, i)); //取背景色
  212. for(int j = 0;j < image.getWidth();j++)
  213. {
  214. /*
  215. * 小人可能高于目标方块,为排除干扰,略过小人所在的纵坐标(列)
  216. */
  217. if (j >= footX - 30 && j <= footX + 30) {
  218. continue;
  219. }
  220. Color color = new Color(image.getRGB(j, i)); //取当前颜色
  221. int t = 0;
  222. t = Math.abs(bgColor.getRGB() - color.getRGB()); //计算色差
  223.  
  224. if (t > 200000){ //如果与背景色不同
  225. targetX = j; //记录行坐标
  226. targetY = i; //记录纵坐标
  227. i = bottom; //结束外层循环
  228. break; //结束内层循环
  229. }
  230. }
  231. }
  232.  
  233. /*
  234. * 第二步,从顶点开始,向下扫描,找到方块占据最多列的那一行,即为目标的Y坐标
  235. */
  236.  
  237. int maxLength; //方块的直径
  238. int x = targetX; //行扫描起始坐标
  239. int y = targetY; //直径所在行(y坐标)
  240.  
  241. /*
  242. * 如果在下面多行,该方块占据的列都相同,说明本行是中心所在行,
  243. * 即Y坐标就是本行。使用flag记录连续相同的行数
  244. */
  245.  
  246. int flag = 0; //不满足条件标志
  247. for(int i = y + 1;i < y + 101 && flag < 8;i++) //当连续8行直径相同后,结束循环
  248. {
  249. for(int j = x;j < image.getWidth();j++)
  250. {
  251. Color bgColor = new Color(image.getRGB(image.getWidth() - 10, i)); //取背景色
  252. Color color = new Color(image.getRGB(j, i)); //取当前颜色
  253. if (( Math.abs(bgColor.getRGB() - color.getRGB())) <= 703400) { //如果与背景色颜色相近
  254. if (j > x) { //当前x坐标大于之前的x,(说明方块在本行占据的列更多)
  255. x = j; //当前x坐标赋值给x
  256. targetY = i; //直径所在行替换为当前y
  257. flag = 0;
  258. }else { //当前x坐标不大于之前的x,(说明方块在本行占据的列不是最多)
  259. flag++; //此标志+1
  260. }
  261. break;
  262. }
  263. }
  264. }
  265. targetY = targetY - flag; //减去多加的flag
  266.  
  267. /*至此,targetX与targetY寻找完毕*/
  268. /*
  269. * 用红色方块记录目标点
  270. */
  271. Graphics g = image.getGraphics();
  272. g.setColor(Color.RED);
  273. g.fillRect(targetX - 5, targetY - 5, 10, 10);
  274. }
  275. }

---恢复内容结束---

微信跳一跳辅助JAVA 自动模拟点击的更多相关文章

  1. 微信跳一跳辅助自动跳Python

    一.说明 此代码借鉴github一位大神所写,已经做了简化合并处理,如果能成功连上手机并运行,可以实现程序自动玩游戏,刷个1000+的分数轻轻松松 github源码地址 https://github. ...

  2. 微信跳一跳辅助Demo

    [原创] 前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗 就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个 ...

  3. 37.微信跳一跳辅助开发(C语言+EasyX)

    一.开发环境 开发环境 使用语言:C/C++ IDE:VS2010+ 其他三方库 EasyX(http://www.easyx.cn/downloads/) ADB(链接:https://pan.ba ...

  4. Android远程桌面助手扩展之微信跳一跳辅助

    微信跳一跳的外挂辅助已是五花八门,万能的TB上也有了各种明码标价的代练.微信小程序游戏的火爆甚至带火了手游外挂产业.另一方面,跳一跳游戏也在不断更新,防止使用外挂刷高分.Android远程桌面助手支持 ...

  5. python 微信跳一跳辅助 复现

    本来用的是苹果ios得手机,但是步骤较为复杂,没有吃透,最后妥协用了android的机器搞得. 首先找到大牛的github https://github.com/wangshub/wechat_jum ...

  6. .NET开发一个微信跳一跳辅助程序

    昨天微信更新了,出现了一个小游戏"跳一跳",玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来 ...

  7. Python实现一个简单的微信跳一跳辅助

    1.  前言 微信的跳一跳相信大家都很熟悉了,而且现在各种外挂.辅助也是满天飞,反正本人的好友排行榜中已经是八九百都不足为奇了.某宝上一搜一堆结果,最低的居然只要3块多,想刷多少分就刷多少分,真是离谱 ...

  8. 【learning】微信跳一跳辅助c++详解 轻松上万 【上】

    写在前面 17年年底Wechat出了这个跳一跳的小游戏,今年2月份的时候简单地玩了一下,发现被游戏虐了(手太残了只能跳20多).     今天刚好有点空,于是就花了一个下午的时间写了一个跳一跳的c++ ...

  9. 【learning】微信跳一跳辅助c++详解 轻松上万 【下】

    如果你还没有看完本blog的上篇,建议您先看完上篇!! 第一代辅助如何死的? 我们先来看四张图      如上方最左图所示,前面是一个小圆柱子,看起来很人畜无害似不似?? 由于上一步跳出了偏差,并没有 ...

随机推荐

  1. Redis05——Redis五大数据类型 String

    String String是Redis最基本的数据类型(较常用),一个key对应一个value string类型是二进制安全的,Redis的string可以包含任何数据 一个Redis中字符串valu ...

  2. 第十一篇 深入Python的dict和set(二)

  3. ACM的探索之Everything Is Generated In Equal Probability(这真的是很有趣的话语丫!)

    ---------------------------------------步履不停,奋勇前进! ------------------------难度真的是蛮大丫!后序补充!

  4. ARM64架构下面安装mysql5.7.22

    MySQL下载地址为: https://obs.cn-north-4.myhuaweicloud.com/obs-mirror-ftp4/database/mysql-5.7.27-aarch64.t ...

  5. logging basic

    logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等. 相比print,具备如下优点:        可以通过设置不同的日志等级, ...

  6. redis持久化2

    编程迷思 博客园 首页 联系 订阅 管理 随笔 - 11  文章 - 0  评论 - 318 深入学习Redis(2):持久化 前言 在上一篇文章中,介绍了Redis的内存模型,从这篇文章开始,将依次 ...

  7. opencv:图像查找表 与 颜色表

    LUT 使用 颜色查找表 example LUT applyColorMap // 读入制作好的lut.png Mat color = imread("D:/images/lut.png&q ...

  8. opencv:绘制图像直方图

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  9. Raid 10配置流程(五块磁盘)

    Raid 10配置流程(五块磁盘) 1.在虚拟机中再添加5块硬盘.  2.使用mdadm命令创建raid10,名称为“/dev/md0” -C代表创建操作,-v显示创建过程,-a yes检查RAID名 ...

  10. HDU4081 Qin Shi Huang's National Road System

    先求最小生成树 再遍历每一对顶点,如果该顶点之间的边属于最小生成树,则剪掉这对顶点在最小生成树里的最长路径 否则直接剪掉连接这对顶点的边~ 用prim算法求最小生成树最长路径的模板~ #include ...