微信跳一跳刷分原理
基本原理就是在 windows 上使用 Android 的 Debug 调试工具点开跳一跳小程序, 每挑一个箱子之前截图上传,通过一个小算法计算小人和下个箱子中心点像素个数得出按压屏幕力度参数,通过 adb 工具实现自动屏幕按压
算法是从 GitHub 上面找到的
逻辑是自己用代码实现的
我尽可能写的详细点
1、需要准备的
1、安卓手机一台
2、Android adb 工具包
3、windows操作系统的电脑一台(这儿用的 win10)、
4、jdk(1.6版本以上)
5、我封装好的跳一跳工具 jar 包
链接: https://pan.baidu.com/s/1hsaohcK 密码: euy3
2、配置 Android adb 环境变量
1、下载 Android adb 工具包
解压到你想解压的任何文件夹,记住工具包的根目录 :D
举个例子: 我的路径是 E:\testadb
无图言吊
2、配置 adb 到环境变量
右键我的电脑 选择属性
点击左侧高级系统设置
点击右下角环境变量
在系统变量一栏找到 Path 双击它
如果你的系统环境变量是这样
点击新建并将你的 adb 工具根目录放进去
如果是这样
在最后面放上你的 adb 工具根目录,记住!!!放根目录之前先加个分号
测试环境变量是否配置好::::::::
打开 DOS 命令窗口,也就是平时所说的 CMD 命令窗口,如果你不会,那就按 win 键(开始键) + R 键,弹出的运行框中输入 CMD 然后使劲敲回车,不用力可能会敲不进!
在命令窗口中 输入adb 如果出现这些说明你成功了
3、配置 JDK
简单介绍一下:
JDK是 java 语言的软件开发工具包。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。、
具体配置方法在我另一篇博客里面 这是链接:http://www.cnblogs.com/mutougezi/p/5465642.html
4、开始搞事情
打开安卓手机上的 USB 调试
将手机连上你的电脑
打开 CMD 输入
adb devices
出现下图说明连接成功
如果出现adb devices unauthorized 这个小东西,撤销手机上的USB调试授权,关掉USB调试。然后重新打开他们
下载 jump.jar
找到它存放的目录
按住 shift + 鼠标右键
选择在此处打开命令菜单, win10系统选择 在此处打开 PowerShell 窗口
在命令行中输入
java -jar jump.jar -a "你放adb工具的根目录"
搞定!
写了三种模式
1、手动模式:需要点小人的脚底下,然后点击小人跳的箱子的中心(贼麻烦,不建议使用)
java -jar jump.jar -a "你放adb工具的根目录" -m 1
2、半自动模式:只需要鼠标点击小人跳的箱子中心(默认模式)
java -jar jump.jar -a "你放adb工具的根目录" -m 2
3、全自动模式:啥也不用干
java -jar jump.jar -a "你放adb工具的根目录" -m 3
逻辑具体实现的源码下篇博客再写,写烦了!
先贴上源码自己看吧
AdbCaller
package com.company.playJumpJumpWithMouse;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class AdbCaller {
private static String adbPath = Constants.ADB_PATH;
private static String screenshotLocation = Constants.SCREENSHOT_LOCATION;
private static Boolean error = null;
public static void setAdbPath(String adbPath) {
AdbCaller.adbPath = adbPath;
}
public static void setScreenshotLocation(String screenshotLocation) {
AdbCaller.screenshotLocation = screenshotLocation;
}
/**
* 调用adb长按屏幕
*
* @param timeMilli
*/
public static void longPress(double timeMilli, BufferedImage image) {
try {
int x = image.getWidth() / 3 + (int) (Math.random() * image.getWidth() / 3);
int y = image.getHeight() - 300 + (int) (Math.random() * 200);
int x2 = (int) (x + ((Math.random() - 0.5) * 20));//左右10个像素随机
int y2 = (int) (y + ((Math.random() - 0.5) * 20));//上下10个像素随机
Process process = Runtime.getRuntime()
.exec(adbPath + " shell input touchscreen swipe " + x + " " + y + " " + x2 + " " + y2 + " " + (int) timeMilli);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = bufferedReader.readLine()) != null)
System.out.println(s);
process.waitFor();
JumpPerfectControl.jumpNext();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 改进的截图方法<br>
* 感谢 hxzqlh
* 当改进的截图方法不能正常执行时降级为常规方法
*/
public static void printScreen() {
if (error != null && error) {
printScreenWithOld();
} else {
try {
String[] args = new String[]{"bash", "-c", adbPath + " exec-out screencap -p > " + screenshotLocation};
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
args[0] = "cmd";
args[1] = "/c";
}
Process p1 = Runtime.getRuntime().exec(args);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
String s;
while ((s = bufferedReader.readLine()) != null)
System.out.println(s);
p1.waitFor();
checkScreenSuccess();
} catch (IOException e) {
e.printStackTrace();
error = true;
printScreenWithOld();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void checkScreenSuccess() throws IOException {
if (error == null) {
BufferedImage image = ImageIO.read(new File(screenshotLocation));
if (image == null) {
throw new IOException("cann't read file \"" + screenshotLocation + "\" into image object");
}
}
}
public static void printScreenWithOld() {
try {
Process p1 = Runtime.getRuntime().exec(adbPath + " shell screencap -p /sdcard/screenshot.png");
p1.waitFor();
Process p2 = Runtime.getRuntime().exec(adbPath + " pull /sdcard/screenshot.png " + screenshotLocation);
p2.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static int getSize() {
try {
Process p = Runtime.getRuntime().exec("adb shell wm density");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = bufferedReader.readLine();
String[] splis = line.split(" ");
return Integer.valueOf(splis[splis.length - 1]);
} catch (Exception e) {
e.printStackTrace();
}
return 400;
}
public static void main(String[] args) {
System.out.println(getSize());
}
}
BackgroundImage4Panel
package com.company.playJumpJumpWithMouse;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
/**
* Created by RoyZ on 2017/12/28.
*/
public class BackgroundImage4Panel extends javax.swing.JFrame {
/**
* serialVersionId
*/
private static final long serialVersionUID = 1L;
private static boolean isFirst = true;
private static Point firstPoint;
private static Point secondPoint;
private static int playMode = Constants.MODE_MANUAL;
private static BufferedImage bufferedImage;
/**
* Creates new form NewJFrame
*/
public BackgroundImage4Panel() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
/**
* 测试入口
*
* @param args 参数列表
*/
public static void main(String[] args) {
ScreenAdapter.SCREEN_DPI = AdbCaller.getSize();
final int resizedScreenWidth, resizedScreenHeight;
final double resizedDistancePressTimeRatio;
final int screenshotInterval;
// adb path,screenshot path
final String screenshotPath;
Options options = new Options();
Option opt = new Option("h", "help", false, "Print help");
opt.setRequired(false);
options.addOption(opt);
opt = new Option("a", "adb-path", true,
"adb path in system,required, eg: C:\\Users\\RoyZ\\Desktop\\platform-tools\\adb.exe");
opt.setRequired(true);
options.addOption(opt);
opt = new Option("o", "screenshot-path", true,
"screenshot path, eg: C:\\Users\\RoyZ\\Desktop\\untitled\\s.png");
opt.setRequired(false);
options.addOption(opt);
opt = new Option("s", "size", true, "size of picture in window, eg: 675x1200");
opt.setRequired(false);
options.addOption(opt);
opt = new Option("t", "interval", true, "screenshot interval, unit millisecond, eg: 2500");
opt.setRequired(false);
options.addOption(opt);
opt = new Option("m", "play-mode", true, "1: manual-mode , 2: semi-mode(default) , 3: auto-mode ");
opt.setRequired(false);
options.addOption(opt);
opt = new Option("r", "random", true, "random done perfect, Y:yes, N:no");
opt.setRequired(false);
options.addOption(opt);
HelpFormatter hf = new HelpFormatter();
hf.setWidth(110);
CommandLine commandLine = null;
CommandLineParser parser = new PosixParser();
try {
commandLine = parser.parse(options, args);
if (commandLine.hasOption('h')) {
// 打印使用帮助
hf.printHelp("PlayJumpJumpWithMouse", options, true);
}
if (commandLine.getOptionValue('a') != null) {
AdbCaller.setAdbPath(commandLine.getOptionValue('a'));
}
if (commandLine.getOptionValue('o') != null) {
AdbCaller.setScreenshotLocation(commandLine.getOptionValue('o'));
screenshotPath = commandLine.getOptionValue('o');
} else {
AdbCaller.setScreenshotLocation("s.png");
screenshotPath = "s.png";
}
if (commandLine.getOptionValue('s') != null
&& Pattern.matches("\\d+x\\d+", commandLine.getOptionValue('s'))) {
String[] str = commandLine.getOptionValue('s').split("x");
resizedScreenWidth = Integer.parseInt(str[0]);
resizedScreenHeight = Integer.parseInt(str[1]);
} else {
resizedScreenWidth = Constants.RESIZED_SCREEN_WIDTH;
resizedScreenHeight = Constants.RESIZED_SCREEN_HEIGHT;
}
if (commandLine.getOptionValue('t') != null) {
screenshotInterval = Integer.parseInt(commandLine.getOptionValue('t'));
} else {
screenshotInterval = Constants.SCREENSHOT_INTERVAL;
}
if (commandLine.getOptionValue('m') != null) {
playMode = Integer.parseInt(commandLine.getOptionValue('m'));
} else {
playMode = Constants.MODE_SEMI_AUTO;
}
if (commandLine.getOptionValue('r') != null) {
if (commandLine.getOptionValue('r').toLowerCase().trim().equals("y")) {
JumpPerfectControl.random = true;
}
}
} catch (ParseException e) {
hf.printHelp("PlayJumpJumpWithMouse", options, true);
return;
}
//去掉了-r参数,改成根据width来进行自动换算.
resizedDistancePressTimeRatio = Constants.RESIZED_DISTANCE_PRESS_TIME_RATIO * Constants.RESIZED_SCREEN_WIDTH / resizedScreenWidth;
if (playMode == Constants.MODE_MANUAL || playMode == Constants.MODE_SEMI_AUTO) {
manualMode(resizedScreenWidth, resizedScreenHeight, resizedDistancePressTimeRatio,
screenshotInterval, screenshotPath);
} else if (playMode == Constants.MODE_AUTO) {
autoJumpMode(screenshotInterval, screenshotPath);
}
}
private static void manualMode(final int resizedScreenWidth, final int resizedScreenHeight,
final double resizedDistancePressTimeRatio, final int screenshotInterval, final String screenshotPath) {
AdbCaller.printScreen();
final BackgroundImage4Panel backgroundImage4Panel = new BackgroundImage4Panel();
backgroundImage4Panel.setSize(resizedScreenWidth, resizedScreenHeight);
backgroundImage4Panel.setVisible(true);
JPanel jPanel = new JPanel() {
/**
* serialVersionId
*/
private static final long serialVersionUID = -1183754274585001429L;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
try {
bufferedImage = ImageIO.read(new File(screenshotPath));
BufferedImage newImage = new BufferedImage(resizedScreenWidth, resizedScreenHeight,
bufferedImage.getType());
if (playMode == Constants.MODE_SEMI_AUTO) {
firstPoint = StartCenterFinder.findStartCenter(bufferedImage);
firstPoint.setLocation(firstPoint.getX() * resizedScreenWidth / bufferedImage.getWidth(),
firstPoint.getY() * resizedScreenWidth / bufferedImage.getWidth());
System.out.println("firstPoint = [x=" + firstPoint.x + ",y=" + firstPoint.y + "]");
isFirst = false;
}
/**
* try to resize
*/
Graphics gTemp = newImage.getGraphics();
gTemp.drawImage(bufferedImage, 0, 0, resizedScreenWidth, resizedScreenHeight, null);
gTemp.dispose();
bufferedImage = newImage;
g.drawImage(bufferedImage, 0, 0, null);
} catch (IOException e) {
e.printStackTrace();
}
}
};
backgroundImage4Panel.getContentPane().add(jPanel);
backgroundImage4Panel.getContentPane().getComponent(0).addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
JPanel jp = ((JPanel) backgroundImage4Panel.getContentPane().getComponent(0));
if (isFirst) {
System.out.println("first " + e.getX() + " " + e.getY());
firstPoint = e.getPoint();
isFirst = false;
} else {
secondPoint = e.getPoint();
int distance = distance(firstPoint, secondPoint);
System.out.println("distance:" + distance);
isFirst = true;
AdbCaller.longPress(distance * resizedDistancePressTimeRatio, bufferedImage);// magic
// number
try {
Thread.sleep(screenshotInterval * 2 / 3 + new Random().nextInt(screenshotInterval / 3));// wait for screencap
} catch (InterruptedException e1) {
e1.printStackTrace();
}
AdbCaller.printScreen();
jp.validate();
jp.repaint();
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
}
private static void autoJumpMode(final int screenshotInterval,
final String screenshotPath) {
new Thread() {
public void run() {
while (true) {
AdbCaller.printScreen();
try {
BufferedImage bufferedImage = ImageIO.read(new File(screenshotPath));
//自动模式的魔数也改为自动计算
double resizedDistancePressTimeRatio = Constants.RESIZED_DISTANCE_PRESS_TIME_RATIO * Constants.RESIZED_SCREEN_WIDTH / bufferedImage.getWidth();
firstPoint = StartCenterFinder.findStartCenter(bufferedImage);
secondPoint = EndCenterFinder.findEndCenter(bufferedImage, firstPoint);
// System.out.println(firstPoint + " , " + secondPoint);
int distance = secondPoint == null ? 0 : distance(firstPoint, secondPoint);
if (secondPoint == null || secondPoint.getX() == 0 || distance < ScreenAdapter.getBabyWidth() ||
// true || //放开可改为全部用ColorFilterFinder来做下一个中心点的查找
Math.abs(secondPoint.getX() - firstPoint.getX()) < ScreenAdapter.getBabyWidth() / 2) {
secondPoint = ColorFilterFinder.findEndCenter(bufferedImage, firstPoint);
if (secondPoint == null) {
AdbCaller.printScreen();
continue;
}
} else {
Point colorfilterCenter = ColorFilterFinder.findEndCenter(bufferedImage, firstPoint);
if (Math.abs(secondPoint.getX() - colorfilterCenter.getX()) > ScreenAdapter.getBabyWidth() / 3) {
secondPoint = colorfilterCenter;
}
}
System.out.println("firstPoint = [x=" + firstPoint.x + ",y=" + firstPoint.y
+ "] , secondPoint = [x=" + secondPoint.x + ",y=" + secondPoint.y + "]");
ColorFilterFinder.updateLastShapeMinMax(bufferedImage, firstPoint, secondPoint);
distance = distance(firstPoint, secondPoint);
AdbCaller.longPress(distance * resizedDistancePressTimeRatio, bufferedImage);// magic
// number
try {
Thread.sleep(screenshotInterval * 2 / 3 + new Random().nextInt(screenshotInterval / 3));// wait for screencap
// screencap
} catch (InterruptedException e1) {
e1.printStackTrace();
}
AdbCaller.printScreen();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}.start();
}
/**
* 对图片进行强制放大或缩小
*
* @param originalImage 原始图片
* @return
*/
public static BufferedImage zoomInImage(BufferedImage originalImage, int width, int height) {
BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
Graphics g = newImage.getGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return newImage;
}
public static int distance(Point a, Point b) {// 求两点距离
return (int) Math.sqrt((a.x - b.getX()) * (a.x - b.getX()) + (a.y - b.getY()) * (a.y - b.getY()));
}
}
ColorFilterFinder
package com.company.playJumpJumpWithMouse;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 直接根据色差来定位下一个中心点 Created by tangshuai on 2017/12/29.
*/
public class ColorFilterFinder {
static Color bgColor = Color.RED;
static Point startCenterPoint;
static int lastShapeMinMax = ScreenAdapter.getShapeMinWidth();
public static Point findEndCenter(BufferedImage bufferedImage, Point startCenterPoint) {
ColorFilterFinder.startCenterPoint = startCenterPoint;
bgColor = new Color(bufferedImage.getRGB(bufferedImage.getWidth() / 2, 300));
Point tmpStartCenterPoint;
Point tmpEndCenterPoint;
// 排除小人所在的位置的整个柱状区域检测,为了排除某些特定情况的干扰.
Rectangle rectangle = new Rectangle((int) (startCenterPoint.getX() - lastShapeMinMax / 2), 0, lastShapeMinMax,
(int) startCenterPoint.getY());
Color lastColor = bgColor;
for (int y = bufferedImage.getHeight() / 3; y < startCenterPoint.y; y++) {
for (int x = 10; x < bufferedImage.getWidth(); x++) {
if (rectangle.contains(x, y)) {
continue;
}
Color newColor = new Color(bufferedImage.getRGB(x, y));
if ((Math.abs(newColor.getRed() - lastColor.getRed())
+ Math.abs(newColor.getBlue() - lastColor.getBlue())
+ Math.abs(newColor.getGreen() - lastColor.getGreen()) >= 24)
|| (Math.abs(newColor.getRed() - lastColor.getRed()) >= 12
|| Math.abs(newColor.getBlue() - lastColor.getBlue()) >= 12
|| Math.abs(newColor.getGreen() - lastColor.getGreen()) >= 12)) {
// System.out.println("y = " + y + " x = " + x);
tmpStartCenterPoint = findStartCenterPoint(bufferedImage, x, y);
// System.out.println(tmpStartCenterPoint);
tmpEndCenterPoint = findEndCenterPoint(bufferedImage, tmpStartCenterPoint);
return new Point(tmpStartCenterPoint.x, (tmpEndCenterPoint.y + tmpStartCenterPoint.y) / 2);
}
lastColor = newColor;
}
}
return null;
}
/**
* 查找新方块/圆的有效结束最低位置
*
* @param bufferedImage
* @param tmpStartCenterPoint
* @return
*/
private static Point findEndCenterPoint(BufferedImage bufferedImage, Point tmpStartCenterPoint) {
Color startColor = new Color(bufferedImage.getRGB(tmpStartCenterPoint.x, tmpStartCenterPoint.y));
Color lastColor = startColor;
int centX = tmpStartCenterPoint.x, centY = tmpStartCenterPoint.y;
for (int i = tmpStartCenterPoint.y; i < bufferedImage.getHeight() && i < startCenterPoint.y - 10; i++) {
// -2是为了避开正方体的右边墙壁的影响
Color newColor = new Color(bufferedImage.getRGB(tmpStartCenterPoint.x, i));
if (Math.abs(newColor.getRed() - lastColor.getRed()) <= 8
&& Math.abs(newColor.getGreen() - lastColor.getGreen()) <= 8
&& Math.abs(newColor.getBlue() - lastColor.getBlue()) <= 8) {
centY = i;
}
}
if (centY - tmpStartCenterPoint.y < ScreenAdapter.getMinShapeHeight()) {
centY = centY + ScreenAdapter.getMinShapeHeight();
}
if (centY - tmpStartCenterPoint.y > ScreenAdapter.getMaxShapeHeight()) {
centY = tmpStartCenterPoint.y + ScreenAdapter.getMaxShapeHeight();
}
if (JumpPerfectControl.needMis()) {
centY -= 10;
}
return new Point(centX, centY);
}
// 查找下一个方块的最高点的中点
private static Point findStartCenterPoint(BufferedImage bufferedImage, int x, int y) {
Color lastColor = new Color(bufferedImage.getRGB(x - 1, y));
int centX = x, centY = y;
for (int i = x; i < bufferedImage.getWidth(); i++) {
Color newColor = new Color(bufferedImage.getRGB(i, y));
if ((Math.abs(newColor.getRed() - lastColor.getRed()) + Math.abs(newColor.getBlue() - lastColor.getBlue())
+ Math.abs(newColor.getGreen() - lastColor.getGreen()) >= 24)
|| (Math.abs(newColor.getRed() - lastColor.getRed()) >= 12
|| Math.abs(newColor.getBlue() - lastColor.getBlue()) >= 12
|| Math.abs(newColor.getGreen() - lastColor.getGreen()) >= 12)) {
centX = x + (i - x) / 2;
} else {
break;
}
}
return new Point(centX, centY);
}
private static boolean like(Color a, Color b) {
return !((Math.abs(a.getRed() - b.getRed()) + Math.abs(a.getBlue() - b.getBlue())
+ Math.abs(a.getGreen() - b.getGreen()) >= 24)
|| (Math.abs(a.getRed() - b.getRed()) >= 12 || Math.abs(a.getBlue() - b.getBlue()) >= 12
|| Math.abs(a.getGreen() - b.getGreen()) >= 12));
}
public static void updateLastShapeMinMax(BufferedImage bufferedImage, Point first, Point second) {
if (first.x < second.y) {
for (int x = second.x; x < bufferedImage.getWidth(); x++) {
Color newColor = new Color(bufferedImage.getRGB(x, second.y));
if (like(newColor, bgColor)) {
lastShapeMinMax = (int) Math.max((x - second.x) * 1.5, lastShapeMinMax);
break;
}
}
} else {
for (int x = second.x; x >= 10; x--) {
Color newColor = new Color(bufferedImage.getRGB(x, second.y));
if (like(newColor, bgColor)) {
lastShapeMinMax = (int) Math.max((second.x - x) * 1.5, lastShapeMinMax);
break;
}
}
}
}
public static void main(String[] args) throws IOException {
// BufferedImage bufferedImage = ImageIO.read(new
// File(Constants.SCREENSHOT_2));
BufferedImage bufferedImage = ImageIO.read(new File("/Users/tangshuai/Desktop/tmp/665_908.png"));
Point point = StartCenterFinder.findStartCenter(bufferedImage);
System.out.println(point);
Point point2 = findEndCenter(bufferedImage, point);
System.out.println(point2);
}
public static String toHexFromColor(Color color) {
String r, g, b;
StringBuilder su = new StringBuilder();
r = Integer.toHexString(color.getRed());
g = Integer.toHexString(color.getGreen());
b = Integer.toHexString(color.getBlue());
r = r.length() == 1 ? "0" + r : r;
g = g.length() == 1 ? "0" + g : g;
b = b.length() == 1 ? "0" + b : b;
r = r.toUpperCase();
g = g.toUpperCase();
b = b.toUpperCase();
su.append("0xFF");
su.append(r);
su.append(g);
su.append(b);
//0xFF0000FF
return su.toString();
}
}
Constants
package com.company.playJumpJumpWithMouse;
/**
* Created by RoyZ on 2017/12/29.
*/
public class Constants {
/**
* adb所在位置
*/
public static final String ADB_PATH = "C:\\Users\\RoyZ\\Desktop\\platform-tools\\adb.exe";
/**
* 截屏文件所在位置
*/
public static final String SCREENSHOT_LOCATION = "C:\\Users\\RoyZ\\Desktop\\untitled\\s.png";
/**
* 窗体显示的图片宽度
*/
public static final int RESIZED_SCREEN_WIDTH = 675;
/**
* 窗体显示的图片高度
*/
public static final int RESIZED_SCREEN_HEIGHT = 1200;
/**
* 在675*1200分辨率下,跳跃蓄力时间与距离像素的比率<br>
* 可根据实际情况自行调整
*/
public static final float RESIZED_DISTANCE_PRESS_TIME_RATIO = 2.175f;
/**
* 截图间隔
*/
public static final int SCREENSHOT_INTERVAL = 3000; // ms
public static final int HDPI = 240;
public static final int XHDPI = 330;
public static final int XXHDPI = 480;
/**
* 手动模式
*/
public static final int MODE_MANUAL = 1;
/**
* 半自动模式,只需要点secondPoint
*/
public static final int MODE_SEMI_AUTO = 2;
/**
* 自动模式
*/
public static final int MODE_AUTO = 3;
}
EndCenterFinder
package com.company.playJumpJumpWithMouse;
import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 找白点,也就是连跳的中心点 Created by tangshuai on 2017/12/29.
*/
public class EndCenterFinder {
// 设定中心点的颜色
static final int red = 0xfa;
static final int green = 0xfa;
static final int blue = 0xfa;
static float scaleX = 1;
public static Point findEndCenter(BufferedImage bufferedImage, Point startCenterPoint) {
int width = bufferedImage.getWidth();
int centerX = 0;
int centerY = 0;
int height = bufferedImage.getHeight() * 2 / 3;
for (int h = bufferedImage.getHeight() / 3; h < height && h < startCenterPoint.y; h++) {
for (int w = 0; w < width; w++) {
int color = bufferedImage.getRGB(w, h);
Color newColor = new Color(color);
if (Math.abs(newColor.getRed() - red) <= 5 && Math.abs(newColor.getGreen() - green) <= 5
&& Math.abs(newColor.getBlue() - blue) <= 5) {
Point endCenter = findWhiteCenter(bufferedImage, w, h, startCenterPoint);
if (endCenter == null) {
return null;
}
if (startCenterPoint.getX() > bufferedImage.getWidth() / 2) {// 在右边,所以如果找到的点也在右边就丢掉
if (endCenter.getX() > startCenterPoint.getX()) {
return new Point(0, -1);
}
} else if (startCenterPoint.getX() < bufferedImage.getWidth() / 2) {
if (endCenter.getX() < startCenterPoint.getX()) {
return new Point(0, -1);
}
}
return endCenter;
}
}
}
return new Point((int) (centerX * scaleX), JumpPerfectControl.needMis() ? centerY - 10 : centerY - 1);
}
static Point findWhiteCenter(BufferedImage bufferedImage, int x, int y, Point startCenterPoint) {
int minX = x, minY = y, maxX = x, maxY = y;
for (int w = x; w < bufferedImage.getWidth(); w++) {
int color = bufferedImage.getRGB(w, y);
Color newColor = new Color(color);
if (Math.abs(newColor.getRed() - red) <= 5 && Math.abs(newColor.getGreen() - green) <= 5
&& Math.abs(newColor.getBlue() - blue) <= 5) {
maxX = x + (w - x) / 2;
} else {
break;
}
}
for (int h = y; h < startCenterPoint.getY(); h++) {
int color = bufferedImage.getRGB(x, h);
Color newColor = new Color(color);
if (Math.abs(newColor.getRed() - red) <= 5 && Math.abs(newColor.getGreen() - green) <= 5
&& Math.abs(newColor.getBlue() - blue) <= 5) {
maxY = h;
}
}
int centerY = minY + (maxY - minY) / 2;
if (maxY - minY < ScreenAdapter.getMinWhiteHeight()) {
return null;
}
return new Point((int) (maxX * scaleX), (int) ((centerY)));
}
public static void main(String[] args) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File("/Users/tangshuai/Desktop/tmp/665_908.png"));
Point point = StartCenterFinder.findStartCenter(bufferedImage);
System.out.println(point);
Point point2 = findEndCenter(bufferedImage, point);
System.out.println(point2);
}
}
JumpPerfectControl
package com.company.playJumpJumpWithMouse;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 连跳次数随机偏移控制
* Created by tangshuai on 2018/1/2.
*/
public class JumpPerfectControl {
private static AtomicInteger jumpCouter = new AtomicInteger(0);
private static int randomMagic = 10;
public static boolean random = false;
public static boolean needMis() {
return random && jumpCouter.get() % randomMagic == 0;
}
public static void jumpNext() {
int counter = jumpCouter.incrementAndGet();
if (random && counter % randomMagic == 0) {
randomMagic = 10 + new Random().nextInt(20);
jumpCouter.set(0);
}
}
}
ScreenAdapter
package com.company.playJumpJumpWithMouse;
/**
* Created by tangshuai on 2018/1/2.
*/
public class ScreenAdapter {
static final int[] centers_xhdpi = new int[]{
-13948087, -13948087, -13948087, -13948087, -13947830, -13882036, -13816755, -13816755, -13750960, -13750960,
-13684910, -13684653, -13618603, -13553065, -13552808, -13487014, -13420964, -13420964, -13420964, -13420706,
-13420192, -13354656, -13158303, -13158303, -13223582, -13157789, -13026973, -13026973, -13092509, -13157789,
-13092509, -13026973, -13092510, -13158302, -13092766, -13026973, -13026973, -13026973, -13026973, -13026973,
-13026973, -13092766, -13158303, -13158303, -13092510, -13092510, -13026973, -13092510, -13158303, -13026973,
-13026973, -13092766, -13092510, -13026973, -13092766, -13158303, -13158303, -13092767, -13027489, -13027489,
-13027489, -13027489, -13027489, -13027489, -13027490, -13027747, -13027749, -13027496, -13027496, -12961961,
-12962219, -12962218, -12896682, -12830381, -12830381};
static final int[] centers_xxhdpi = new int[]{
-13948087, -13948087, -13948087, -13947830, -13948087, -13948087, -13948087, -13947830, -13816755, -13816755,
-13750960, -13684910, -13618603, -13553065, -13816755, -13816755, -13750960, -13684910, -13618603, -13553065,
-13487014, -13420964, -13420964, -13420706, -13354656, -13158303, -13487014, -13420964, -13420964, -13420706,
-13354656, -13158303, -13223582, -13157789, -13026973, -13092509, -13092509, -13026973, -13223582, -13157789,
-13026973, -13092509, -13092509, -13026973, -13158302, -13092766, -13026973, -13026973, -13026973, -13026973,
-13158302, -13092766, -13026973, -13026973, -13026973, -13026973, -13158303, -13158303, -13092510, -13026973,
-13158303, -13026973, -13158303, -13158303, -13092510, -13026973, -13158303, -13026973, -13092766, -13092510,
-13092766, -13158303, -13092767, -13027489, -13092766, -13092510, -13092766, -13158303, -13092767, -13027489,
-13027489, -13027489, -13027489, -13027490, -13027749, -13027496, -13027489, -13027489, -13027489, -13027490,
-13027749, -13027496, -12961961, -12962219, -12896682, -12830381, -12961961, -12962219, -12896682, -12830381};
static final int[] centers_hdpi = new int[]{
-13948087, -13948087, -13948087, -13947830, -13816755, -13816755, -13750960, -13684910, -13618603, -13553065,
-13487014, -13420964, -13420964, -13420706, -13354656, -13158303, -13223582, -13157789, -13026973, -13092509,
-13092509, -13026973, -13158302, -13092766, -13026973, -13026973, -13026973, -13026973, -13158303, -13158303,
-13092510, -13026973, -13158303, -13026973, -13092766, -13092510, -13092766, -13158303, -13092767, -13027489,
-13027489, -13027489, -13027489, -13027490, -13027749, -13027496, -12961961, -12962219, -12896682, -12830381};
public static int SCREEN_DPI = Constants.XHDPI;
public static int getShapeMinWidth() {
if (SCREEN_DPI > Constants.XXHDPI) {
return 200;
} else if (SCREEN_DPI > Constants.XHDPI) {
return 150;
} else {
return 100;
}
}
public static int[] getCenterArrays() {
if (SCREEN_DPI > Constants.XXHDPI) {
return centers_xxhdpi;
} else if (SCREEN_DPI > Constants.XHDPI) {
return centers_xhdpi;
} else {
return centers_hdpi;
}
}
public static int getBabyWidth() {
if (SCREEN_DPI > Constants.XXHDPI) {
return 100;
} else if (SCREEN_DPI > Constants.XHDPI) {
return 75;
} else {
return 50;
}
}
public static int getMaxShapeHeight() {
if (SCREEN_DPI > Constants.XXHDPI) {
return 345;
} else if (SCREEN_DPI > Constants.XHDPI) {
return 230;
} else {
return 173;
}
}
public static int getMinShapeHeight() {
if (SCREEN_DPI > Constants.XXHDPI) {
return 52;
} else if (SCREEN_DPI > Constants.XHDPI) {
return 40;
} else {
return 26;
}
}
public static int getMinWhiteHeight(){
if (SCREEN_DPI > Constants.XXHDPI) {
return 24;
} else if (SCREEN_DPI > Constants.XHDPI) {
return 18;
} else {
return 12;
}
}
}
StartCenterFinder
package com.company.playJumpJumpWithMouse;
import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
/**
* 找小人的底盘中心点. Created by tangshuai on 2017/12/29.
*/
public class StartCenterFinder {
static int[] centers = ScreenAdapter.getCenterArrays();
public static Point findStartCenter(BufferedImage bufferedImage) {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
int centerX = 0;
int centerY = 0;
for (int h = 0; h < height; h++)
for (int w = 0; w < width; w++) {
int color = bufferedImage.getRGB(w, h);
if (color == centers[0]) {
if (checkIsCenter(bufferedImage, h, w)) {
centerX = w + ScreenAdapter.getBabyWidth() / 2;
centerY = h;
return new Point(centerX, (centerY + 2));
}
}
}
return new Point(0, -1);
}
private static boolean checkIsCenter(BufferedImage bufferedImage, int h, int w) {
for (int i = w; i < w + 50; i++) {
int color = bufferedImage.getRGB(i, h);
Color centerColor = new Color(centers[i - w]);
Color newColor = new Color(color);
if (Math.abs(newColor.getRed() - centerColor.getRed()) > 5
|| Math.abs(newColor.getGreen() - centerColor.getGreen()) > 5
|| Math.abs(newColor.getBlue() - centerColor.getBlue()) > 5) {
return false;
}
}
return true;
}
}