微信跳一跳辅助插件(纯Android原生实现)

微信跳一跳也出来一段时间了,各种插件版本也是层出不穷,基于学习的目的,写了这个demo,完全是android原生实现。

目前的辅助程序大致原理都是一样的,只是实现方式不同。

运行效果


原理

1.截取当前屏幕
2.根据图片确定几个关键坐标点的位置(如下图所示)
3.计算棋子底部和下一个直线跳台的距离
4.根据距离模拟触摸屏幕
jump1.png

一开打算使用AccessibilityService来实现(比如之前比较火热的抢红包插件),因为不需用root系统,但是后来在截取屏幕的时候发现不太好实现,就放弃了。
后来选择使用adb shell命令来截屏和模拟点击,但是可惜的是需要root,所以只能root手机了(魅族自带root功能,非常方便)。
root之后一切就好办了,直接用service就能实现我们想要的功能了。

思路

1.启动一个服务
2.在服务里重复执行:截屏——计算——点击屏幕的操作就行了

注意点

1.确保服务不会轻易被系统杀死,这边我用了前台服务(优先级稍高于后台服务)
2.图片的扫描是bitmap对象,这边注意bitmap的内存回收

关键代码

截屏和模拟点击

获取了root权限后:
主要是两条指令:
screencap -p /sdcard/跳一跳助手/wxjump.png"//截屏
input swipe 100 100 100 100 100//触摸屏幕

本地图像识别确定关键坐标点

首先扫描确定目标跳台的上顶点,因为微信跳一跳的背景几乎都为纯色背景,
可以通过逐行扫描,根据颜色差来确定上顶点。
这边不需要扫描全部图片,跳台的高度基本在屏幕的上半部分,可以扫描(1/3——2/3或者2/5——3/5)
大概差不多就行,可以自行调整。

Bitmap src =  BitmapFactory.decodeFile("/sdcard/跳一跳助手/wxjump.png");//获取本地图像
int  R, G, B;
        int pixelColor;
        int pixelColorTop=0;//台面上顶点颜色
        int pixelBottomColor=0;//台面下顶点颜色
        int height = src.getHeight();
        int width = src.getWidth();
        Point chessPoint=new Point();//棋子坐标点
        Point tableTopPoint=new Point();//目标跳台上顶点
        Point tableMiddlePoint=new Point();//目标跳台中心点
        Point tableBottomPoint=new Point();//目标跳台下顶点
        //寻找跳台上顶点
        searchTop:
        for (int y = height/4; y < 2*height/3; y++) {
            int pixelColorBorder=src.getPixel(50, y);//边界对照颜色
            int R_BORDER= Color.red(pixelColorBorder);
            int G_BORDER= Color.green(pixelColorBorder);
            int B_BORDER= Color.blue(pixelColorBorder);
            for (int x = 50; x < width-50; x++) {
                pixelColor = src.getPixel(x, y);
                R = Color.red(pixelColor);
                G = Color.green(pixelColor);
                B = Color.blue(pixelColor);
                //根据颜色值差异判断上顶点
                if(Math.abs(R_BORDER-R)>10||Math.abs(G_BORDER-G)>10||Math.abs(B_BORDER-B)>10){
                    pixelColorTop=pixelColor;
                    tableTopPoint.x=x;
                    tableTopPoint.y=y;
                    Log.e("tableTopPointColor:","("+R+"|"+G+"|"+B+")");
                    break searchTop;
                }

            }
        }

逐行扫描,首先是获取边界对照点的颜色值,然后逐一比对。我看过其他的一些版本,有些是根据只要颜色值不同
就默认为是上顶点。但是实际提取颜色的过程中,我发现同一行每一个像素点背景的颜色存在细小的误差,比如两个相邻点
的颜色值可能是RGB[255,255,255]和[254,254,255]。
所以我这边判断上顶点是根据检测点与边界对照点RGB的误差超过10就可以认为是上顶点。(目前测试没有发现问题)

//寻找棋子坐标点
        searchChess:
        for(int y=tableTopPoint.y;y<2*height/3; y++){
            for (int x = 50; x < width-50; x++) {
                pixelColor = src.getPixel(x, y);
                R = Color.red(pixelColor);
                G = Color.green(pixelColor);
                B = Color.blue(pixelColor);
                //根据颜色值判断棋子上定顶点
                if(50 < R&&R< 60&&53 < G &&G< 63&&95 < B&&B< 110){
                    chessPoint.x=x;
                    chessPoint.y=y+130;
                    Log.e("chess:",chessPoint.x+"|"+chessPoint.y);
                    Log.e("chess:",R+"|"+G+"|"+B);
                    break searchChess;
                }
            }
        }

棋子的坐标点相对好找,这边为了节省扫描开支,y轴可以从跳台的上顶点往下扫描
直接判定颜色值得RGB范围即可确定。和其他版本不同的是,我这边只扫描了棋子的上顶点。因为
棋子的大小是固定的,确定了上顶点就可以确定棋子跳台的中心位置了。我这边默认加了130(可能有一些误差,实际测试暂时没发现问题)

//寻找跳台下顶点,从最大方块往上计算,寻找与上顶点相同的点
        for(int y=tableTopPoint.y+274;y>tableTopPoint.y; y--){
            pixelBottomColor = src.getPixel(tableTopPoint.x, y);
            if(pixelBottomColor==pixelColorTop){
                tableBottomPoint.x=tableTopPoint.x;
                tableBottomPoint.y=y;
                tableMiddlePoint.x=tableBottomPoint.x;
                tableMiddlePoint.y=(tableBottomPoint.y+tableTopPoint.y)/2;
                Log.e("bottom:",tableTopPoint.x+"|"+y);
                Log.e("middle:",tableMiddlePoint.x+"|"+tableMiddlePoint.y);
                break;
            }

        }

这边也是其他版本提供的思路,获取到上顶点后,因为跳一跳跳台的大小不会超过某一个值,所以直接从上顶点的y
坐标加274往上扫描,颜色值与上顶点相同的点就是下顶点。这里的274大约是最大方块的对角线长度。

计算距离s;确定触摸时间t

因为距离和触摸时间是一个一次函数t=k*s,所以只需要确定k的值就行

 float SpaceTimeConfig=0.92f;
        Log.e("distance",(int)(SpaceTimeConfig*distance)+"");
        try {
            CommandExecution.execCommand("input swipe 100 100 100 100 "+(int)(SpaceTimeConfig*distance),true);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("error",e.getMessage()+"");
        }
 我这边k的值取得0.92 (测试后,每次都跳的中心点)这个值试几次就可以调出来,当然你也可以自己计算出
 不同的分辨率的屏幕需要调整一下

其他优化待优化的地方

 1.图像识别的地方还可以优化,主要是跳台的上下顶点位置,某些特殊的纹路会识别失败(木纹之类的)
 2.代码里的一些常量(k的系数,棋子高度,跳台的最大面宽等),也不需要手动替换,可以获取屏幕的分辨率来做适配
 3.读取本地图像的权限问题,我没有做适配,因为测试用的魅族手机,6.0以上的权限不需要特别适配,如果是其他手机还要增加读取权限。

GitHub地址https://github.com/shajinyang/WxJumpGame

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容