""" 使用方法: 1.打开模拟器,运行微信,进入跳一跳 2.开始新一局,进入等待起跳的界面。(确保可以看到小人) 3.运行此脚本,看到提示"鼠标移动到左上角",将鼠标移动到游戏区域的左上角,保持1秒。 看到提示"鼠标移动到右下角",将鼠标移动到游戏区域的右下角,保持1秒。 4.脚本开始自动玩游戏 """ import win32api import win32con from ctypes import * import time import random from PIL import ImageGrab """ 请调整rate值。 rate为按压时间的放大倍率,1为不变,大于1为放大,小于1为缩小。 调整方法: 小人跳得过远就改小一些,反之则改近一些 精确度越高越好,建议从小数点后一位开始调,精确到小数点后三位 """ rate = 1.236 class POINT(Structure): _fields_ = [("x", c_ulong), ("y", c_ulong)] def get_mouse_point(): """ 获取鼠标位置 :return: dict,鼠标横纵坐标 """ po = POINT() windll.user32.GetCursorPos(byref(po)) return int(po.x), int(po.y) def mouse_move(x, y): """ 移动鼠标位置 :param x: int, 目的横坐标 :param y: int, 目的纵坐标 :return: None """ windll.user32.SetCursorPos(x, y) def mouse_click(x=None, y=None): """ 模拟鼠标点击 :param x: int, 鼠标点击位置横坐标 :param y: int, 鼠标点击位置纵坐标 :return: None """ if not x is None and not y is None: mouse_move(x, y) time.sleep(0.05) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) def mouse_pclick(x=None, y=None, press_time=0.0): """ 模拟式长按鼠标 :param x: int, 鼠标点击位置横坐标 :param y: int, 鼠标点击位置纵坐标 :param press_time: float, 点击时间,单位秒 :return: None """ if not x is None and not y is None: mouse_move(x, y) time.sleep(0.05) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) time.sleep(press_time) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) def get_static_mouse_point(): """ 获取鼠标稳定的位置 :return: dict,鼠标横纵坐标 """ last = get_mouse_point() while True: time.sleep(0.5) current = get_mouse_point() if last == current: return current last = current def grab(x1, y1, x2, y2): """ 以点(x1,y1)为左上角,以点(x2,y2)为右下角截图 :param x1: int, 左上角横坐标 :param y1: int, 左上角纵坐标 :param x2: int, 右下角横坐标 :param y2: int, 右下角纵坐标 :return: ImageGrab对象, 截图 """ im = ImageGrab.grab((x1, y1, x2, y2)) return im def get_role_x(im): """ 获得角色的x轴位置 :param im: ImageGrab对象,截图 :return: int,角色x轴位置 """ pix = im.load() width = im.size[0] height = im.size[1] sum = 0 count = 0 for y in range(height): for x in range(width): r, g, b = pix[x, y] if 54 <= r <= 56 and 59 <= g <= 61 and 101 <= b <= 103: sum += x count += 1 if count > 0: return int(sum / count) return 0 def get_start_x(im, middle_x, end_x, no_turn=True): """ 获得起跳位置 :param im: ImageGrab对象,截图 :param middle_x: int,对称轴位置 :param end_x: int,落点位置 :param no_turn: bool,是否转弯 :return: int,起跳位置 """ if no_turn: return get_role_x(im) else: if end_x > middle_x: return middle_x - (end_x - middle_x) else: return middle_x + (middle_x - end_x) def get_end_x(im, middle_x, jump_right=True): """ 获得落点位置 :param im: ImageGrab对象,截图 :param middle_x: int,对称轴位置 :param jump_right: bool,是否是向右跳的 :return: int,落点位置 """ pix = im.load() width = im.size[0] height = im.size[1] if jump_right: for y in range(height): avgR, avgG, avgB = pix[0, y] sum = 0 count = 0 for x in range(middle_x + 10, width): r, g, b = pix[x, y] if abs(r - avgR) > 20 or abs(g - avgG) > 20 or abs(b - avgB) > 20: sum += x count += 1 if count > 0: return int(sum / count) else: for y in range(height): avgR, avgG, avgB = pix[0, y] sum = 0 count = 0 for x in range(middle_x - 10): r, g, b = pix[x, y] if abs(r - avgR) > 20 or abs(g - avgG) > 20 or abs(b - avgB) > 20: sum += x count += 1 if count > 0: return int(sum / count) return 0 def is_special(im, end_x): """ 判断是否为特殊方块 :param im: ImageGrab对象,截图 :param end_x: int,落点位置 :return: bool,是否为特殊方块 """ pix = im.load() width = im.size[0] height = im.size[1] for y in range(height): r, g, b = pix[end_x + 5, y] if r == 244 and g == 138 and b == 39: return True r, g, b = pix[end_x, y] if r == 239 and g == 118 and b == 119: return True return False if __name__ == '__main__': """ 获取截图区域 """ print("鼠标移动到左上角") time.sleep(1) upleft = get_static_mouse_point() print("OK") time.sleep(0.5) print("鼠标移动到右下角") time.sleep(1) downright = get_static_mouse_point() print("OK") jump_right = True # 计算对称轴位置 im = grab(upleft[0], upleft[1], downright[0], downright[1]) start_x = get_role_x(im) end_x = get_end_x(im, jump_right) middle_x = int((start_x + end_x) / 2) while True: # 截图 im = grab(upleft[0], upleft[1], downright[0], downright[1]) # 获取落点位置 time.sleep(0.2) last_jump_right = jump_right jump_right = get_role_x(im) < middle_x end_x = get_end_x(im, middle_x, jump_right) # 获取起跳点位置 time.sleep(0.2) start_x = get_start_x(im, middle_x, end_x, jump_right == last_jump_right) # 判断落点是否为特殊方块 time.sleep(0.2) special_flag = is_special(im, end_x) # 模拟点击 press_time = abs(start_x - end_x) / 400.0 press_time *= rate p = get_mouse_point() mouse_pclick(downright[0] - int(random.uniform(10, 50)), downright[1] - int(random.uniform(10, 50)), press_time) mouse_move(p[0], p[1]) # 如果是特殊方块,等待两秒 if special_flag: time.sleep(2) time.sleep(1.5)