跳一跳java代码教程_Java代码模拟按键玩Android微信跳一跳

微信跳一跳这个小游戏很火,网上已经出现了很多“辅助”,大部分都可以让你拿高分,常年稳置榜首,9999分不是梦。

我出于兴趣,使用Java也写了一个,只能在Android上玩,我写这个不是为了拿高分,测试的时候是离线下测试的,就是想写来玩一玩。

大概思路如下:

电脑通过数据线连接手机。通过 adb shell screencap -p /*.* 让手机截屏并保存到SD卡。使用 adb pull /sdcard/*.* *://*.* 把手机里的图片拉取到电脑。分析得到的图片从而计算模拟按键时间。

分析图片

d4784b6bb1b166f644c82ec216aadf52.png

看这张图片,我们需要找到两个来确定跳跃的距离,第一个点是人物脚下的点,第二个点是目标跳板的中点。

我直接遍历这张图的每一个像素点,但有点地方是可以忽略的,如上面的1/3和下面的1/3区域。

人物的点很好找,用PS打开图片,放大再放大

7ea0a5920f321b441266457ef5c6f6ea.png

查看中间点的rgb值,一般都可以较准确的找到人物的中点,但有极少数情况会找不到。

9b28b129990faa8b7e94434105aa5ce4.png       而目标跳板的中点就有点麻烦了,跳板的形状有正方形,圆形,我们可以找到两个点来确定跳板的中点,最上面和最下面的点。

手机屏幕的坐标左上角为(0,0),从上到下,从右到左遍历图片,把遍历的每一个点的rgb值和背景(同一行最左或最右的像素点,因为背景色会从上到下渐变)比较,如果和背景色不同,那么目标的最上点就找到了。

接着找最下点,因为最上点已知了,最下点的查找范围就设置在最上点的左右,用同样方法即可找到。

取上下两点的中间就是目标跳板的中点了。

最后计算人物到目标跳板的距离

7dabb4f75c9babcb04e67ce11487a8e1.png

使用公式即可。

最后模拟按键时间通过使用距离乘上一个常熟得到,常数是多少,不知道,多试几下可以大概猜出,我用的是1.436 。

这个代码还不完美,只能玩400分左右。。。有时又能700分,不过,毕竟是自己写的,没法和GitHub上热门的比,已经较满意了,看心情决定要不要继续写,哈哈。

代码:

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

public class Main {

private static int image = 0;

public static void main(String[] args) throws Exception{

while (true) {

//截图到手机

cmd("adb shell screencap -p /sdcard/.a/" + image + ".png");

//从手机拉取图片到电脑

new File("e:/" + image + ".png").createNewFile();

cmd("adb pull /sdcard/.a/" + image +".png " + "e:/" + image + ".png");

//计算按键时间并模拟按键

int pressTime = (int) (get_pressTime()*1000/1000);

cmd("adb shell input swipe 550 1600 550 1600 " + pressTime);

System.out.println("按键时间为:"+pressTime);

System.out.println("-----------");

//模拟右滑

//cmd("adb shell input swipe 850 1600 550 1600 400");

image++;

TimeUnit.MILLISECONDS.sleep(1000);

}

}

//计算按键时间

private static double get_pressTime() throws IOException{

File file = new File("e:/" + image + ".png");

BufferedImage img = ImageIO.read(file);

int width = img.getWidth();

int height = img.getHeight();

int[] s = s_xy(img, width, height);

if (s == null) {

System.out.println("游戏结束!");

System.exit(0);

}

//cmd("adb shell input swipe " +s[0]+" "+s[1]+" "+s[0]+" "+s[1]+" 2000");

System.out.println("人的位置:" + s[0] + " " + s[1]);

int[] o = o_xy(img, width, height);

if (o == null) {

System.out.println("游戏结束!");

System.exit(0);

}

//cmd("adb shell input swipe " +o[0]+" "+o[1]+" "+o[0]+" "+o[1]+" 2000");

System.out.println("目标垫子:" + o[0] + " " + o[1]);

double d = Math.sqrt(Math.abs((o[0]-s[0]) * (o[0]-s[0]) + (o[1]-s[1]) * (o[1]-s[1])));

System.out.println("两点距离:" + d);

img.flush();

return d * 1.436;

}

//寻找人的位置

private static int[] s_xy(BufferedImage img, int width, int height) {

int[] s = { 0, 0 };

for (int y = height/3; y < height - height/3; y++) {

for (int x = width/5; x < width; x++) {

int rgb = img.getRGB(x, y);

int r =(rgb & 0xff0000 ) >> 16 ;

int g= (rgb & 0xff00 ) >> 8 ;

int b= (rgb & 0xff );

if (r == 57 && g == 59 && b == 102) {//脚底的rgb

s[0] = x;

s[1] = y;

return s;

}

}

}

return null;

}

//寻找目标跳板中点

private static int[] o_xy(BufferedImage img, int width, int height) {

int[] o = { 0, 0 };

for (int y = height/3; y < height-height/3; y++) {

for (int x = width-2; x > 0; x--) {

//右边对比点

int trgb = img.getRGB(width-1, y);

int tr = (trgb & 0xff0000) >> 16 ;

int tg = (trgb & 0xff00) >> 8 ;

int tb = (trgb & 0xff);

//当前点

int rgb = img.getRGB(x, y);

int r = (rgb & 0xff0000) >> 16 ;

int g = (rgb & 0xff00) >> 8 ;

int b = (rgb & 0xff);

//人头挡住

if ((r <= 75 && r >= 50) && (g <= 76 && g >= 50) && (b <= 109 && b >= 50) && x >= 70) {

//跳到人头左边

x = x - 70;

rgb = img.getRGB(x, y);

r = (rgb & 0xff0000) >> 16 ;

g = (rgb & 0xff00) >> 8 ;

b = (rgb & 0xff);

}

//找到跳板的最上点,和背景的rgb值做对比,加点误差范围

if ((r <= tr-3 || r >= tr+3) && (g <= tg-3 || g >= tg+3) && (b <= tb-4 || b >= tb+3) ||

(r <= tr-3 || r >= tr+3) || (g <= tg-3 || g >= tg+3) && (b <= tb-4 || b >= tb+3) ||

(g <= tg-3 || g >= tg+3) || (b <= tb-3 || b >= tb+3) && (r <= tr-4 || r >= tr+3))

{

/*

o[0] = x;

o[1] = y;

return o;*/

//药瓶

if (rgb == img.getRGB(x-5, y) && r == 255 && g == 255 & b == 255) {

x -= 5;

for (int by = y + 60; by > y; by--) {

for (int bx = x + 30; bx > x - 30; bx--) {

if (img.getRGB(bx, by) == rgb) {

o[0] = (x + bx)/2;

o[1] = (y + by)/2;

return o;

}

}

}

}

//正方形跳板 找最下的点

for (int by = y + 260; by > y; by--) {

for (int bx = x + 60; bx > x - 60; bx--) {

if (img.getRGB(bx, by) == rgb) {

o[0] = (x + bx)/2;

o[1] = (y + by)/2;

return o;

}

}

}

}

}

}

return null;

}

//调用命令行

private static void cmd(String command){

Process process = null;

try {

process = Runtime.getRuntime().exec(command);

process.waitFor();

}

catch (Exception e) {

e.printStackTrace();

}

finally {

if (process != null) process.destroy();

}

}

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值