微信跳一跳辅助的java具体实现代码,供大家参考,具体内容如下
1.参考知乎教你用python来玩微信跳一跳,鉴于本人python一直都是半吊子水平,之前打算用python刷分,可无奈安装python环境各种模块缺失,报错不停,于是乎,使用java重新实现了一下。
2.环境配置及相关说明:
1)、windows系统,本人win10
2)、ava环境安装,jdk7以上即可
3)、安卓手机一部、数据线一条
4)、电脑安装adb驱动,连接安卓手机,同时打开usb调试模式
5)、打开微信小程序的跳一跳游戏,java程序跑起来,具体代码往下看
6)、本人所用为魅蓝note2安卓手机,屏幕 分辨率1920x1080,不同型号的手机,可能需要调整相关参数,具体看代码注释
7)、增加了刷分失败后游戏自动重新开局功能
8)、娱乐而已,不要较真,据说微信官方已经关注,分数太高可能会被清零,哈哈
3、废话不多说,上代码:
package com.yihusitian.gamehelper; import java.awt.image.bufferedimage; import java.io.bufferedreader; import java.io.file; import java.io.ioexception; import java.io.inputstreamreader; import java.util.arrays; import java.util.concurrent.timeunit; import javax.imageio.imageio; /** * 参考知乎 * * @link <a href="https://zhuanlan.zhihu.com/p/32452473" rel="external nofollow" rel="external nofollow" target="_blank">https://zhuanlan.zhihu.com/p/32452473</a> * * 跳一跳辅助 * * @author leeho */ public class jumpjumphelper { private static final string image_name = "current.png"; private static final string store_dir = "d:/jump_screencapture"; //数量 private static final int imagelengthlength = 5; //存放图片的大小 private static final long[] imagelength = new long[imagelengthlength]; private final rgbinfo rgbinfo = new rgbinfo(); private final string[] adb_screen_capture_cmds = { "adb shell screencap -p /sdcard/" + image_name, "adb pull /sdcard/current.png " + store_dir }; //截屏中游戏分数显示区域最下方的y坐标,300是 1920x1080的值,根据实际情况修改 private final int gamescorebottomy = 300; //按压的时间系数,可根据具体情况适当调节 private final double presstimecoefficient = 1.35; //按压的起始点坐标,也是再来一局的起始点坐标 private final int swipex = 550; private final int swipey = 1580; //二分之一的棋子底座高度 private final int halfbaseboardheight = 20; //棋子的宽度,从截屏中量取,自行调节 private final int halmabodywidth = 74; //游戏截屏里的两个跳板的中点坐标,主要用来计算角度,可依据实际的截屏计算,计算xy的比例 private final int boardx1 = 813; private final int boardy1 = 1122; private final int boardx2 = 310; private final int boardy2 = 813; /** * 获取跳棋以及下一块跳板的中心坐标 * * @return * @author leeho * @throws ioexception * @update 2017年12月31日 下午12:18:22 */ private int[] gethalmaandboardxyvalue(file currentimage) throws ioexception { bufferedimage bufferedimage = imageio.read(currentimage); int width = bufferedimage.getwidth(); int height = bufferedimage.getheight(); system.out.println("宽度:" + width + ",高度:" + height); int halmaxsum = 0; int halmaxcount = 0; int halmaymax = 0; int boardx = 0; int boardy = 0; //从截屏从上往下逐行遍历像素点,以棋子颜色作为位置识别的依据,最终取出棋子颜色最低行所有像素点的平均值,即计算出棋子所在的坐标 for (int y = gamescorebottomy; y < height; y++) { for (int x = 0; x < width; x++) { processrgbinfo(bufferedimage, x, y); int rvalue = this.rgbinfo.getrvalue(); int gvalue = this.rgbinfo.getgvalue(); int bvalue = this.rgbinfo.getbvalue(); //根据rgb的颜色来识别棋子的位置, if (rvalue > 50 && rvalue < 60 && gvalue > 53 && gvalue < 63 && bvalue > 95 && bvalue < 110) { halmaxsum += x; halmaxcount++; //棋子底行的y坐标值 halmaymax = y > halmaymax ? y : halmaymax; } } } if (halmaxsum != 0 && halmaxcount != 0) { //棋子底行的x坐标值 int halmax = halmaxsum / halmaxcount; //上移棋子底盘高度的一半 int halmay = halmaymax - halfbaseboardheight; //从gamescorebottomy开始 for (int y = gamescorebottomy; y < height; y++) { processrgbinfo(bufferedimage, 0, y); int lastpixelr = this.rgbinfo.getrvalue(); int lastpixelg = this.rgbinfo.getgvalue(); int lastpixelb = this.rgbinfo.getbvalue(); //只要计算出来的boardx的值大于0,就表示下个跳板的中心坐标x值取到了。 if (boardx > 0) { break; } int boardxsum = 0; int boardxcount = 0; for (int x = 0; x < width; x++) { processrgbinfo(bufferedimage, x, y); int pixelr = this.rgbinfo.getrvalue(); int pixelg = this.rgbinfo.getgvalue(); int pixelb = this.rgbinfo.getbvalue(); //处理棋子头部比下一个跳板还高的情况 if (math.abs(x - halmax) < halmabodywidth) { continue; } //从上往下逐行扫描至下一个跳板的顶点位置,下个跳板可能为圆形,也可能为方框,取多个点,求平均值 if ((math.abs(pixelr - lastpixelr) + math.abs(pixelg - lastpixelg) + math.abs(pixelb - lastpixelb)) > 10) { boardxsum += x; boardxcount++; } } if (boardxsum > 0) { boardx = boardxsum / boardxcount; } } //按实际的角度来算,找到接近下一个 board 中心的坐标 boardy = (int) (halmay - math.abs(boardx - halmax) * math.abs(boardy1 - boardy2) / math.abs(boardx1 - boardx2)); if (boardx > 0 && boardy > 0) { int[] result = new int[4]; //棋子的x坐标 result[0] = halmax; //棋子的y坐标 result[1] = halmay; //下一块跳板的x坐标 result[2] = boardx; //下一块跳板的y坐标 result[3] = boardy; return result; } } return null; } /** * 执行命令 * * @param command * @author leeho * @update 2017年12月31日 下午12:13:39 */ private void executecommand(string command) { process process = null; try { process = runtime.getruntime().exec(command); system.out.println("exec command start: " + command); process.waitfor(); bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(process.geterrorstream())); string line = bufferedreader.readline(); if (line != null) { system.out.println(line); } system.out.println("exec command end: " + command); } catch (exception e) { e.printstacktrace(); } finally { if (process != null) { process.destroy(); } } } /** * adb获取安卓截屏 * * @author leeho * @update 2017年12月31日 下午12:11:42 */ private void executeadbcapturecommands() { for (string command : adb_screen_capture_cmds) { executecommand(command); } } /** * 跳一下 * * @param distance * @author leeho * @update 2017年12月31日 下午12:23:19 */ private void dojump(double distance) { system.out.println("distance: " + distance); //计算按压时间,最小200毫秒 int presstime = (int) math.max(distance * presstimecoefficient, 200); system.out.println("presstime: " + presstime); //执行按压操作 string command = string.format("adb shell input swipe %s %s %s %s %s", swipex, swipey, swipex, swipey, presstime); system.out.println(command); executecommand(command); } /** * 再来一局 * * @author leeho * @update 2017年12月31日 下午12:47:06 */ private void replaygame() { string command = string.format("adb shell input tap %s %s", swipex, swipey); executecommand(command); } /** * 计算跳跃的距离,也即两个点之间的距离 * * @param halmax * @param halmay * @param boardx * @param boardy * @return * @author leeho * @update 2017年12月31日 下午12:27:30 */ private double computejumpdistance(int halmax, int halmay, int boardx, int boardy) { return math.sqrt(math.pow(math.abs(boardx - halmax), 2) + math.pow(math.abs(boardy - halmay), 2)); } public static void main(string[] args) { try { file storedir = new file(store_dir); if (!storedir.exists()) { boolean flag = storedir.mkdir(); if (!flag) { system.err.println("创建图片存储目录失败"); return; } } jumpjumphelper jumpjumphelper = new jumpjumphelper(); //执行次数 int executecount = 0; for (;;) { //执行adb命令,获取安卓截屏 jumpjumphelper.executeadbcapturecommands(); file currentimage = new file(store_dir, image_name); if (!currentimage.exists()) { system.out.println("图片不存在"); continue; } long length = currentimage.length(); imagelength[executecount % imagelengthlength] = length; //查看是否需要重新开局 jumpjumphelper.checkdoreplay(); executecount++; system.out.println("当前第" + executecount + "次执行!"); //获取跳棋和底板的中心坐标 int[] result = jumpjumphelper.gethalmaandboardxyvalue(currentimage); if (result == null) { system.out.println("the result of method gethalmaandboardxyvalue is null!"); continue; } int halmax = result[0]; int halmay = result[1]; int boardx = result[2]; int boardy = result[3]; system.out.println("halmax: " + halmax + ", halmay: " + halmay + ", boardx: " + boardx + ", boardy: " + boardy); //计算跳跃的距离 double jumpdistance = jumpjumphelper.computejumpdistance(halmax, halmay, boardx, boardy); jumpjumphelper.dojump(jumpdistance); //每次停留2.5秒 timeunit.milliseconds.sleep(2500); } } catch (exception e) { e.printstacktrace(); } } /** * 检查是否需要重新开局 * * @author leeho * @update 2017年12月31日 下午1:39:18 */ private void checkdoreplay() { if (imagelength[0] > 0 && imagelength[0] == imagelength[1] && imagelength[1] == imagelength[2] && imagelength[2] == imagelength[3] && imagelength[3] == imagelength[4]) { //此时表示已经连续5次图片大小一样了,可知当前屏幕处于再来一局 arrays.fill(imagelength, 0); //模拟点击再来一局按钮重新开局 replaygame(); } } /** * 获取指定坐标的rgb值 * * @param bufferedimage * @param x * @param y * @author leeho * @update 2017年12月31日 下午12:12:43 */ private void processrgbinfo(bufferedimage bufferedimage, int x, int y) { this.rgbinfo.reset(); int pixel = bufferedimage.getrgb(x, y); //转换为rgb数字 this.rgbinfo.setrvalue((pixel & 0xff0000) >> 16); this.rgbinfo.setgvalue((pixel & 0xff00) >> 8); this.rgbinfo.setbvalue((pixel & 0xff)); } class rgbinfo { private int rvalue; private int gvalue; private int bvalue; public int getrvalue() { return rvalue; } public void setrvalue(int rvalue) { rvalue = rvalue; } public int getgvalue() { return gvalue; } public void setgvalue(int gvalue) { gvalue = gvalue; } public int getbvalue() { return bvalue; } public void setbvalue(int bvalue) { bvalue = bvalue; } public void reset() { this.rvalue = 0; this.gvalue = 0; this.bvalue = 0; } } }
更多内容大家可以参考专题《微信跳一跳》进行学习。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。
如对本文有疑问, 点击进行留言回复!!
VideoStudio多相机编辑器怎么用? VideoStudio多相机的使用方法
网友评论