微信跳一跳小游戏辅助
微信跳一跳小游戏辅助
最近微信发布了新版本,加入了【小游戏功能】,同时官方提供了一个测试小游戏【跳一跳】。
跳一跳就是一个插画风格额游戏,玩家通过按住屏幕蓄力,然后小人会根据你蓄力的长短跳跃到前方。 而且官方还把分数跟朋友圈进行排名,导致朋友圈最近非常多人在跳跳跳。
不过这游戏需要你准确的把握好蓄力的时间,才能精准跳到对应的格子上。
观察这游戏的特点,其实可以通过计算距离来预估蓄力的时间。开搞!
大致原理
简单来说,就是利用了安卓手机可以直接通过 ADB 程序进行截图。然后截图传送到电脑上,电脑上去计算当前点跟目标点的距离,然后通过距离计算蓄力的时间来达到跳的准的目的。
流程如下:
- 安卓手机打开跳一跳程序,同时连接到电脑。
- 在 IDEA 中启动辅助程序。
- 程序会通过 ADB 命令对手机当前屏幕进行截图。
- 将截图传送到电脑,电脑上实时将图片渲染到电脑程序框里。
- 用户通过鼠标手动点击起始位置,然后再点击下一个目标。
- 程序计算出当前坐标跟下个目标之间的距离,根据手机屏幕大小等计算蓄力的事件。
- 通过 ADB 程序发送触摸屏幕指定坐标以及触摸时间给手机。
- 手机根据指令将小人跳到指定的目标。
需要掌握的技能
- 懂 Java 基本语法
- 了解一点 ADB 指令
- 了解一点 Java AWT 或者 Swing 界面编程概念
- 了解计算 2 个坐标点之间的距离 (即 开根号((x1 - x2)^2 + (y1 - y2)^2))
环境
- 操作系统: Ubuntu 16.04
- JDK: JDK 1.8
- IDE: IDEA 2017.1.3
- ADB 24.3.4
- 安卓手机
ADB 驱动安装
ADB 是一个安卓设备调试工具,全程是 Android Debug Bridge。 经常刷机或者玩软件逆向的应该很熟悉,这里就不说这么详细了。
根据你的操作系统使用不同的方式安装 ADB
- Ubuntu 下直接从仓库安装即可
sudo apt-get install -y android-tools-adb
# 如果仓库里没有的话添加下源
sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install -y android-tools-adb
- Windows 需要下载一个压缩包,然后将压缩包解压到你电脑本地,然后将解压的目录配置到环境变量 path 中。跟配置 JDK 环境变量类似的套路, ADB 就是一堆程序的集合。不过由于国内众所皆知的网络原因,是不能直接从谷歌官网下载,可以通过魔法进行下载或者直接在国内网上下载即可。
安装完成后,打开命令行输入:
adb version
如果出现 Android Debug Bridge version x.x.xxx
的字眼则说明环境变量配置成功。
连接设备
这里简单点直接通过数据线连接即可,连接后命令行输入:
adb devices
如果出现下面的字眼则说明检测成功:
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
xxxx device
直接执行下面的命令连接即可:
adb shell
编码
先编写几个基础的类。
首先编写坐标点对象:
package com.suny.weixin.jump;
/**
* 2018-2-5
*/
public class Point {
public int x;
public int y;
}
编写截图工具类:
/**
* 2018-2-5
*/
public class ScreenshotUtils {
public static void jump(int time) {
try {
out.println("自动跳到指定的坐标");
out.println("\n");
String command = String.format("adb shell input touchscreen swipe 170 187 170 187 %d", time);
Runtime.getRuntime().exec(command);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void captureScreenshot() {
try {
String screenshotCommand = "adb shell screencap -p /sdcard/jump.png";
String pullCommand = "adb pull /sdcard/jump.png /home/xxx/Downloads/jump.png";
Process screenshotProcess = Runtime.getRuntime().exec(screenshotCommand);
screenshotProcess.waitFor();
Process pullProcess = Runtime.getRuntime().exec(pullCommand);
out.println("【" + LocalTime.now() + "】刷新手机界面到PC");
pullProcess.waitFor();
} catch (Exception e) {
out.print("是否还没有连接手机");
}
}
}
创建一个面板:
package com.suny.weixin.jump;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
/**
* 2018-2-5
*/
public class PhonePanel extends JPanel{
private static final long serialVersionUID = 1L;
private static final String JUMP_PNG = "/home/xxx/Downloads/jump.png";
@Override
public void paint(Graphics g){
try {
ScreenshotUtils.captureScreenshot();
// 手机截屏的路径自己根据实际的调整
Image image = ImageIO.read(new File(JUMP_PNG));
// 图像展示大小需要自己设定,这里用的我手机的,根据各自的手机屏幕大小调整
g.drawImage(image, 0, 0, 540, 960, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
首先先编写一个 Java 界面主程序:
package com.suny.weixin.jump;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import static java.lang.System.out;
/**
* 2018-2-5
*/
public class WeixinJumpGameFrame extends JFrame {
// 显示手机屏幕图像的面板
private PhonePanel phoneImgPanel = null;
// 否为第一次点击
private boolean isFirst = true;
// 上一次点击的点的坐标
private final transient Point prePoint = new Point();
// 当前点击的点的坐标
private final transient Point curPoint = new Point();
private StartGame() {
// 创建手机屏幕图像面板
phoneImgPanel = new PhonePanel();
this.add(phoneImgPanel);
// 窗口的大小为540x960像素,这里需要根据你的手机大小调整
this.setSize(540, 960);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setVisible(true);
this.setTitle("跳一跳辅助");
phoneImgPanel.addMouseListener(new MouseListener() {
@Override
public void mousePressed(MouseEvent event) {
// 如果是第一次点击
if (isFirst) {
// 记录点击的坐标为起跳点坐标
prePoint.x = event.getX();
prePoint.y = event.getY();
// false表示已经记录了起跳点
isFirst = false;
// 输出当前小球的坐标
out.println("当前小球坐标是【" + prePoint.x + "," + prePoint.y + "】");
return;
}
// 如果不是第一次点击,记录点击的坐标为目标站台坐标
curPoint.x = event.getX();
curPoint.y = event.getY();
// 输出目标站台的坐标
out.println("目标站台坐标是【" + curPoint.x + "," + curPoint.y + "】");
// 计算起跳点和目标站台之间的距离
final int distance = calDistance(prePoint, curPoint);
// 根据距离计算跳跃的时间,这里使用了一个固定的比例系数0.37,记得改,大手机小手机会有差异
final int time = (int) (distance / 0.37);
// 执行跳跃操作
ScreenshotUtils.jump(time);
// 等待3秒让手机屏幕更新
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 刷新图像面板,获取最新的手机屏幕图像
isFirst = true;
phoneImgPanel.validate();
phoneImgPanel.repaint();
}
@Override
public void mouseReleased(MouseEvent event) {
}
@Override
public void mouseExited(MouseEvent event) {
}
@Override
public void mouseEntered(MouseEvent event) {
}
@Override
public void mouseClicked(MouseEvent event) {
}
});
}
private static int calDistance(Point p1, Point p2) {
int dx = p1.x - p2.x;
int dy = p1.y - p2.y;
int distance = (int) Math.sqrt(dx * dx + dy * dy);
out.println("两点间距离为" + distance);
return distance;
}
public static void main(String[] args) {
// 输出程序开始的提示信息
out.println("==========跳一跳辅助开始==============");
out.println("\n");
out.println("\n");
out.print("当前机型【小米MAX2】,分辨率【1920 x 1080】");
new StartGame();
}
}
测试
- 打开手机的跳一跳游戏界面。
- 使用 USB 线或者是远程 ADB 连上手机。
- 启动 IDEA 上的程序。
- 鼠标先点击起始位置一下。
- 再用鼠标点击下一个目标站台,可以看到小人会准确跳过去。
注意事项
- 每个人手机屏幕大小不一样,需要多调试几次。
- 官方检测还是挺严格的,注意别刷太多分,毕竟游戏还是以娱乐为主。