原版本github地址:https://github.com/wangshub/wechat_jump_game

当时版本我用时感觉性能不佳,为能霸榜装逼,针对自己的手机进行了改进。

主要是对检测棋子,棋格部分进行了改进,仍有许多bug和未解决的问题之处,若有兴趣也可以再次进行改进,提升性能。

源码地址:http://download.csdn.net/download/wz2671/10259178

具体的环境配置等,可以参考原作者的github。

jump.py

# -*- coding: utf-8 -*-

"""

=== 思路 ===

核心:每次落稳之后截图,根据截图算出棋子的座标和下一个块顶面的中点座标,

根据两个点的距离乘以一个时间系数获得长按的时间

识别棋子:靠棋子的颜色来识别位置,通过截图发现最下面一行大概是一条

直线,就从上往下一行一行遍历,比较颜色(颜色用了一个区间来比较)

找到最上面的那一行的所有点,然后求个中点,求好之后再让 Y 轴座标

减小一定高度从而得到中心点的座标

识别棋盘:靠底色和方块的色差来做,从分数之下的位置开始,一行一行扫描,

由于圆形的块最顶上是一条线,方形的上面大概是一个点,所以就

用类似识别棋子的做法多识别了几个点求中点,这时候得到了块中点的 X

轴座标,利用链码思想求得右边界的X轴座标,乘以一定系数得到中心点座标

最后:根据两点的座标算距离乘以系数来获取长按时间

"""

from __future__ import print_function, division

import os

import sys

import time

import math

import random

from PIL import Image

from six.moves import input

try:

from common import debug, config, screenshot

except Exception as ex:

print(ex)

print('请将脚本放在项目根目录中运行')

print('请检查项目根目录中的 common 文件夹是否存在')

exit(-1)

VERSION = "1.1.2"

# DEBUG 开关,需要调试的时候请改为 True,不需要调试的时候为 False

DEBUG_SWITCH = False

#1.392

# Magic Number,不设置可能无法正常执行,请根据具体截图从上到下按需

# 设置,设置保存在 config 文件夹中

config = config.open_accordant_config()

under_game_score_y = config['under_game_score_y']

# 长按的时间系数,请自己根据实际情况调节

press_coefficient = config['press_coefficient']

# 二分之一的棋子底座高度,可能要调节

piece_base_height_1_2 = config['piece_base_height_1_2']

# 棋子的宽度,比截图中量到的稍微大一点比较安全,可能要调节

piece_body_width = config['piece_body_width']

def set_button_position(im):

"""

将 swipe 设置为 `再来一局` 按钮的位置

"""

global swipe_x1, swipe_y1, swipe_x2, swipe_y2

w, h = im.size

left = int(w / 2)

top = int(1584 * (h / 1920.0))

left = int(random.uniform(left-50, left+50))

top = int(random.uniform(top-10, top+10)) # 随机防 ban

swipe_x1, swipe_y1, swipe_x2, swipe_y2 = left, top, left, top

def jump(distance):

"""

跳跃一定的距离

"""

press_time = distance * press_coefficient

# press_time = max(press_time, 200) # 设置 200ms 是最小的按压时间

# 离近了补一点,离远了减一点

press_time = int(press_time)

if press_time < 500:

