思路:
1.截取安卓模擬器對應窗口的圖像內容
2.處理圖像找出起點和終點
3.計算距離
4.鼠標事件
經過:
1.一開始想先將截圖儲存在某個路徑,在用文件流讀取那個圖片,對圖片進行處理。之后發現直接對BufferedImage里的內容進行處理更方便。
2.在計算距離的時候遇到了一點困難,用了取巧的辦法。即找到新台階中心點的橫坐標,找到小人起跳點的橫坐標,相減求得橫向距離。手測三角形的長邊和底邊的比例,乘一下求出距離。
3.距離和按鍵時間的關系一開始以為是線性關系,后來發現好像並不是這樣,想利用神經網絡來擬合一下,還在思考實現方法。
結果:
1.能夠自動地在安卓模擬器上刷到600+分,遇到圓形小台階不是很穩,會掉下去。
2.在遇到圓形台階時距離的測算會遇到一點問題,應該是三角形的形狀變了,導致距離計算不准確,很難刷到高分。
待改進:
1.擬合距離-時間公式。
2.找到測距離更准確的辦法。
窗口截取:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.image.*;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
public class ScreenCut {
private static int startX = 0;
private static int startY = 0;
private static int width = 0;
private static int height = 0;
private static String path = "";
private static int[][] data = null;
public static void main(String[] args)
{
ScreenCut();
}
public static int[][] ScreenCut()
{
startX = 7;
startY = 45;
width = 540;
height = 960;
path = "C:\\Users\\Administrator\\Desktop\\Jump1.bmp";
data = getScreenCutData(startX, startY, width, height);
storeAsBmp(path,data);
return data;
}
public static int[][] getScreenCutData(int startX, int startY, int width, int height)
{
//time = caledTime;
//BufferedImage screenCut = new BufferedImage();
int[][] data = new int[width][height];
try
{
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(startX,startY,width,height);
BufferedImage screenCut = robot.createScreenCapture(screenRect);
//System.out.println(screenCut);
for(int i = 0; i < width; i++)
{
for(int j = 0; j < height; j++)
{
data[i][j] = screenCut.getRGB(i, j);
}
}
//screenCut.getRGB(0, 0, 540, 960, data, 0, 0);
}
catch(AWTException e)
{
System.out.println(e);
}
/*
for(int i = 0; i < width; i++)
{
for(int j = 0; j < height; j++)
{
System.out.println("i = " + i + "j = " + j + data[i][j]);
}
}
*/
return data;
//int r = data[539][958] >> 16 & 0xFF;
//int g = data[539][958] >> 8 & 0xFF;
//int b = data[539][958] & 0xFF;
//System.out.println(r + " " + g + " " + b);
}
}
處理圖像及計算距離:
import java.util.*;
import java.awt.Graphics;
import java.io.*;
public class PicDeal
{
//public static void main(String args[])
//{
//String src = "C:\\Users\\Administrator\\Desktop\\Jump1.bmp";
//String srcout = "C:\\Users\\Administrator\\Desktop\\Jumpout.bmp";
//double distance = BmpCalTime(src,srcout);
//}
//
public static double screenCutDataCalTime(int[][] data)
{
int screenCutWidth = data.length;
int screenCutHeight = data[0].length;
int[][] r = null;
int[][] g = null;
int[][] b = null;
int nTopX = 0;
int nTopY = 0;
int oX = 0;
int oY = 0;
double distance = 0;
double ratioDistance = 0;
double allDistance = 0;
System.out.println("pic size: " + screenCutWidth + " " + screenCutHeight);
allDistance = screenCutHeight;
//
//System.out.println(skipnum);
r = new int[screenCutHeight][screenCutWidth];
g = new int[screenCutHeight][screenCutWidth];
b = new int[screenCutHeight][screenCutWidth];
int flag = 1;
boolean flag2 = false;
for(int i = 0; i < screenCutHeight; i++)
{
for(int j = 0; j < screenCutWidth; j++)
{
//int r = data[539][958] >> 16 & 0xFF;
//int g = data[539][958] >> 8 & 0xFF;
//int b = data[539][958] & 0xFF;
//System.out.println(r + " " + g + " " + b);
int red = data[j][i] >> 16 & 0xFF;
int green = data[j][i] >> 8 & 0xFF;
int blue = data[j][i] & 0xFF;
//if(476 > i && i > 474 && j < 183 && j > 181)
//{
//System.out.println(red +" " + green +" "+ blue);
//}
if(i > 300 && j > 10 && j < screenCutWidth - 10)
{
if( flag == 1 && (Math.abs(red-r[i][j-1]) + Math.abs(green-g[i][j-1]) + Math.abs(blue-b[i][j-1])) > 20 )
{
nTopX = j;
nTopY = i + 1;
flag = 2;
System.out.println("new location: " + nTopX + " " + nTopY);
}
if( flag2 == false && red > 50 && red < 54 && green > 51 && green < 55 && blue > 58 && blue < 62)
{
oX = j;
oY = i + 88;
flag2 = true;
System.out.println("old location: " + oX + " " + oY);
}
}
r[i][j] = red;
g[i][j] = green;
b[i][j] = blue;
}
}
distance = 1.1557 * Math.abs(oX - nTopX);
ratioDistance = distance/allDistance;
System.out.println("distance = " + distance);
System.out.println("allDistance = " + allDistance);
System.out.println("ratioDistance = " + ratioDistance);
return ratioDistance;
}
private static int byte2Int(byte[] b)
{
int num=(b[3]&0xff)<<24|(b[2]&0xff)<<16|(b[1]&0xff)<<8|(b[0]&0xff);
return num;
}
}
鼠標事件:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.*;
public class mouseClick {
private static int time = 0;
public static void clickAndHode(int caledTime)
{
time = caledTime;
if(time <100)
{
time = 300;
}
//BufferedImage screenCut = new BufferedImage();
try
{
Robot robot = new Robot();
robot.mouseMove(300, 300);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(time);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.delay(1500);
}
catch(AWTException e)
{
System.out.println(e);
}
}
}main函數:
public class JumpCheat {
public static void main(String[] args)
{
//String src = "C:\\Users\\Administrator\\Desktop\\Jump1.bmp";
for(int lop = 0; lop < 100; lop ++)
{
PicDeal picDeal = new PicDeal();
mouseClick mClick = new mouseClick();
ScreenCut sCut = new ScreenCut();
int[][] data = sCut.ScreenCut();
//double caledTime = picDeal.BmpCalTime(src);
double caledTime = picDeal.screenCutDataCalTime(data);
int holdTime = (int) (caledTime * 2675);
mClick.clickAndHode(holdTime);
}
}
}
github:https://github.com/stpraha/JumpCheat
本文介绍了一种基于图像处理的“跳一跳”自动刷分方法,通过识别游戏元素位置来计算跳跃距离并实现自动操作。
1487

被折叠的 条评论
为什么被折叠?



