JAVA实现跳一跳辅助程序之虎啸龙吟

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: 前序:今天有幸,看到2位博主的文章,在此表示感谢。自己也动手实现了一下。实现原理 请参考博主 https://www.cnblogs.com/dongkuo/p/8285162.html  另感谢博主 http://www.cnblogs.com/litblank/p/8267526.html  提供的基础部分代码,免去了我自己再写一边的麻烦。

前序:

今天有幸,看到2位博主的文章,在此表示感谢。自己也动手实现了一下。

实现原理 请参考博主 https://www.cnblogs.com/dongkuo/p/8285162.html  

另感谢博主 http://www.cnblogs.com/litblank/p/8267526.html  提供的基础部分代码,免去了我自己再写一边的麻烦。

由于第一篇是python 实现,楼主是JAVA出生,想通过java实现,刚好在评论中看到了 第二位博主的java实现连接,但是自己用博主的代码,测试发现效果并不理想,获取的位置点不对。。。可能是打开方式不对~~~0.0

遂根据第一位博主的思路,重新实现了一下,亲测3张图,基本都是ok 的,下面就看看代码部分的实现

代码实现:

  1 package code;
  2 
  3 import java.awt.AWTException;
  4 import java.awt.Graphics2D;
  5 import java.awt.Transparency;
  6 import java.awt.image.BufferedImage;
  7 import java.io.File;
  8 import java.io.IOException;
  9 import java.io.InputStreamReader;
 10 import java.io.LineNumberReader;
 11 import java.util.Map;
 12 import java.util.Map.Entry;
 13 import java.util.TreeMap;
 14 import javax.imageio.ImageIO;
 15 
 16 public class Jump {
 17     //存放图片的路径
 18     static String file1 = "C:\\Users\\JJJ\\Desktop\\jump3.jpg";
 19     //始 扫描行,针对不同的手机分辨率可能不一样,需要修改,此处建议手工测量下坐上角跳跃步数的数字位置,估算出起始行  楼主的手机是se 像素是 1156*640
 20     static int start_y = 200;
 21     static boolean istest = false;
 22     static int background_x = 10;   //定义默认的背景色,一定是不会出现其他物体的位置
 23     static int background_y = 580;
 24     
 25     public static void main(String[] args) throws AWTException, InterruptedException, IOException {
 26          istest = true;
 27          
 28        
 29             System.out.println("开始:计算" + file1);
 30             if (istest) {
 31                 cmd_java("cmd /c start adb.bat ", "C:\\Users\\JJJ\\Downloads\\cofface_adb\\cofface_adb_windows_v5.1");//批处理文件
 32             }
 33             BufferedImage bi = (BufferedImage) ImageIO.read(new File(file1));
 34             Map<Integer, Integer> treemap = new TreeMap<Integer, Integer>();
 35             // 获取图像的宽度和高度
 36             int width = bi.getWidth();
 37             int height = bi.getHeight();
 38             //小人中心点坐标 
 39             int poix = 0;
 40             int poiy = 0;
 41             //目标物体的最顶点X轴 和左边或右边的Y轴
 42             int mubiaopoix1 = 0;
 43             int mubiaopoiy2 = 0;
 44             //目标中心点坐标
 45             int mubiaopoix = 0;
 46             int mubiaopoiy = 0;
 47             BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 48             Graphics2D g2d = img.createGraphics();
 49             // 设置画布为透明
 50             img = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
 51            // 扫描图片,获取小人的底部中心坐标
 52             for (int i = start_y; i < height; i++) {
 53                 for (int j = 0; j < width; j++) {// 行扫描
 54                     int dip = bi.getRGB(j, i);
 55                     int p = dip;
 56                     int red = 0xff & (p >> 16);
 57                     int green = 0xff & (p >> 8);
 58                     int blue = 0xff & p;
 59                     // 目标人图形
 60                     if (i < (height / 1.5)) 
 61                     {
 62                         if ((red > 53 && red < 59) && (green > 57 && green < 61) && (blue > 59 && blue < 103)) 
 63                         {  // 获取小人坐标,从中取除Y值最大的一个
 64                             treemap.put(i, j);
 65                         }
 66                     }
 67                 }
 68             }
 69             //获取最后的小人底部坐标 ,此处使用treemap 直接排好序,循环获取Y轴值最大的一个
 70            for (Entry<Integer, Integer> entry : treemap.entrySet())
 71            {
 72                poiy = entry.getKey();
 73                poix = entry.getValue();
 74            }
 75            //开始扫描目标物体的最上和最左坐标 ,扫描的Y最大值为当前小人的Y值
 76            treemap.clear(); //清除前面的记录,准备存放目标物体的坐标
 77            RGB rgb = null;
 78            boolean frist = true;
 79            RGB rgb_0 = pixToRgb(bi, background_x, background_y);  //默认的背景色
 80            for (int y = start_y; y < poiy; y++) { 
 81                int x = 0;
 82                if (poix < width /2) //此处特别说明下,如果小人的坐标在整个屏幕的左边,则目标物体一定在右边,遂起始x轴从小人之后开始加20开始循环,反之则不用
 83                {
 84                    x  = poix + 20; 
 85                }
 86                else
 87                {
 88                    x  = 20; 
 89                }
 90                for (; x < width - 20; x++) {// 行扫描
 91                    int dip = bi.getRGB(x, y);
 92                    int p = dip;
 93                    RGB rgb_1 = pixToRgb(bi, x, y);
 94                    if(frist && rgbCz(rgb_0,rgb_1,10))  //如果不相同则说明找到了第一个点
 95                    {
 96                        mubiaopoix1 = x;
 97                        rgb = rgb_1;
 98                        frist = false;
 99                        continue;
100                    }
101                    if (!frist && rgbBcz(rgb,rgb_1,10))
102                    {
103                        treemap.put(x, y);  //存放所有当前台面的像素点坐标,然后从中选出X值最小的一个,
104                    }
105                }
106            }
107            //获取目标物体的坐标,如果是在右半边,则获取最后一个值的Y轴,如果是在左边,则获取第一个
108            if (poix > width / 2)
109            {
110                for (Entry<Integer, Integer> entry : treemap.entrySet())
111                {
112                    mubiaopoiy2 = entry.getValue();
113                    break;
114                }
115            }
116            else
117            {
118                for (Entry<Integer, Integer> entry : treemap.entrySet())
119                {
120                    mubiaopoiy2 = entry.getValue();
121                }
122            }
123            //通过获取的2个点坐标计算出中心点位置
124            mubiaopoix = mubiaopoix1;
125            mubiaopoiy = mubiaopoiy2;
126            //计算 小人与目标人物的距离
127            int total = (mubiaopoix - poix) * (mubiaopoix - poix) + (mubiaopoiy - poiy) * (mubiaopoiy - poiy);
128            double length = (double) Math.sqrt(total);
129            double time =  length * 1.35; //时间系数
130            System.out.println("小人的坐标为:" + poix + "," + poiy);
131            System.out.println("目标物体的坐标为:" + mubiaopoix + "," + mubiaopoiy);
132            System.out.println("需要按压屏幕的时间为:" + time + "毫秒");
133         }
134 153 
154     static InputStreamReader ir = null;
155     static LineNumberReader input = null;
156 
157     public static void cmd_java(String cmd) throws IOException {
158         Process process = Runtime.getRuntime().exec(cmd, null, new File("C:\\Users\\chenyd\\adb"));
159         ir = new InputStreamReader(process.getInputStream());
160         input = new LineNumberReader(ir);
161         while (input.readLine() != null) {
162         }
163         input.close();
164         ir.close();
165     }
166 
167     public static void cmd_java(String cmd, String url) throws IOException {
168         Process process = Runtime.getRuntime().exec(cmd, null, new File(url));
169         ir = new InputStreamReader(process.getInputStream());
170         input = new LineNumberReader(ir);
171         while (input.readLine() != null) {
172             System.out.println(11);
173         }
174         input.close();
175         ir.close();
176     }
177 
178     /**
179      * 颜色的差值不在范围内
180      */
181     public static boolean rgbCz(RGB rgb_1, RGB rgb_2, int fd_rgb) {
182         if (Math.abs(rgb_1.getRed() - rgb_2.getRed()) > fd_rgb && Math.abs(rgb_1.getGreen() - rgb_2.getGreen()) > fd_rgb
183                 && Math.abs(rgb_1.getBlue() - rgb_2.getBlue()) > fd_rgb) {
184             return true;
185         }
186         return false;
187     }
188     
189     /**
190      * 颜色的差值在范围内
191      */
192     public static boolean rgbBcz(RGB rgb_1, RGB rgb_2, int fd_rgb) {
193         if (Math.abs(rgb_1.getRed() - rgb_2.getRed()) < fd_rgb && Math.abs(rgb_1.getGreen() - rgb_2.getGreen()) < fd_rgb
194                 &&  Math.abs(rgb_1.getBlue() - rgb_2.getBlue()) < fd_rgb) {
195             return true;
196         }
197         return false;
198     }
199 
200     public static RGB pixToRgb(BufferedImage bi, int j, int i) {
201         try {
202             int dip = bi.getRGB(j, i);
203             int p = dip;
204             int red = 0xff & (p >> 16);
205             int green = 0xff & (p >> 8);
206             int blue = 0xff & p;
207             return new RGB(j, i, red, green, blue);
208         } catch (Exception e) {
209 
210         }
211         return null;
212     }
213 
214 }
215 
216 class RGB {
217 
218     public RGB() {
219     }
220 
221     public RGB(int x, int y, int red, int green, int blue) {
222         super();
223         X = x;
224         Y = y;
225         this.red = red;
226         this.green = green;
227         this.blue = blue;
228     }
229 
230     public int X;
231     public int Y;
232     public int red;
233     public int green;
234     public int blue;
235 
236     public int getRed() {
237         return red;
238     }
239 
240     public void setRed(int red) {
241         this.red = red;
242     }
243 
244     public int getGreen() {
245         return green;
246     }
247 
248     public void setGreen(int green) {
249         this.green = green;
250     }
251 
252     public int getBlue() {
253         return blue;
254     }
255 
256     public void setBlue(int blue) {
257         this.blue = blue;
258     }
259 
260     public int getX() {
261         return X;
262     }
263 
264     public void setX(int x) {
265         X = x;
266     }
267 
268     public int getY() {
269         return Y;
270     }
271 
272     public void setY(int y) {
273         Y = y;
274     }
275 
276 }

 