press_time += 100 - 2*(press_time//10)

elif press_time > 1000:

press_time -= press_time//50

cmd = 'adb shell input swipe {x1} {y1} {x2} {y2} {duration}'.format(

x1=swipe_x1,

y1=swipe_y1,

x2=swipe_x2,

y2=swipe_y2,

duration=press_time

)

print(cmd)

os.system(cmd)

return press_time

def find_piece_and_board(im):

"""

寻找关键座标

"""

w, h = im.size

scan_x_border = int(w / 8) # 扫描棋子时的左右边界

scan_end_y = 0 # 扫描的起始 y 座标

im_pixel = im.load()

# 以 50px 步长,尝试探测 scan_start_y

for i in range(int(h / 3), int(h*2 / 3), 50):

last_pixel = im_pixel[0, i]

for j in range(1, w):

pixel = im_pixel[j, i]

# 不是纯色的线,则记录 scan_start_y 的值,准备跳出循环

if sum(list(map(lambda x: abs(x[0]-x[1]), zip(pixel, last_pixel)))) > 3:

scan_end_y = i

break

if scan_end_y:

break

# 记录下y,对该行扫描,确定终点的横座标

# 由于圆左右不对称,回退寻找最顶端的那条线

pure = False

for i in range(scan_end_y, scan_end_y-55, -1):

if pure:

scan_end_y = i+2 # 要加2,上一条已经是纯白线,但又减了一次

break

last_pixel = im_pixel[0, i]

for j in range(1, w):

pixel = im_pixel[j, i]

if sum(list(map(lambda x: abs(x[0]-x[1]), zip(pixel, last_pixel)))) > 3:

break

if j == w-1:

pure = True

# 从 scan_end_y 开始往下扫描,棋子应位于屏幕下半部分,这里暂定不超过 2/3

scan_start_y = 0

for i in range(scan_end_y, int(h * 2 / 3)):

# 横座标方面也减少了一部分扫描开销

for j in range(scan_x_border, w - scan_x_border):

pixel = im_pixel[j, i]

# 根据棋子的颜色判断

if (51 < pixel[0] < 54) \

and (51 < pixel[1] < 63) \

and (58 < pixel[2] < 64):

scan_start_y = i

break

if scan_start_y != 0:

break

# 计算棋子的横座标

start_x = 0

piece_x_c = piece_x_sum = 0

for i in range(scan_x_border, w - scan_x_border):

pixel = im_pixel[i, scan_start_y]

if (51 < pixel[0] < 54) \

and (51 < pixel[1] < 63) \

and (58 < pixel[2] < 64):

piece_x_sum += i

piece_x_c += 1

start_x = piece_x_sum//piece_x_c

# 计算棋格的最顶端座标,考虑棋子比棋格高的情况

# 因为棋子和棋格在中线两侧,所以从另外的一边找棋格顶端

st = ed = 0

dir = 0 # 鉴别方向,-1朝左跳, 1朝右跳

if start_x < w/2:

st = w//2+1

ed = w

dir = 1

else:

st = 1

ed = w//2

dir = -1

pure = True

if scan_end_y == scan_start_y: # 当棋子比棋格低,继续往下找

for i in range(scan_end_y, int(h * 2 / 3)):

last_pixel = im_pixel[0, i]

for j in range(st, ed):

pixel = im_pixel[j, i]

# 不是纯色的线,则记录 scan_end_y 的值,准备跳出循环

if sum(list(map(lambda x: abs(x[0]-x[1]), zip(pixel, last_pixel)))) > 3:

pure = False

scan_end_y = i

break

if pure != True:

break

end_x_c = end_x_sum = 0

pixel = im_pixel[st-1, scan_end_y]

for i in range(st, ed):

last_pixel = im_pixel[i, scan_end_y]

if sum(list(map(lambda x: abs(x[0]-x[1]), zip(pixel, last_pixel)))) > 3:

end_x_sum += i

end_x_c += 1

end_x = end_x_sum//end_x_c

if not all((piece_x_sum, piece_x_c)):

return 0, 0, 0, 0

# scan_end_y 棋盘最上方的高度, scan_start_y 棋子最上方的高度

# 棋子最终座标 start_x(已求得), start_y

# 棋盘最终座标 end_x(已求得), end_y

# 棋子纵座标可以通过顶端座标减去到中心的距离求得

start_y = scan_start_y + 191 # 191是我量出来的,只针对本手机的分辨率情况下

# 求棋盘的纵座标end_y

# 根据棋子跳跃方向决定检测边界的方向,借鉴链码的思想

# 连续向下超过5即为边界

down_time = 0

bac_pixel = im_pixel[end_x, scan_end_y-1]

# 以向右跳为例,分别代表右,右下,下, 左下, 左; 这儿原先想根据跳跃方向向对应方向检测,但是左边会受阴影影响

# 向右检测暂时未出现被遮挡不能检测的情况,只出现过棋子跳出边界的情况,这种情况应该很少见,不管了

step = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1]]

dx = end_x; dy = scan_end_y

back = False

# 考虑到带耳朵的方块出现的一些特殊情况,加了向左下,左方向的判断

while(down_time < 5):

for i in range(6):

if (back and i == 0) or (back and i == 1):

continue

next_pixel = im_pixel[dx+step[i][0], dy+step[i][1]]

if sum(list(map(lambda x: abs(x[0]-x[1]), zip(next_pixel, bac_pixel)))) > 20:

dx += step[i][0]

dy += step[i][1]

if i == 2:

down_time += 1

elif down_time != 0:

down_time = 0

if i == 4 or i == 5:

back = True

elif back:

back = False

break

# 这个0.57是指中心点到上边界和右边界的距离比,圆和正方形的比值不同,圆的更小些,正方形更大些,

# 暂未想出合适的区分方法,可以通过上面求出的链码求面积或周长进行判断,不过略麻烦

end_y = scan_end_y + abs(int(0.57*(dx-end_x))) # 0.57以实际机型为准

return end_x, end_y, start_x, start_y

def yes_or_no(prompt, true_value='y', false_value='n', default=True):

"""

检查是否已经为启动程序做好了准备

"""

default_value = true_value if default else false_value

prompt = '{} {}/{} [{}]: '.format(prompt, true_value,\

false_value, default_value)

i = input(prompt)

if not i:

return default

while True:

if i == true_value:

return True

elif i == false_value:

return False

prompt = 'Please input {} or {}: '.format(true_value, false_value)

i = input(prompt)

def main():

"""

主函数

"""

# debug.dump_device_info()

screenshot.check_screenshot()

while True:

screenshot.pull_screenshot()

im = Image.open('./autojump.png')

# 获取棋子和 board 的位置

end_x, end_y, start_x, start_y = find_piece_and_board(im)

