当前位置: 首页 > 编程笔记 >

微信跳一跳辅助Java代码实现

汤飞翮
2023-03-14
本文向大家介绍微信跳一跳辅助Java代码实现,包括了微信跳一跳辅助Java代码实现的使用技巧和注意事项,需要的朋友参考一下

微信跳一跳辅助的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; 
  } 
 } 
}

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

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

 类似资料:
  • 本文向大家介绍微信跳一跳刷分java代码实现,包括了微信跳一跳刷分java代码实现的使用技巧和注意事项,需要的朋友参考一下 朋友圈晒跳一跳成绩好久了,今天无意中看到以前一个同事小妞晒用代码刷分的视频,百度了一下果然看到了代码(代码在最后),几经波折,终于成功运行,刷了一点分数。 首先大概说一下步骤: 1.百度下载刷分代码 2.安装adb 3.找个手机使用USB调试模式连接电脑 4.启动跳一跳微信小

  • 本文向大家介绍使用Python制作微信跳一跳辅助,包括了使用Python制作微信跳一跳辅助的使用技巧和注意事项,需要的朋友参考一下 1.  前言 微信的跳一跳相信大家都很熟悉了,而且现在各种外挂、辅助也是满天飞,反正本人的好友排行榜中已经是八九百都不足为奇了。某宝上一搜一堆结果,最低的居然只要3块多,想刷多少分就刷多少分,真是离谱。 作为一枚程序猿,我决心也自己搞一下,不为别的,一来为了磨练一下自

  • 本文向大家介绍.NET开发实现一个微信跳一跳的辅助程序,包括了.NET开发实现一个微信跳一跳的辅助程序的使用技巧和注意事项,需要的朋友参考一下 前言 相信大家应该都知道了,最近微信更新了,出现了一个小游戏“跳一跳”,玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来分把,于是就想着要是开发个辅助就好了,于是简单想

  • 本文向大家介绍微信跳一跳自动脚本C#代码实现,包括了微信跳一跳自动脚本C#代码实现的使用技巧和注意事项,需要的朋友参考一下 前言 CSDN前阵子推送了篇文章,讲的是微信跳一跳的技术实现,大致浏览,发现难度不高,很适合练手。 思路 ADB得到屏幕截图,转换成bitmap逐像素分析图像,得到跳跃起点和终点坐标,最后ADB按压屏幕进行跳跃  相关知识 ADB创建 ·在https://adb.clockw

  • 本文向大家介绍微信跳一跳游戏Android刷分代码,包括了微信跳一跳游戏Android刷分代码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了微信跳一跳游戏Android实现刷分,供大家参考,具体内容如下 更多内容大家可以参考专题《微信跳一跳》进行学习。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍微信跳一跳python辅助软件思路及图像识别源码解析,包括了微信跳一跳python辅助软件思路及图像识别源码解析的使用技巧和注意事项,需要的朋友参考一下 本文将梳理github上最火的wechat_jump_game的实现思路,并解析其图像处理部分源码 首先废话少说先看效果 核心思想 获取棋子到下一个方块的中心点的距离 计算触摸屏幕的时间 点击屏幕 重要方法 计算棋子到下一个方块中心