由于楼主目前没有安卓设备,还无法带上adb实验,目前只是通过手动截取图片,和测量距离计算了3张,总体比较下来,还算是正确的。

第一张图片

 

计算结果如图:

第二张图片

 计算结果如图:

第三张图片

计算结果如图:

后续再搞个安卓设备试试~

 

give me the ball!
相关实践学习
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
11月前
|
Java 流计算
利用java8 的 CompletableFuture 优化 Flink 程序
本文探讨了Flink使用avatorscript脚本语言时遇到的性能瓶颈,并通过CompletableFuture优化代码,显著提升了Flink的QPS。文中详细介绍了avatorscript的使用方法,包括自定义函数、从Map中取值、使用Java工具类及AviatorScript函数等,帮助读者更好地理解和应用avatorscript。
185 2
利用java8 的 CompletableFuture 优化 Flink 程序
|
12月前
|
XML 存储 JSON
Java程序部署
Java程序部署
|
6月前
|
Java C语言
课时8:Java程序基本概念(标识符与关键字)
课时8介绍Java程序中的标识符与关键字。标识符由字母、数字、下划线和美元符号组成,不能以数字开头且不能使用Java保留字。建议使用有意义的命名,如student_name、age。关键字是特殊标记,如蓝色字体所示。未使用的关键字有goto、const;特殊单词null、true、false不算关键字。JDK1.4后新增assert,JDK1.5后新增enum。
103 4
|
6月前
|
Java 编译器
课时7:Java程序基本概念(注释)
课时7介绍了Java程序中的注释。编程语言有其语法和语义,注释有助于理解代码需求,防止断档。Java支持三类注释:单行(//)、多行(/* */)和文档注释(/** */)。注释不会被编译器编译。范例中展示了如何在代码中使用注释,并强调了注释对项目文档管理的重要性。
|
6月前
|
存储 Java 数据库连接
【YashanDB知识库】Java程序调用存储过程,在提取clob时报YAS-00004
【YashanDB知识库】Java程序调用存储过程,在提取clob时报YAS-00004
|
6月前
|
搜索推荐 Java Android开发
课时146:使用JDT开发Java程序
在 Eclipse 之中提供有 JDT环境可以实现java 程序的开发,下面就通过一些功能进行演示。 项目开发流程
238 0
|
8月前
|
传感器 安全 算法
消防救援支队消防员单兵装备智能养护舱电机驱动java版程序(二)
本文探讨消防救援中智能养护舱电机驱动的Java程序设计,作为系列文章第二部分。通过自动化和智能化手段,智能养护舱提升了装备维护效率与准确性。文章详细介绍了电机驱动模块的设计与实现,包括硬件选型、PID控制策略、安全保护机制及Java程序架构,确保电机精确控制、稳定性和安全性。未来将优化功能并引入智能算法和物联网技术,进一步提升装备维护智能化水平。
|
8月前
|
IDE Java 开发工具
消防救援支队消防员单兵装备智能养护舱点击驱动java版程序(一)
智能消防作战服架通过电机驱动系统提升消防员作业效率和安全性。本文介绍基于Java的电机驱动程序开发,涵盖硬件准备、软件环境搭建及驱动程序实现。重点包括串口通信配置、电机控制类设计与控制逻辑实现,确保电机高效稳定运行。通过正确配置通信协议和串口参数,并添加异常处理机制,保障系统的安全性和可靠性。
|
6月前
|
Java 开发工具
课时5:第一个Java程序
课时5介绍了编写第一个Java程序的步骤,包括创建Hello.java文件、编写“Hello World”代码、编译和运行程序。主要内容有:1) 新建并编辑Hello.java;2) 编译Java源文件生成.class文件;3) 通过命令行解释执行Java程序;4) 解释主方法的作用及信息输出操作。本课强调了类定义、文件命名规则和基本程序结构的重要性,并建议初学者使用记事本编写代码以熟悉基础语法。
|
10月前
|
SQL 安全 Java
Java 异常处理:筑牢程序稳定性的 “安全网”
本文深入探讨Java异常处理,涵盖异常的基础分类、处理机制及最佳实践。从`Error`与`Exception`的区分,到`try-catch-finally`和`throws`的运用,再到自定义异常的设计,全面解析如何有效管理程序中的异常情况,提升代码的健壮性和可维护性。通过实例代码,帮助开发者掌握异常处理技巧,确保程序稳定运行。
160 2

热门文章

最新文章