# print(start_x, start_y, end_x, end_y)

set_button_position(im)

jump(math.sqrt((end_x-start_x)**2+(end_y-start_y)**2))

# if DEBUG_SWITCH:

# debug.save_debug_screenshot(ts, im, piece_x,

# piece_y, board_x, board_y)

# debug.backup_screenshot(ts)

im.close()

# 为了保证截图的时候应落稳了,多延迟一会儿,随机值防 ban

time.sleep(random.uniform(1.0, 1.2))

if __name__ == '__main__':

main()

游戏效果图如下:

然而,,,

不过低调些应该还是不会被检测出的。

python跳一跳脚本详解_跳一跳 python脚本 改进版相关推荐

  1. python中的import详解_如何在python中import

    用法 1.import同一个路径下的.py文件. 这是import关键字最基本的用法,import moudle1可以理解为直接将module1.py的语句复制到对应的代码段. 2.import pa ...

  2. python之sys模块详解_(转)python之os,sys模块详解

    python之sys模块详解 原文:http://www.cnblogs.com/cherishry/p/5725184.html sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和 ...

  3. python跳一跳脚本详解_微信跳一跳游戏 python脚本辅助得高分

    微信小程序一时间火爆朋友圈,关键是还有排行榜!游戏操作简单,可直接根据电脑识别,用python写出自动跳辅助脚本,本想动手写下,索性网上有大神写了现成脚本,修改了一小部分参数,就可以稳定使用了霸榜没有 ...

  4. python学习详解_深入解析Python小白学习【操作列表】

    1.遍历列表 需要对列表中的每个元素都执行相同的操作时,可使用for 循环: magicians = ['alice','david','carolina'] for magician in magi ...

  5. python凯撒密码详解_四十八、Python用smtp发邮件详解(163和QQ邮箱)

    Python发邮件详解 一.利用163的smtp发送邮件 import smtplibfrom email.mime.text import MIMETextfrom email.header imp ...

  6. python中index方法详解_详解python中的index函数用法

    1.函数的创建 def fun(): #定义 print('hellow') #函数的执行代码 retrun 1 #返回值 fun() #执行函数 2.函数的参数 普通参数 :要按照顺序输入参数 de ...

  7. python ssl模块用法详解_一看就懂,Python 日志模块详解及应用!

    日志概述 百度百科的日志概述: Windows网络操作系统都设计有各种各样的日志文件,如应用程序日志,安全日志.系统日志.Scheduler服务日志.FTP日志.WWW日志.DNS服务器日志等等,这些 ...

  8. python股票网格交易法详解_干货 | 浅谈网格交易法

    原标题:干货 | 浅谈网格交易法 网格交易法的基本原理就是把行情的所有日间上下的波动全部囊括,它不会放过任何一次的行情上下波动. 不管市场价格如何上下波动,不外3种形态:上涨,盘整,下跌.由于不同的操 ...

  9. python json模块详解_深入解析Python编程中JSON模块的使用

    JSON编码支持的基本数据类型为 None , bool , int , float 和 str , 以及包含这些类型数据的lists,tuples和dictionaries. 对于dictionar ...

最新文章

  1. tor screenrec屏幕录制+_ScreenFlow for mac(屏幕录制软件) v8.2.4中文版
  2. GDB调试基础操作详解【GDB调试】
  3. Gerrit代码审核服务器搭建全过程
  4. CF_275_DIV2_D_Interesting Array
  5. Approximation and fitting、Statistical estimation
  6. java socket 线程池_程序员:java使用线程池和TCP实现简单多轮聊天系统
  7. x=min(x, y)
  8. 军工电子产品环境可靠性测试试验实验室GJB150A
  9. Dlink ?一款交互式FlinkSQL开发平台
  10. 7天连锁酒店郑南雁:顺势创业者无为管理人
  11. Javaweb的HTML的表单标签
  12. Excel打开时自动开一个sheet1页面
  13. 修嗒嗒“全民家装狂欢节”诞生,巨额补贴能否造就家装行业的“双十二”?
  14. 程序设计入门-java
  15. 线程池ExecutorService
  16. ffmpeg 图片转视频
  17. 推荐一个在上海买中老年服饰的地方
  18. Python基础 - 文件拷贝
  19. Tita 绩效管理:一对一正式面谈
  20. 学习笔记-频率域滤波(2)-取样函数

热门文章

  1. django学习问题及解决方法
  2. LCS、LIS及LCIS
  3. 今民生:上海天伦医院告诫患者小心黑心医托?
  4. matlab与化学,MATLAB与化学
  5. 洛谷 小木棍(暴力+剪剪剪剪枝)
  6. linux pandas教程_十分钟入门 Pandas
  7. 运筹学与博弈论的关系
  8. 服务器文件被篡改evopro后缀,SQLServer数据库服务器mdf文件中了勒索病毒,扩展名被篡改为.fuk25933...
  9. gradle在build的时候找不到某个jar包的解决办法
  10. ThreadPoolExecutor线程池的使用