补发30日未发的博客。
PS:最新改进的算法和针对我自己手机调优的参数已经停不下来了,见项目:https://github.com/GameTerminator/AutoJump

几年前参考网上的文章写过天天连萌自动玩的项目(之前写在 iteye 的博客上:http://maosidiaoxian.iteye.com,github 项目地址为:https://github.com/GameTerminator/lianmeng),这次微信小游戏里的跳一跳玩了玩,就自然而然地想到用同样的方式来做。

经过几次修正和简化,最终思路和实现如下:

  1. 使用 monkeyrunner 里的接口截图
  2. 找出跳动的那个小球的 x 坐标
  3. 找出最终要跳达的点的 x 坐标
  4. 算出其距离,并按线性方程计算出时间
  5. 使用 monkeyrunner 里的接口模拟长按事件

接下来是完整的 Java 代码实现过程。

截图及模拟长按

要调用 monkeyrunner 来截图及模拟长按,我们需要 sdk 里的几个 jar 包,它们分别是(以下版本省略为*):

  • chimpchat-*.jar
  • common-*.jar
  • ddmlib-*.jar
  • guava-*.jar

以上这些 jar 包在 sdk 中的 tools/lib/ 中可以找到。然后我们使用其 API 来实现 ADB 连接,截图,长按。代码如下:

package com.githang.autojump;import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;import java.awt.image.BufferedImage;/*** @author 黄浩杭 (huanghaohang@parkingwang.com)*/
public class AdbHelper {private final AdbBackend mAdbBackend = new AdbBackend();private IChimpDevice mChimpDevice;public void waitForConnection() {mChimpDevice = mAdbBackend.waitForConnection();}public void disconnect() {mChimpDevice.dispose();}/*** 截图*/public BufferedImage snapshot() {IChimpImage img;// 当尝试次数太多时不再尝试。int tryTimes = 0;do {System.out.println("截图中.." + tryTimes);img = mChimpDevice.takeSnapshot();tryTimes++;} while (img == null && tryTimes < 15);if (img == null) {throw new RuntimeException("try to much times to take snapshot but failed");}return img.getBufferedImage();}/*** 长按* @param x x坐标* @param y y坐标* @param ms 长按时间,单位毫秒*/public void press(int x, int y, int ms) {mChimpDevice.drag(x, y, x, y, 1, ms);}
}

上面的代码中,由于 IChimpDevice 没有直接提供长按的接口,这里使用的是拖拽方法。

找到起始位置

接下来是要找到跳跃的起始位置。这里我们简化一下,允许存在一些误差,找到小球的中心的 x 坐标,和目的点的 x 坐标即可。
由于在每一步中小球都不会有变化,并且在小球上面不会有其他色块与小球颜色接近,所以我想到的找到小球中心的 x 坐标的思路如下:
先获取小球的一部分图像,然后截图整个界面,由上至下遍历,找到与小球颜色接近的那块区域,其中心点就是小球的中心点。
截图小球的方式有多种,比如用 PS 抠图,或 QQ 截图,代码也可以,方式如下:
先截取游戏时的界面,然后用 PxCook 测量出小球的位置。我手机屏幕为720 * 1280,截取的是小球中间的 24 * 24的一块区域,代码如下:

    private static void clipTarget() throws IOException {BufferedImage image = ImageIO.read(new File("screen.png"));BufferedImage target = new BufferedImage(24, 24, BufferedImage.TYPE_INT_ARGB);for (int i = 0; i < 24; i++) {for (int j = 0; j < 24; j++) {target.setRGB(i, j, image.getRGB(212 + i, 620 + j));}}ImageIO.write(target, "png", new File("target.png"));}

上面的 212620 是在 PxCook 中测量出来的数值。

然后就是找出每一步小球所在的位置。思路也很简单,逐行往下遍历,如果某个像素点的颜色与刚才所获取的小球区域的颜色相近,则遍历这个点为起始点的[x,y][x+23, y+23]矩形区域,如果每个像素点都接近,则表示这块区域就是小球,否则则继续遍历。判断颜色相近,我想到的是其 R G B 相差均小于10。最终找到小球的代码如下:

    private static boolean isJumpFrom(BufferedImage source, BufferedImage target, int x, int y) {for (int i = 0, width = target.getWidth(); i < width; i++) {for (int j = 0, height = target.getHeight(); j < height; j++) {int colorValue = target.getRGB(i, j);if (colorValue == 0) {continue;}int tempX = x + i;int tempY = y + j;Color targetColor = new Color(colorValue);Color sourceColor = new Color(source.getRGB(tempX, tempY));if (Math.abs(targetColor.getRed() - sourceColor.getRed()) > 10|| Math.abs(targetColor.getGreen() - sourceColor.getGreen()) > 10|| Math.abs(targetColor.getBlue() - sourceColor.getBlue()) > 10) {return false;}}}return true;}

从上往下逐行进行遍历,代码如下:

int width;
int height;
BufferedImage target = ImageIO.read(new File("target.png"));
int bWidth = target.getWidth();
int bHeight = target.getHeight();
while (true) {BufferedImage image = helper.snapshot();width = image.getWidth();height = image.getHeight();LOG.info("查找位置");int toX = findToX(width, height, image);FINDING:for (int y = height * 2 / 5, endY = height * 4 / 5; y < endY; y++) {for (int x = 0, endX = width - bWidth; x < endX; x++) {if (isJumpFrom(image, target, x, y)) {final int targetX = x + bWidth / 2;final int targetY = y + bHeight / 2;LOG.info("找到位置: " + targetX + ", " + targetY);final int distance = Math.abs(toX - targetX);final int time;// TODO 计算出时间helper.press(targetX, targetY, time);Thread.sleep(time);break FINDING;}}}
}

找出跳跃终点

在上面的代码中,有个 findToX(width, height, image) 方法的调用,它就是用于找出跳跃的终点坐标。它的原理也很简单。
由于在游戏中,背影是纯色渐变的,而要到达的区域,它的顶面颜色与背影色相差较大,并且不是椭圆就是菱形,它的特点是在这个平面上,中心点与顶点的 x 坐标相同。所以只要在显示分数的下面,从上往下每一行进行遍历,找到有一点与上面那一行的点颜色相差较大,这个点的 x 坐标就是要跳过去的点的 x 坐标了。代码如下:

    private static int findToX(int width, int height, BufferedImage image) {for (int y = height / 5, endY =  height / 2; y < endY; y++) {Color background = new Color(image.getRGB(2, y - 1));for ( int x = 0; x < width; x++) {Color color = new Color(image.getRGB(x, y));if (Math.abs(color.getRed() - background.getRed()) > 10|| Math.abs(color.getGreen() - background.getGreen()) > 10|| Math.abs(color.getBlue() - background.getBlue()) > 10) {LOG.info("跳到:" + x + ", " + y);return x;}}}throw new RuntimeException("ToX not found!");}

最终代码

最后是写一个大循环,每一步里面截图,找到要终点 x 坐标,找到小球中心,算出距离,再换算成时间,发送模拟按下事件,然后暂停按下的时间,再暂停 2 秒。这里暂停 2 秒的原因是,有些场景,停留 2 秒以上会有加分。最终 main 方法代码如下:

    public static void main(String[] args) throws InterruptedException, IOException {AdbHelper helper = new AdbHelper();helper.waitForConnection();int width;int height;BufferedImage target = ImageIO.read(new File("target.png"));int bWidth = target.getWidth();int bHeight = target.getHeight();while (true) {BufferedImage image = helper.snapshot();width = image.getWidth();height = image.getHeight();LOG.info("查找位置");int toX = findToX(width, height, image);FINDING:for (int y = height * 2 / 5, endY = height * 4 / 5; y < endY; y++) {for (int x = 0, endX = width - bWidth; x < endX; x++) {if (isJumpFrom(image, target, x, y)) {final int targetX = x + bWidth / 2;final int targetY = y + bHeight / 2;LOG.info("找到位置: " + targetX + ", " + targetY);final int distance = Math.abs(toX - targetX);final int time;time = Math.max(330, (int) (distance * 2.38f));LOG.info("距离:" + distance + "  按下时间:" + time + "ms");helper.press(targetX, targetY, time);Thread.sleep(time);break FINDING;}}}Thread.sleep(2000);}}

其中由距离计算出时间的公式可以自己再进行调优。目前我的公式基本都能拿三四百分以上,最高是 800 多分。

项目完整代码,请参见 Github 项目:https://github.com/GameTerminator/AutoJump。Idea Gradle 项目。
其他相关项目:

  • 天天连萌自动玩:https://github.com/GameTerminator/lianmeng
  • 别踩白块儿暴力玩法:https://github.com/GameTerminator/dont-touch-white

排行榜:

在朋友里刷个第一名还是挺简单的。

跳一跳——电脑能做的事就不要人工来做啦相关推荐

  1. opencv在电脑屏幕上画_用Python+OpenCV让电脑帮你玩微信跳一跳

    前言 最近微信小游戏跳一跳大热,自己也是中毒颇久,无奈手残最高分只拿到200分.无意间看到教你用Python来玩微信跳一跳一文,在电脑上利用adb驱动工具操作手机,详细的介绍以及如何安装adb驱动可以 ...

  2. 100行python代码做一个程序_100行python代码实现微信跳一跳辅助程序

    写在前面 分享一下今天下午用python写的"跳一跳"小游戏的辅助程序.之前是准备用树莓派操控一个"机械手指"来代替人的触摸操作,但该方案还在酝酿中,实现了再分 ...

  3. scratch小游戏脚本大全_酷酷带你一起做小游戏--跳一跳

    运用scratch我做了一个跳一跳小游戏,首先我要确定游戏流程, 小恐龙跑向障碍物,玩家用键盘的空格键控制恐龙跳跃 如果恐龙跳过障碍物则游戏分数加一 如果恐龙接触到障碍物则游戏结束,脚本全部停止 先添 ...

  4. python做的游戏怎么导到微信_微信跳一跳游戏的脚本-scratch导出到微信-微信小程序是怎么做的...

    1. 微信更新后出来了一块比较火的小游戏,要是一款不涉及到排行的游戏,可能没人去关注这款游戏.最开自己一直苦练技术,想在微信排行上面装一装,练了好久才跑三百多分.接着在Github(Github地址: ...

  5. python做的游戏放到微信_【1、 创建一个python的文件,运行后,文字版方式模拟微信游戏“跳一跳?】...

    python脚本学习过程推荐 学习流程: 一:打础 1.找到合适的书籍(推荐Python核心编程2Dive into Python),大致读一次,循环啊判,常用类啊,搞懂(太难的跳过) 2.勤练习py ...

  6. 做一个微信跳一跳的外挂

    淘宝上好多卖跳一跳代练的,其实做一个很简单,不需要有安卓开发知识,不需要有图像识别知识,不需要有人工智能知识!重要的事情说三遍,都不需要. 简单说一下思路: 1.用adb连手机截图,命令是: adb ...

  7. 手把手教你做跳一跳助手

    转载自:http://blog.csdn.net/OQjya206rsQ71/article/details/78970088 其实也不能说算是外挂吧,算是个游戏小助手吧,毕竟不能抓包,也不能直接修改 ...

  8. “跳一跳”小游戏这么火爆,它是如何做的设计和开发?

    2018 伊始,最火爆的不是春晚和红包,而是从天而降的"跳一跳".这款来自微信的轻量级小游戏,以 2800 万人 / 小时的惊人 PCU 数据,稳据小游戏排行榜首位.如果你还不了解 ...

  9. 糖葫芦不做了,我们来跳一跳吧 O(∩_∩)O~~ PCA + 截断 SVD (含 python 实现及代码细节梳理)

    上一篇我串了糖葫芦,矩阵乘法/线性变换 + 特征分解/奇异值分解(SVD) + PCA. PCA 本来是糖葫芦的最后也是最上面那颗山楂,无奈山楂太大了 2333,所以这里另起一篇了.然后 PCA 这篇 ...

最新文章

  1. 通过BeanShell获取UUID并将参数传递给Jmeter
  2. CCF C³:创业公司如何面对开源?知乎CTO李大海:谢邀
  3. hdu1316 大数
  4. c语言词法分析程序实验报告,实验一词法分析程序设计与实现
  5. /etc/passwd 与 /etc/shadow文件的区别
  6. #pragma pack(n)和sizeof求结构的大小
  7. java命令行参数工具_Java方法中的参数太多,第8部分:工具
  8. IDEA 配置Maven国内源
  9. c++ opencv mat_实战 | OpenCV 实现多张图像拼接
  10. Flink-org.apache.flink.streaming.api.windowing.windows.Window
  11. SQLServer中在视图上使用索引(转载)
  12. Dev Express 安装
  13. 超强 | 保险单据在线OCR,秒速识别保单信息
  14. VirtualBox下安装Windows Server 2008
  15. 安装microsoft office 和visio遇到的那些事儿
  16. 什么是激光导航扫地机器人?
  17. RTI_DDS使用参与者QoS属性编辑传输TCP
  18. 批量安装windows系统补丁包
  19. ArcGIS之经纬度表格数据转矢量
  20. 【毕业设计选题】2022通信工程毕业设计题目推荐大全

热门文章

  1. gitlab 有master权限提交master时报错
  2. 苹果启动2亿美元环境保护基金;英特尔将为汽车制造商生产芯片|前沿科技周报
  3. 「经验分享」plantsimulation生产系统仿真教程利用率和MTTR模拟
  4. 小学生学Arduino------制作流水灯
  5. 如何防止DNS被修改
  6. 华硕重炮手b550m plus的bios超频介绍
  7. php文件提示保存文件,php header函数文件下载时直接提示保存
  8. 新编计算机科学概论考试,新编计算机科学概论-刘艺蔡敏-习题与答案
  9. deepin美化,conky使用教程
  10. 信息摘要算法之一:MD5算法解析及实现