Python如何实现微信《跳一跳》游戏的一指操作自动化?


Python如何实现微信《跳一跳》游戏的一指操作自动化?
57 回复
import time
import numpy as np
from PIL import ImageGrab
import matplotlib.pyplot as plt
import cv2

class WeChatJumpAuto:
    def __init__(self):
        self.screenshot_region = (0, 0, 1080, 1920)  # 根据手机分辨率调整
        self.press_coefficient = 1.35  # 按压时间系数,需要根据实际情况调整
        
    def get_screenshot(self):
        """获取屏幕截图"""
        screenshot = ImageGrab.grab(bbox=self.screenshot_region)
        return cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
    
    def find_player_and_target(self, img):
        """识别玩家棋子和目标中心点"""
        # 1. 识别玩家棋子(通常为底部中心位置)
        height, width = img.shape[:2]
        roi_height = int(height * 0.6)
        
        # 玩家棋子通常在屏幕底部1/3区域
        player_roi = img[roi_height:, :]
        
        # 使用颜色过滤(棋子通常有特定颜色,这里以红色为例)
        hsv = cv2.cvtColor(player_roi, cv2.COLOR_BGR2HSV)
        lower_red = np.array([0, 100, 100])
        upper_red = np.array([10, 255, 255])
        mask = cv2.inRange(hsv, lower_red, upper_red)
        
        # 查找轮廓
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        
        if contours:
            # 取最大的轮廓作为棋子
            max_contour = max(contours, key=cv2.contourArea)
            x, y, w, h = cv2.boundingRect(max_contour)
            player_x = x + w // 2
            player_y = y + roi_height + h // 2
        else:
            # 如果颜色识别失败,使用固定位置(需要根据实际游戏调整)
            player_x = width // 2
            player_y = height - 150
        
        # 2. 识别目标中心点(使用边缘检测)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        edges = cv2.Canny(gray, 50, 150)
        
        # 在玩家棋子以上区域寻找目标
        search_region = edges[:player_y-100, :]
        
        # 寻找非零像素点
        nonzero = cv2.findNonZero(search_region)
        if nonzero is not None:
            # 计算所有边缘点的中心
            target_x = int(np.mean(nonzero[:, 0, 0]))
            target_y = int(np.mean(nonzero[:, 0, 1]))
        else:
            # 如果找不到边缘,使用屏幕中心偏上位置
            target_x = width // 2
            target_y = height // 3
        
        return (player_x, player_y), (target_x, target_y)
    
    def calculate_distance(self, player_pos, target_pos):
        """计算两点之间的欧几里得距离"""
        return np.sqrt((target_pos[0] - player_pos[0])**2 + 
                      (target_pos[1] - player_pos[1])**2)
    
    def jump(self, distance):
        """模拟按压操作"""
        press_time = distance * self.press_coefficient
        press_time = max(300, min(press_time, 2000))  # 限制按压时间范围
        
        # 这里需要根据你的ADB命令或模拟点击工具来实现
        # 示例使用ADB命令(需要连接手机并开启USB调试)
        import subprocess
        subprocess.call(f'adb shell input swipe 500 1500 500 1500 {int(press_time)}', shell=True)
        
        return press_time
    
    def run(self):
        """主循环"""
        print("开始自动跳一跳...")
        time.sleep(3)  # 给时间切换到游戏界面
        
        while True:
            try:
                # 1. 截图
                img = self.get_screenshot()
                
                # 2. 识别位置
                player_pos, target_pos = self.find_player_and_target(img)
                
                # 3. 计算距离
                distance = self.calculate_distance(player_pos, target_pos)
                print(f"玩家位置: {player_pos}, 目标位置: {target_pos}, 距离: {distance:.1f}")
                
                # 4. 执行跳跃
                press_time = self.jump(distance)
                print(f"按压时间: {press_time:.1f}ms")
                
                # 5. 等待落地
                time.sleep(2.5)
                
            except KeyboardInterrupt:
                print("\n程序已停止")
                break
            except Exception as e:
                print(f"发生错误: {e}")
                time.sleep(1)

if __name__ == "__main__":
    auto_jump = WeChatJumpAuto()
    auto_jump.run()

核心实现要点:

  1. 屏幕截图:使用PIL的ImageGrab获取游戏画面,需要根据手机分辨率调整截图区域
  2. 位置识别
    • 玩家棋子:通过颜色过滤(HSV空间)或固定位置识别
    • 目标中心:使用Canny边缘检测找到下一个跳台的中心点
  3. 距离计算:计算棋子底部中心到目标中心的欧几里得距离
  4. 按压时间:距离乘以系数得到按压时长,需要实际调试确定最佳系数
  5. 模拟操作:通过ADB命令发送长按指令,需要手机开启USB调试

