微信跳一跳辅助的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 https://zhuanlan.zhihu.com/p/32452473

*

* 跳一跳辅助

*

* @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;

}

}

}

更多内容大家可以参考专题《微信跳一跳》进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

微信跳一跳java实现自动跳_微信跳一跳辅助Java代码实现相关推荐

  1. java 试卷自动生成_基于JAVA的试题自动生成系统 - WEB源码|JSP源码/Java|源代码 - 源码中国...

    压缩包 : 试卷自动生成系统.rar 列表 试卷自动生成系统/.classpath 试卷自动生成系统/.project 试卷自动生成系统/bin/Db/Sql.class 试卷自动生成系统/bin/f ...

  2. 微信公众号怎么推送消息_微信公众号发送消息

    A.模板消息发送 模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等.不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息. 备注 ...

  3. 微信登录画面_微信登录界面的地球变了_微信登录界面首变真相

    细心的小伙伴发现在启动微信的时候,那个经典的一个小人剪影面对着地球的画面开始发生了一些变化,似乎云层变得更为清晰细致了.微信登录界面6年来首变化,那么为何改变来的如此突然呢,下面小编就分享给大家! 手 ...

  4. python学法用法 自动刷分_微信跳一跳python辅助工具刷分教程详解

    随着身边不少小伙伴都加入了微信跳一跳挑战,朋友圈最近都被刷爆了,为了刷分,很多小伙伴都开始开挂了,Github大神wangshub分享了一个针对该游戏的开源项目,那微信跳一跳python怎么刷分呢,下 ...

  5. python学法用法 自动刷分_微信跳一跳python怎么刷分_微信跳一跳python使用教程

    微信跳一跳python怎么刷分?要知道,游戏中这个Python脚本程序可以刷很高的分数,所以接下来小编要为大家介绍下python使用教程! 微信跳一跳python使用教程 工具介绍 Python 2. ...

  6. python学法用法 自动刷分_微信跳一跳python使用教程 微信跳一跳python怎么刷分

    最近,跳一跳,可以说是火爆了微信好友圈,Github大神wangshub分享了一个针对该游戏的开源项目,也就是一个Python脚本程序可以刷很高的分,下面就为大家带来跳一跳python使用教程. 微信 ...

  7. 跳一跳python源码下载_教程 跳一跳源码

    这个压缩包为跳一跳工具源码 (安卓版) 仅供代码爱好者交流研究, 且不可用作其他用途,否则后果自负!!! 本来想分享一点数据分析领域-回归预测模型解读与实际工作中发挥用处 后来看到朋友圈被跳一跳霸屏, ...

  8. 跳一跳python源码下载_《跳》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...

    基本词义 ◎ 跳 tiào 〈动〉 (1) (形声.从足,兆声.本义:跃) (2) 同本义 [jump:leap:spring] 跳,-一曰跃也.--<说文> 特跳此者.--<左传· ...

  9. 微信授权Java重定向前端地址_微信网页授权+分享踩过的坑

    页面用浏览器自带返回和安卓物理返回死循环的话,直接看高潮部分 背景 折磨我两个工作日加周末一天的问题,我觉得还是有必要记录一下,为什么程序员总是加班,就是遇到这些意想不到的问题 需求 领导:我想做两个 ...

  10. java实现qq抢红包_微信抢红包到底是怎么抢到的?

    " 微信抢红包功能,一下子拉近了长辈与我们之间的距离,每年都是盼望着亲人群抢红包,今天来给大家分享一下,为啥抢红包有人多,有人少,什么时候抢最合适?" 01 - 微信抢红包 场景描 ...

最新文章

  1. Java多线程- 线程池的基本使用和执行流程分析 - ThreadPoolExecutor
  2. 行走智慧城市 数据要有统一“身份”
  3. 将Facebook整个托管在AWS上,这可行吗?
  4. 013_JDK的Collections类的sort方法的实现
  5. Python容器类型公共方法汇总
  6. 滑动窗口最大值—leetcode239
  7. [转载]工作面试时最难的25个问题
  8. 工业级光纤收发器如何正确使用和维护?
  9. Service混合开启笔记(startService+bindService)
  10. 技术文章系列汇总(持续更新中)并附博客上树状列表源代码
  11. php 保存json格式数组 json_encode /u 不转义
  12. 简单的围棋棋盘打谱设计C#实现
  13. 网站被挂马实用怎么解决的办法之一
  14. 同时定位与地图创建综述
  15. PPSIG携手100+位contributor,共建飞桨开源社区
  16. 示例-Luat示例-HTTP
  17. Android TTS语音播报实践
  18. 卡尔曼滤波(kalman)相关理论以及与HMM、最小二乘法关系
  19. Gitee推送本地文件到仓库并且创建子文件夹(详细)
  20. DCS、PLC与SCADA的区别

热门文章

  1. txt 转成mysql_请问txt文件怎么转换成SQL数据库文件
  2. 互联网摸鱼日报(2023-06-24)
  3. Windows 7 上使用CMake-gui生成 open62541.c 和 open62541.h 的过程
  4. ajax联系人数,loner_li AJax无刷新获取 当前在线人数 实例
  5. 速通A100-4硬件防火墙和ISA软件防火墙
  6. 关闭 trados 2019 自动更正
  7. 云合同的文件如何存放到服务器,数据迁移到云服务器合同
  8. Linux下安装国际版QQ
  9. 【GA三维路径规划】基于matlab遗传算法无人机三维路径规划【含Matlab源码 1268期】
  10. AG9321MCQ_QFN88_中文规格书