工具:ADB

原理:

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

程序代码:

 import java.awt.EventQueue;
import java.awt.Graphics; import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color; import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal; public class Skip {
/*
* 以下参数根据手机配置自行调整:
*/
private final int time = 2800; //执行跳跃间隔时间(单位:ms)
private final double scale = 2.04; //用于计算按下屏幕时间的比例,触屏时间=距离*scale private JFrame frame; //窗体
private JLabel lblNewLabel; //用于显示图片的Label
private BufferedImage image; //手机截屏
private int skipTime = 0; //跳跃次数
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Skip window = new Skip(); //跳一跳类实例
window.frame.setVisible(true); //设置窗体可见
} catch (Exception e) {
e.printStackTrace();
}
}
});
} /**
* Create the application.
*/
public Skip() {
initialize(); //初始化
} /**
* Initialize the contents of the frame.
*/
private void initialize() {
image = Control.getScreen(); //截取第一个图片
Control.getFoot(image); //寻找计算小人位置
Control.getTarget(image); //寻找目标中心
ImageIcon imageIcon = new ImageIcon(image); //以截图创建一个ImageIcon对象,供标签使用 frame = new JFrame(); //创建一个窗体
frame.setBounds(100, 0, imageIcon.getIconWidth(), imageIcon.getIconHeight()); //设置窗体大小位置
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗体时结束进程 lblNewLabel = new JLabel("手机屏幕"); //创建标签
//给标签添加单机时间:单机后开始自动跳跃
lblNewLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Thread skip = new Thread(new SkipRun());
skip.start();
}
});
lblNewLabel.setIcon(imageIcon); //设置标签图片
frame.getContentPane().add(lblNewLabel, BorderLayout.CENTER); //添加标签到窗体中
} //单步跳跃
protected void skip() {
double distance = Control.getDistance(image); //计算距离
Control.mouseon(Integer.parseInt(new BigDecimal(String.valueOf(distance * scale)).setScale(0, BigDecimal.ROUND_HALF_UP).toString())); //模拟触屏
try {
//记录本次图片
ImageIO.write(image, "png", new File("debug" + skipTime++ + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
} //自动跳跃主线程
class SkipRun implements Runnable{ @Override
public void run() {
//循环跳跃
while(true) {
skip();
try {
//小人跳跃需要花一定时间,在此等待3秒
Thread.sleep(time);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//将当前手机屏幕显示在窗体中
image = Control.getScreen();
lblNewLabel.setIcon(new ImageIcon(image));
}
} } } /**
* 工具类,负责发送ADB命令、计算小人与目标距离
*/
class Control {
private static int footX = 0, footY = 0; //小人底部坐标
private static int targetX = 0,targetY = 0; //目标方块中心坐标
//获取截屏
public static BufferedImage getScreen(){
//截屏
try {
//手机截屏,存储到SD卡
Process process = Runtime.getRuntime().exec("adb shell screencap /sdcard/screen.png");
process.waitFor();
//将截图传到电脑,以便接下来的分析
process = Runtime.getRuntime().exec("adb pull /sdcard/screen.png screen.png");
process.waitFor();
} catch (IOException | InterruptedException e) {
//异常处理
e.printStackTrace();
}
//加载文件
File file = new File("screen.png");
if (file == null || !file.exists()) {
System.out.println("获取截屏失败");
return null;
} //加载图片
BufferedImage image = null;
try {
image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
return image;
} //长按屏幕
public static void mouseon(int time) {
try {
Runtime.getRuntime().exec("adb shell input swipe 200 200 200 200 " + time);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} //计算距离
public static double getDistance (BufferedImage image) {
getFoot(image); //获取小人坐标
getTarget(image); //获取目标坐标
return Math.sqrt((footX - targetX) * (footX - targetX) + (footY - targetY) * (footY - targetY));
} public static void getFoot(BufferedImage image){ Color footColor = new Color(54,60,102); //小人底部颜色
int top = (int)(image.getHeight() * 0.5); //扫描范围顶部(X)
int bottom = (int) (image.getHeight() * 0.7); //扫描范围底部(X)
/*
* 自底向上扫描小人脚下位置
*/
for(int i = bottom;i > top;i--)
{
for(int j = 0;j < image.getWidth();j++)
{
//如果当前颜色与小人脚部颜色相近
if(Math.abs(image.getRGB(j, i) - footColor.getRGB()) < 200) {
footX = j;
footY = i - 10; //自左向右扫描,原始结果会偏左,在此稍向右移
i = top; //结束外层循环
break;
}
}
}
/*
* 用蓝色方块标记找到的小人位置
*/
Graphics g = image.getGraphics();
g.setColor(Color.BLUE);
g.fillRect(footX - 5, footY - 5, 10, 10);
} public static void getTarget(BufferedImage image) { /*
* 第一步,找到目标方块上端顶点,该顶点的X坐标即中心的X坐标
*/ int top = (int)(image.getHeight() * 0.35); //扫描范围顶部
int bottom = (int)(image.getHeight() * 0.49); //扫描范围底部
Color headColor = new Color(56, 54, 71);
/*
* 自顶向下扫描目标方块顶端位置
*/
for(int i = top;i < bottom;i++)
{
Color bgColor = new Color(image.getRGB(10, i)); //取背景色
for(int j = 0;j < image.getWidth();j++)
{
/*
* 小人可能高于目标方块,为排除干扰,略过小人所在的纵坐标(列)
*/
if (j >= footX - 30 && j <= footX + 30) {
continue;
}
Color color = new Color(image.getRGB(j, i)); //取当前颜色
int t = 0;
t = Math.abs(bgColor.getRGB() - color.getRGB()); //计算色差 if (t > 200000){ //如果与背景色不同
targetX = j; //记录行坐标
targetY = i; //记录纵坐标
i = bottom; //结束外层循环
break; //结束内层循环
}
}
} /*
* 第二步,从顶点开始,向下扫描,找到方块占据最多列的那一行,即为目标的Y坐标
*/ int maxLength; //方块的直径
int x = targetX; //行扫描起始坐标
int y = targetY; //直径所在行(y坐标) /*
* 如果在下面多行,该方块占据的列都相同,说明本行是中心所在行,
* 即Y坐标就是本行。使用flag记录连续相同的行数
*/ int flag = 0; //不满足条件标志
for(int i = y + 1;i < y + 101 && flag < 8;i++) //当连续8行直径相同后,结束循环
{
for(int j = x;j < image.getWidth();j++)
{
Color bgColor = new Color(image.getRGB(image.getWidth() - 10, i)); //取背景色
Color color = new Color(image.getRGB(j, i)); //取当前颜色
if (( Math.abs(bgColor.getRGB() - color.getRGB())) <= 703400) { //如果与背景色颜色相近
if (j > x) { //当前x坐标大于之前的x,(说明方块在本行占据的列更多)
x = j; //当前x坐标赋值给x
targetY = i; //直径所在行替换为当前y
flag = 0;
}else { //当前x坐标不大于之前的x,(说明方块在本行占据的列不是最多)
flag++; //此标志+1
}
break;
}
}
}
targetY = targetY - flag; //减去多加的flag /*至此,targetX与targetY寻找完毕*/
/*
* 用红色方块记录目标点
*/
Graphics g = image.getGraphics();
g.setColor(Color.RED);
g.fillRect(targetX - 5, targetY - 5, 10, 10);
}
}

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

微信跳一跳辅助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. Redis04——Redis五大数据类型 key

    key  keys *  查看当前库的所有键  exists <key>  判断某个键是否存在  type <key>   查看键的类型  del<key>  删除 ...

  2. IntelliJ IDEA 2017.3尚硅谷-----设置界面

  3. lamp与zabbix开机自启

    目录 1.控制httpd脚本 2.控制zabbix_server脚本 3.控制zabbix_agentd脚本 4.服务端lamp开机自动启动 5.客户端zabbix_agentd开机自动启动 1.控制 ...

  4. 路飞-后台Django项目创建

    后台:Django项目创建 环境 """ 为luffy项目创建一个虚拟环境 >: mkvirtualenv luffy """ &qu ...

  5. 远程操作Linux主机

    通过putty文件访问: 下载路径:https://the.earth.li/~sgtatham/putty/0.70/w32/putty-0.70-installer.msi 通过Python文件执 ...

  6. new一个对象做了哪些操作

    网上其实有很多说new关键字做了哪些操作,读过之后就忘了,这里以自己的理解做一个简单的记录. function Naji () { this.skulk = function () { return ...

  7. Linux - bash - 小坑: IFS

    1. 概述 for 循环读取文件内容时, 输出被打得稀碎 2. 场景 需求 读入文件 逐行显示 源文件 Continuous Delivery with Docker and Jenkins Jenk ...

  8. CSS学习(1)简介

    什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与 ...

  9. mybatis - 执行 getById

    1. getById 的执行 前面一篇 提到过, Mapper.java 创建的时候, 会通过 jdk 代理的方式来创建, 且代理处理类为: MapperProxy . 所以当执行 UserMappe ...

  10. Python - 用python实现split函数

    # pattern支持字符或者字符串 def my_split(string, pattern): ret = [] len_pattern = len(pattern) while True: in ...