手把手教你做跳一跳助手
转载自:http://blog.csdn.net/OQjya206rsQ71/article/details/78970088
其实也不能说算是外挂吧,算是个游戏小助手吧,毕竟不能抓包,也不能直接修改分数(据说之前可以直接抓包修改分数,不过这漏洞已经被微信官方修复),今天这个是 Android 同学可以非常容易看懂的一篇文章,是从 Android 的角度实现的,附带着技术原理分析和代码分析。
这个开源库已经被我同学分享到 GitHub 上,他自己很无聊,就写了这个东西和这篇文章,自己通过写代码实现高分也是玩的不亦乐乎,这就是程序员和普通玩家的区别吧。
开源库地址:https://github.com/xushanmeng/WechatJumpHelper
功能简介
用JAVA自动控制手机玩跳一跳
自动识别图像计算距离
自动帮你点击屏幕
自动缓存图片,并在图片上标记一些识别结果,如下图:
运行环境
JAVA,最低版本为7.0,官网下载
adb驱动,官网下载(需要翻墙),或者到这里下载SDK-tools,其中就包含adb
安卓手机,目前已适配分辨率
1600x2560
1440x2560
1080x1920
720x1080
使用方法
有JAVA开发工具的同学可以直接运行java代码,便于代码调试,下面主要介绍运行已经打包好的jar包的方法
手机打开USB调试,并连接电脑
打开USB调试方法,进入
设置
,找到开发者选项
,打开并勾选USB调试
;如果没有
开发者选项
,进入关于手机
,连续点击版本号
7次,即可开启开发者选项
。
通过下面的命令,运行Android.jar
java -jar Android.jar
根据手机分辨率选择跳跃系数,目前已适配机型:
其他分辨率请自己微调。
1600x2560机型推荐0.92
1440x2560机型推荐1.039
1080x1920机型推荐1.392
720x1080机型推荐2.078
原理说明
通过adb命令控制手机截图,并取回到本地
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png .
图片分析
有靶点,即目标物体中心的白色圆点,则靶点中心为目标落点
无靶点,但是纯色平面,或者规则平面,则平面中心为目标落点
无靶点,又无纯色规则平面,但是左上和右上位置的斜率是固定的,可根据固定斜率的斜线和目标物体中心线的焦点计算落点
根据棋子的颜色,取顶部和底部的特征像素点,在截图中进行匹配,找到棋子坐标
由于目标物体不是在左上就是在右上,可以从上往下扫描,根据色差判断目标物体位置,其中又分为以下几种类型
计算棋子坐标和目标落点的距离
距离×跳跃系数=按压屏幕的时间,不同分辨率的手机,跳跃系数也有所不同
通过adb命令,给手机模拟按压事件
adb shell input swipe x y x y time
其中x
和y
是屏幕坐标,time
是触摸时间,单位ms。
工程结构
代码详解
这里将针对一些关键算法的代码进行解释
寻找棋子位置
把截图放大,可以看到棋子顶部像素连成一条横线,那么我们通过颜色匹配,找到这一条线的始末位置,取中间位置,就得到了棋子的x坐标。
棋子的底部也是一条横线,用颜色匹配,我们检测到相似颜色的最大y坐标,就是棋子底部了,不过考虑到棋子底部是个圆盘,我们把棋子的y坐标再往上提一些。
这样我们就得到了棋子的xy坐标,下面是相关代码:
/* 计算棋子位置 */ Pixel piece = new Pixel(); for (int i = TOP_BORDER; i < screenHeight - BOTTOM_BORDER; i++) {int startX = 0;int endX = 0;for (int j = LEFT_BORDER; j < screenWidth - RIGHT_BORDER; j++) {int red = Color.red(pixels[i][j].color);int green = Color.green(pixels[i][j].color);int blue = Color.blue(pixels[i][j].color);if (50 < red && red < 55&& 50 < green && green < 55&& 55 < blue && blue < 65) {//棋子顶部颜色//如果侦测到棋子相似颜色,记录下开始点if (startX == 0) {startX = j;endX = 0;}} else if (endX == 0) {//记录下结束点endX = j;if (endX - startX < PIECE_TOP_PIXELS) {//规避井盖的BUG,像素点不够长,则重新计算startX = 0;endX = 0;}}if (50 < red && red < 60&& 55 < green && green < 65&& 95 < blue && blue < 105) {//棋子底部的颜色//最后探测到的颜色就是棋子的底部像素piece.y = i;}}if (startX != 0 && piece.x == 0) {piece.x = (startX + endX) / 2;} } //棋子纵坐标从底部边缘调整到底部中心 piece.y -= PIECE_BOTTOM_CENTER_SHIFT;
寻找靶点
所谓靶点,就是目标物体中心的那个小圆点,颜色值为
0xf5f5f5
。那么我们只需要寻找颜色值为0xf5f5f5的色块就可以了,为了规避其他物体相近颜色干扰,我们可以限制色块的大小,正确大小的色块才是靶点。
但是如何计算色块的大小呢,色块最顶端到最底端y坐标的差值我们作为色块的高度,同理,最左侧到最右侧x坐标的差值作为宽度,我们只需要查找这四个顶点的坐标就可以了。
本来打算用凸包的Graham扫描算法,后来发现色块已经是凸包了,且边缘像素是连续的,那么我们按照一定顺序,遍历边缘像素,就可以在O(n^-2)的时间复杂度里,得到色块的顶点坐标了。
我们从第一个像素点开始,寻找的顺序如图所示:
/*** 寻找色块顶点像素*/public static final Pixel[] findVertexs(Pixel[][] pixels, Pixel firstPixcel) {Pixel[] vertexs = new Pixel[4];Pixel topPixel = firstPixcel;Pixel leftPixel = firstPixcel;Pixel rightPixel = firstPixcel;Pixel bottomPixel = firstPixcel;Pixel currentPixcel = firstPixcel;//先把坐标置于左上角while (checkBorder(pixels, currentPixcel)//判断是否超出图像边缘&& Color.compareColor(pixels[currentPixcel.y - 1][currentPixcel.x], firstPixcel)) {//判断是否是相同颜色currentPixcel = pixels[currentPixcel.y - 1][currentPixcel.x];}while (checkBorder(pixels, currentPixcel)&& Color.compareColor(pixels[currentPixcel.y][currentPixcel.x - 1], firstPixcel)) {currentPixcel = pixels[currentPixcel.y][currentPixcel.x - 1];}//寻找上顶点像素while (checkBorder(pixels, currentPixcel)) {if (Color.compareColor(pixels[currentPixcel.y - 1][currentPixcel.x], firstPixcel)) {currentPixcel = pixels[currentPixcel.y - 1][currentPixcel.x];} else if (Color.compareColor(pixels[currentPixcel.y][currentPixcel.x + 1], firstPixcel)) {currentPixcel = pixels[currentPixcel.y][currentPixcel.x + 1];} else {topPixel = findCenterPixcelHorizontal(pixels, currentPixcel);break;}}//寻找右顶点像素while (checkBorder(pixels, currentPixcel)) {if (Color.compareColor(pixels[currentPixcel.y][currentPixcel.x + 1], firstPixcel)) {currentPixcel = pixels[currentPixcel.y][currentPixcel.x + 1];} else if (Color.compareColor(pixels[currentPixcel.y + 1][currentPixcel.x], firstPixcel)) {currentPixcel = pixels[currentPixcel.y + 1][currentPixcel.x];} else {rightPixel = findCenterPixcelVertial(pixels, currentPixcel);break;}}//寻找下顶点像素while (checkBorder(pixels, currentPixcel)) {if (Color.compareColor(pixels[currentPixcel.y + 1][currentPixcel.x], firstPixcel)) {currentPixcel = pixels[currentPixcel.y + 1][currentPixcel.x];} else if (Color.compareColor(pixels[currentPixcel.y][currentPixcel.x - 1], firstPixcel)) {currentPixcel = pixels[currentPixcel.y][currentPixcel.x - 1];} else {bottomPixel = findCenterPixcelHorizontal(pixels, currentPixcel);break;}}//寻找左顶点像素while (checkBorder(pixels, currentPixcel)) {if (Color.compareColor(pixels[currentPixcel.y][currentPixcel.x - 1], firstPixcel)) {currentPixcel = pixels[currentPixcel.y][currentPixcel.x - 1];} else if (Color.compareColor(pixels[currentPixcel.y - 1][currentPixcel.x], firstPixcel)) {currentPixcel = pixels[currentPixcel.y - 1][currentPixcel.x];} else {leftPixel = findCenterPixcelVertial(pixels, currentPixcel);break;}}vertexs[0] = leftPixel;vertexs[1] = topPixel;vertexs[2] = rightPixel;vertexs[3] = bottomPixel;return vertexs;}
得到了四个坐标点,我们就可以计算色块的中点了,也就是目标落点。
对于没有靶点,但是落点是规则平面的,也可以用类似算法。
斜率计算对于没有靶点,又不是规则平面的,我们怎么计算落点呢,这时候就要用到斜率了。
可以看得出来,每次左上角或右上角出现的物体,针对当前物体的方向都是一样的,也就是两个物体中心的连线,斜率是固定的。
基本所有的目标物体,最顶点像素中点的x坐标,都是在物体中间,我们至少先得到了目标物体x坐标了,记为des.x ,接下来要求des.y 。
如上图所示,计算过程如下:
斜线的公式为 y=kx+b
那么,在棋子坐标上有 piece.y=k*piece.x+b
在目标落点坐标上有 des.y=kdes.x+b
代入得到 des.y=k*(des.x-piece.x)+piece.y
然而这种算法还是有偏差的。
可以看到,同样的斜率,如果棋子的位置有偏差,计算出来最终落点还是会有偏差的。
代码解析就先讲这么多,希望有大神可以提出更好的解决方案。
玩游戏小窍门
连续的落到物体中心位置,是有分数加成的,最多跳一次可以得几十分
井盖、商店、唱片、魔方,多停留一会,有音乐响起后也是有分数加成的
那么看一下程序员的朋友圈有多残酷吧
手把手教你做跳一跳助手相关推荐
- python入门小游戏之跳一跳_从零基础开始,用python手把手教你玩跳一跳小游戏,直接打出高分...
这对于很多人来说,可能是已经过时的游戏,但是对于python入门来说,却是一个非常值得学习的项目. TONOW收集了很多有关python入门的项目案例,包含了相应的教程和源码,哪怕你从未接触编程,也通 ...
- python 玩公众号游戏_从零基础开始,用python手把手教你玩跳一跳小游戏,直接打出高分...
这对于很多人来说,可能是已经过时的游戏,但是对于python入门来说,却是一个非常值得学习的项目. 我们收集了很多有关python入门的项目案例,包含了相应的教程和源码,哪怕你从未接触编程,也通过这些 ...
- 实例:用C#.NET手把手教你做微信公众号开发(20)--使用微信支付线上收款:jsapi方式
在做线上.线下销售时,可以使用微信便捷支付,通过微信公众号收款有很多种收款方式,如下图: 今天我们来讲一下jsapi支付,场景就是在微信内打开某个页面,完成在线支付,同样一个网页,使用微信打开就是js ...
- 手把手教你做短视频去水印微信小程序(2-首页)
手把手教你做短视频去水印微信小程序系列教程(2-首页) 文章目录 手把手教你做短视频去水印微信小程序系列教程(2-首页) 前言 一.顶部banner 二.地址解析 1.整体代码 2. input框输入 ...
- 手把手教你做一个自己的chrome扩展程序
手把手教你做一个自己的chrome扩展程序 [目录] first.效果 1.收藏夹修改 (1).鼠标移动到收藏夹上的动作效果 (2).收藏夹框 (3)百度搜索框功能 2.右上文字修改 3.背景图片修改 ...
- 实例:用C#.NET手把手教你做微信公众号开发(21)--使用微信支付线上收款:H5方式
在做线上.线下销售时,可以使用微信便捷支付,通过微信公众号收款有很多种收款方式,如下图: 今天我们来讲一下H5场景支付,使用手机浏览器打开就是H5方式,最常见的推广是短信内置链接,这种场景需要调用微信 ...
- 福利预告,跳一跳助手即将发布,您不知道还有这些...
福利预告,跳一跳助手即将来临 一周后,即2月9号正式发布 跳一跳助手,免费免费免费提供! 透露一下 跳一跳助手的界面是这样滴: 这工具有啥用? 举个栗子: 花城君用该工具,不小心就玩到了680分了 ...
- 手把手教MFC做计算器
手把手教MFC做计算器 创建时间:2011年7月19日(星期二) 下午4:56 | 分类:未分类 | 字数:6671 | 发送到我的Qzone | 另存为... | 打印 手把手教MFC做计算器 (2 ...
- 手把手教你做关键词匹配项目(搜索引擎)---- 第九天
第九天 回顾: 8. 手把手教你做关键词匹配项目(搜索引擎)---- 第八天 7. 手把手教你做关键词匹配项目(搜索引擎)---- 第七天 6. 手把手教你做关键词匹配项目(搜索引擎)---- 第六天 ...
最新文章
- java selenium常用API(WebElement、iFrame、select、alert、浏览器窗口、事件、js) 一
- 开发日记-20190802 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 18
- python与excel结合能做什么-机器学习实践:如何将Spark与Python结合
- 2016c语言模拟试卷一,2016年9月计算机二级C语言考试预测试题及答案(4)
- rabbitmq安装与配置(windows)亲测有效!!!
- 《疯狂Java讲义》(二十九)---- JDBC
- PAT:1032. Sharing (25) AC
- 微信小程序学习笔记01:微信小程序概述
- Python的list方法append和extend有什么区别?
- C语言去除字符串空格
- python冒泡循环示例_Python循环示例–循环在python中
- python 对文件夹的相关操作
- 运算放大器权威指南(第3版) (op amps for everyone)_OP高质量,ED多版本,有钱的动物狂想曲就是能为所欲为...
- 奈奎斯特稳定性判据的详细推导(手把手教,看完就会!)
- JTT808/1078管理平台发布
- 投资热议:为什么另类数据对数字转型至关重要?
- mysql获取某个最大的值的一行数据_某一字段分组取最大(小)值所在行的数据
- C++算法和数据结构之《二叉树》
- vue组件通讯:父传子、子传父、事件发射详解
- 微型计算机百度云,STONE_百度云资源_盘多多如风搜_盘搜搜_哎哟喂啊
热门文章
- C# 操作.mdb文件出现.ldb锁死文件 无法删除.mdb文件
- 详细研究swarm项目的安装教程,完整版,怎么安装bee
- springboot-WSDL服务端
- 横轴墨卡托投影参数_几种投影的主要参数【转】
- MyBatis Review——整合ehcache
- Android中图案锁的实现
- 学成在线-第19天-讲义-分布式事务
- K8S node-shell
- 解决[Error] ‘i‘ was not declared in this scope
- android导入win10照片,iphone手机照片导入win10电脑的方法