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

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

(0)

相关推荐

  • Android版微信跳一跳小游戏利用技术手段达到高分的操作方法

    本文主要来讲个个好玩的东西,近来微信刚出的跳一跳微信小程序的游戏很火,看到很多人都达到了二三百分就各种刷朋友圈了. 甩手一个表情 最终我们达到的分数却是这样的: 羡慕吧 一定会有人拍手叫好,"黄金右手"!说真的,我已经不用右手好多年,而且我玩这个游戏压根就没用手,而是意念!哈哈,别喷我,开个玩笑而已,肯定是利用技术手段啦,什么技术?python喽-哈哈,不过不是我写的,我自己是做Android开发的,我对于python从来没有接触,只是恰好在蛋哥公众号看到关于这个游戏的文章,觉得有意思

  • 安卓版本微信跳一跳自动执行代码剖析

    手动版的这里不多说,图像识别,坐标计算跳跃,要想得高分会点的手疼.这里主要剖析下自动版的,这里仅介绍安卓版本. 整体的结构 脚本的整体结构还是比较简洁的,如下图所示. 手机连接PC,PC通过adb命令对手机游戏界面进行截图: PC通过adb命令将该截图拷贝回PC: PC端通过python对图像进行处理(第一版中使用的opencv,目前使用的是直接读取像素的rgb值),获取棋子的位置,获取下一个棋盘的位置,然后计算出下一跳的距离,从而根据经验值计算出按压时间t: 通过adb命令模拟按压时间t即可实

  • 利用Kotlin实现破解Android版的微信小游戏--跳一跳

    前言 昨天下午,微信小程序开放了游戏接口,朋友圈瞬间炸开了锅,尤其是"跳一跳"这款游戏的成绩单,在朋友圈刷了一波又一波. 下面就来给大家介绍了关于Kotlin破解Android版的微信小游戏跳一跳的相关内容,让大家可以好好炫耀一番. 成果 跳一跳 微信小程序可以玩游戏了,我们来破解一下<跳一跳>这个官方出品的小游戏吧. 思路 用usb调试安卓手机,用adb截图并用鼠标测量距离,然后计算按压时间后模拟按压. $ adb shell input swipe <x1>

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

    微信跳一跳辅助的Java具体实现代码,供大家参考,具体内容如下 1.参考知乎教你用Python来玩微信跳一跳,鉴于本人Python一直都是半吊子水平,之前打算用python刷分,可无奈安装python环境各种模块缺失,报错不停,于是乎,使用Java重新实现了一下. 2.环境配置及相关说明: 1).Windows系统,本人win10 2).AVA环境安装,JDK7以上即可 3).安卓手机一部.数据线一条 4).电脑安装ADB驱动,连接安卓手机,同时打开USB调试模式 5).打开微信小程序的跳一跳游

  • 微信跳一跳辅助python代码实现

    微信跳一跳辅助的python具体实现代码,供大家参考,具体内容如下 这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短来控制这个「小人」跳跃的距离.可能刚开始上手的时候,因为时间距离之间的关系把握不恰当,只能跳出几个就掉到了台子下面. 玩法类似于<flappy bird> 下载github的一个程序,但是在windows10下不能运行,原因是windows10下没有copy命令了,修改为Python自带的复制方法,即可完成.今天运行好像一开始不能正确跳第一次,人工辅助后,后

  • 安卓版微信跳一跳辅助 跳一跳辅助Java代码

    安卓版微信跳一跳辅助,java实现,具体内容如下 已经看到网上有大神用各种方式实现了,我这是属于简易版ADB命令式实现. 操作方法 1.光标移动到起始点,点击FORM 2.光标移动到目标点,点击TO 3.小人已经跳过去了 原理说明 安装APP,通过设置起点和目标点位置,获得弹跳的毫秒数,发送请求到连接手机的电脑中,电脑执行adb命令起跳. 具体实现 本人的测试设备是Mate9,android版本为7.0,由于在非Root环境下,普通安卓应用并不能通过Runtime.getRuntime().ex

  • 微信跳一跳刷分java代码实现

    朋友圈晒跳一跳成绩好久了,今天无意中看到以前一个同事小妞晒用代码刷分的视频,百度了一下果然看到了代码(代码在最后),几经波折,终于成功运行,刷了一点分数. 首先大概说一下步骤: 1.百度下载刷分代码 2.安装adb 3.找个手机使用USB调试模式连接电脑 4.启动跳一跳微信小程序 5.在eclipse中运行代码(此处要不断调试根据手机屏幕大小修改参数) 结果就是你的手机屏幕会自动按压然后让棋子跳. 再说下问题: 一.安装adb问题集: 下载adb工具地址 在此处的设备管理器中,如果没有安装在其他

  • 100行java写的微信跳一跳辅助程序

    前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个蒙版. 下面就开始介绍我的小程序,没好多东西,真正的代码应该就是100行左右,没啥难的. 下面这是我的微信朋友们的跳一跳 也就这样吧,因为wechat还是有那个仿作弊系统的,所以还是低调的吧... 话不多说,还是下面奉上我的code吧,说多了墨迹呢.... package com.rain.jump.util;

  • 基于VS+Opencv2.4.10微信跳一跳辅助工具

    最近微信的跳一跳小程序可谓火了一把,不是因为它本身多好玩,而是有大部分的程序员们加入其中,利用各种领域方法,实现了微信跳一跳的外挂,分数轻松上千或上万.之前也看了基于Python开源的代码,GitHub上现在的star已经快超过1W了,简直不敢想.趁着今天礼拜天,在实验室中也简单的实现了一下微信跳一跳的辅助工具,精度还不够高,我跑了一下才到90,纯属娱乐好玩的,后期再继续改进,主要是依赖C++来实现了一下. 环境: Win10+VS2012+Opencv2.4.10+ADB工具 环境的搭建请查阅

  • 使用Python制作微信跳一跳辅助

    1.  前言 微信的跳一跳相信大家都很熟悉了,而且现在各种外挂.辅助也是满天飞,反正本人的好友排行榜中已经是八九百都不足为奇了.某宝上一搜一堆结果,最低的居然只要3块多,想刷多少分就刷多少分,真是离谱. 作为一枚程序猿,我决心也自己搞一下,不为别的,一来为了磨练一下自己的解决问题的能力,而来也为了娱乐一下.像这种任务,最适合的当然是Python,丰富的第三方库,而且具有胶水语言的特点. 本程序的主要设计思路就是,PC端adb连接手机→截屏→在PC端展示→用户鼠标选取起点和终点→计算距离.时长→a

  • python实现微信跳一跳辅助工具步骤详解

    说明 1.windows上安装安卓模拟器,安卓版本5.1以上 2.模拟器里下载安装最新的微信6.6.1 3.最好使用python2.7,python3的pyhook包有bug,解决比较麻烦 步骤 1.windows上安装python2.7,配置好环境变量和pip 2.到这个网站下载对应版本的pyHook和pywin32 http://www.lfd.uci.edu/~gohlke/pythonlibs 2.打开cmd,安装下载好的whl文件和其他库 pip install pywin32-221

  • 微信跳一跳python自动代码解读1.0

    微信跳一跳自动代码,具体内容如下 那个跳一跳python"外挂",有几个python文件,其中有一个是得到截图,然后鼠标在图片上点击两次,python窗口上会打印两次鼠标的位置,并且会跟上一行这两个点之间的距离. 这个功能我先给除去获取截屏,就说怎么在某张图片上算出两次点击的距离. 首先,需要用到图形模块,PIL: from PIL import Image img = Image.open('0.jpg') 然后用图形绘制模块matplotlib来给出一个plot对象: import

随机推荐