注意:实际使用时需要根据具体游戏版本调整颜色阈值和位置识别逻辑,系数press_coefficient也需要多次测试校准。

调好系数就能稳过。

厉害了,看了下代码,好像是 python2

实际用下来误差挺大的,跳几格就 gg 了

玩了几把,最高 20 分

最多能跳 4 格。。。。之前跳的每格误差特别大。

今天早上 v 站上面有个用 java 写的,也是 adb



我是用鼠标仔细瞄准之后点的,准确率还可以啊,玩了 200 多分。

昨晚临时写的,代码拙劣,提供了一个想法,祝大家玩的开心

应该可以改进一下, 自动识别 now 点和 target 点。
我手点了 100 分没耐心了 ~

‘adb’ �����ڲ����ⲿ���Ҳ���ǿ����еij���
�����������


编译出来这个 是什么鬼? adb 没安装成功?

#11
配置一下 adb 的环境变量。


系数问题,调一下就好了。已经没朋友了。

刷到了 1k 多 不能刷了 = =

adb shell input swipe 320 410 320 410 607 执行之后对手机无效啊?

是的。。。系数调到 1.1 就没问题了

貌似 你的手机分辨率 和 楼主的不一样.

需要在开发者选项里开权限

想知道怎么你是怎么测试出距离所对应按压时间的

咋不用 python 写个图片识别…识别菱形中间点与自己的位置 然后调整力度…
你这个…并不是完美

有些手机 adb shell input swipe 是无效的

开发者模式应该都是有相关设置的,打开就可以了

撸了一个自动识别位置, 不是特别准确不过能跑, 已经 400 多分了

点 320 分。太累了。不玩了

哈哈 正在写

为啥其他游戏用外挂被人所不齿,这种小游戏用外挂大家貌似都很宽容呢?

这个能拿到屏幕截图, 也可以估算蓄力时间, 但操作还是没法自动完成.

adb shell input

在 iOS 中好像没有类似的实现吧

小游戏外挂一般开源

只是娱乐一下的 就很宽容了… 没事点点那种 又不用打什么职业比赛 手动偷笑

搞定了,miui 需要在开发者选项中开启USB 调试(安全设置)

写好了给我来一份

求分享!!!

因为别的外挂使用成本高 这个外挂开源随便用 大家就心满意足了

是不是要出个 node 版本了

我执行到这里 34 行 im = plt.imshow(img, animated=True) 就报错了,Unable to display children:Error resolving variables Traceback (most recent call last):
File “E:\Program Files\JetBrains\PyCharm Community Edition 2017.2.3\helpers\pydev_pydevd_bundle<a target=”_blank" href=“http://pydevd_comm.py” rel=“nofollow noopener”>pydevd_comm.py", line 1004, in do_it
_typeName, valDict = pydevd_vars.resolve_compound_variable(self.thread_id, self.frame_id, self.scope, self.attributes)
TypeError: ‘NoneType’ object is not iterable

这个厉害了

我还以为是强化学习做的,原来要手动点,然后算距离

6666666666

我就担心微信号会不会被封哈。

#23 有没有代码分享学习一下

666,转换成 python3 试了一下,就是点的累。点到了 800 去朋友圈发个图,嘿嘿。。

点了 600…

2560*1440 分辨率 距离系数设置多少合适

2K 屏距离系数是 1

我设置 1 跳不了 3 下就死了

我也觉得应该用强化学习来做

我手动打的 381 分,本来在朋友圈稳居第一的,然后手贱把这个东西分享给了朋友,被朋友的 2000 多分超了,我擦!

mac 怎么操作。。·


想写个识别算法不容易呐

https://gist.github.com/lll9p/f838c17fc6e3d62baf415989ae6d8c6e

在 LZ 的基础上稍微改了一下,不用跳一次点两下了:P

我用那个 JAVA 的辅助工具玩到了 5000 分

加入 图像识别起点,。。😂https://github.com/Chaaang/wechat_jumpandjump

#37 这个代码的原理是:点击截图上的起点和目标点,然后计算长度乘以系数,得到一个按压时间。这个错误是由于第一次没有点再截图内,所以第一个坐标是[None,None]

求一个 s8+的参数,我每次跑 100 多分就挂了,不知道那个参数不对

回到顶部