1实验环境

操作系统:Windows10

编码语言:Python3.6

编译平台:Pycharm

Python库:os、datetime、matplotlib、opencv-python、time

2实验代码流程图

3代码运行步骤和结果等

3.1 手机和电脑用数据线连接

使用通过数据线连接手机,将开发者模式打开并授权

通过adb命令

adb devices

可以查看连接的Android设备的信息

3.2 获取手机相关的信息

查看Android手机的分辨率(第四行)

adb shell dumpsys window displays

获取屏幕密度

adb shell wm density

获取手机型号

adb shell getprop ro.product.device

获取Android系统的版本

adb shell getprop ro.build.version.release

3.3 截屏

输入如下命令:

adb shell screencap -p /sdcard/auto.png

此时,截屏的图片就保存到 /sdcard/auto.png文件中。

注意:/sdcard/和/data/目录是可以写入的。

可以通过命令查看sdcard目录下所有的文件。

adb shell ls /sdcard/ -l

通过如下命令把手机上的文件拷贝到电脑上

adb pull /sdcard/auto.png h:\

此时,图片就会被拷贝到h:\根目录下了。打开即可看到当前手机的屏幕信息。

3.4 屏幕点击事件

通过如下命令模拟手机的滑动事件

adb shell input swipe x1 y1 x2 y2 duration

通过adb shell input swipe命令进行滑动

l  x1、y1:滑动开始的点。

l  x2、y2:滑动结束的点。

l  duration:持续的时间(单位ms)。

特殊情况下:如果不写duration参数,就理解为点击事件。如果写duration,然后x1y1和x2y2是相同的点,就表示长按。

跳一跳关键是:duration的值的计算。

尝试:

adb shell input swipe 100 100 100 100 700

尝试修改duration的值,看看跳的效果。

求得可以拿到加分的中间值。比如555~871都可以拿到加分(555以下和871以上就不能拿到加分),此时则取中间值为(555+871)/2=713 作为后面计算的参考值。

3.5 duration值的计算

假设我们截屏的效果是如下:

从图中可以看到,时间的值跟开始位置到结束位置的距离有关。

假设时间是t,距离是s。公式应该是s = at

基本思路:两点之间的距离乘以一个时间系数。

所以要从截图上识别出起跳位置的坐标(x1,y1)和目标位置的坐标(x2,y2)。

起跳位置的坐标:小人的底座中心点

目标位置的坐标:目标菱形的中心点

然后计算这两点之间的距离(欧氏距离):sqrt((x1-x2)2+(y1-y2)2)

3.6 寻找关键坐标——起跳坐标

算法策略:获取小人的底座中心点的值作为起跳点。

1 获取小人的所有像素点中y坐标的最大值

2 在小人y坐标的最大值那些像素点中,计算出x的平均值,作为小人底座的x的值。

3 y坐标的最大值减去一个偏移值,就作为小人底座的y值。(注意:该偏移值不同的设备是不同的,同一台设备不同场景下是一样的)

比如教师机的设备中最低点的值是(410,1162),中心值是(410,1142),从而计算出偏移值为1162-1142=20

3.7 获取目标坐标的y值

取屏幕宽和高的一半(x=540和y=960)

我们会发现,目标格子的边沿(x=560,y=980)和这个是差不多的(y的偏差是20,x的偏差是20)

以后每次跳动的时候,假如已经知道目标格子的边沿,和目标坐标的x值,就可以很轻松计算出目标坐标的y值。

注意:每个格子的宽和高的比例是相同的。

方形:左:(560,848)                 园:左:(251,876)

   右:(1015,848)                           右:(522,876)

   上:(790,718)                             上:(388,799)

   下:(790,980)                             下:(388,957)

   中:(790,850)                             中:(388,876)

高和宽的比例:(980-718)/(1015-560) =262/455=0.576。假设该值为p

  

最后,由已知的目标坐标的x值,求目标坐标的y值。

先附上运行结果,以及截图信息:

在理解了跳一跳的基本思路之后,现在附上完整代码(有注释):

# main.py# _*_ coding:utf-8 _*_
__author__ = 'WoLykos'from operations import *
from draw import *
from algorithm import *
import time
import random# 测试截屏
# def test_screen_cap():
#     op = Operation()
#     op.screen_cap()# 测试显示图片
def test_show_pic():draw = Draw()draw.show_pic("img/auto.png")# 测试计算欧式距离
def test_euclidean_distance():algorithm = Algorithm()p1 = (3, 4)p2 = (6, 8)d = algorithm.euclidean_distance(p1, p2)print(d)# 测试寻找关键坐标
def test_find_point():op = Operation()im = op.screen_cap()algorithm = Algorithm()start_x, start_y, end_x, end_y = algorithm.find_point(im)print("start_point:", start_x, start_y)print("end_point:", end_x, end_y)start_point = (start_x, start_y)end_point = (end_x, end_y)distance = algorithm.euclidean_distance(start_point, end_point)# print(distance)press_time = algorithm.distance_to_time(distance)op.jump(start_point, end_point, press_time)if __name__ == "__main__":# test_screen_cap()# test_show_pic()while True:# test_euclidean_distance()
        test_find_point()time.sleep(1 + 2*random.random())

# algorithm.py
# _*_ coding:utf-8 _*_
__author__ = 'WoLykos'class Algorithm:# 构造器def __int__(self):pass# 计算两点之间的欧氏距离# p1和p2表示两个点 用元组来表示def euclidean_distance(self, p1, p2):return ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**0.5  # ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**0.5# 寻找关键坐标# 返回值1,2 piece_x, piece_y 起跳点的坐标 170,555# 返回值3,4 board_x, board_y 目标点的坐标 395,425def find_point(self, im):# piece_x = piece_y = 0# board_x = board_y = 0# 图像的大小w, h = im.size  # (1080,1920)# 加载图像im_pixel = im.load()# 记录小人所有的点points = []# 记录y的最大值piece_y_max = 0# 1 计算出起跳点 就是小人底座的中心点# 1.1 获取小人的所有像素点中y坐标的最大值# 遍历图像中的每一个点# 遍历每一行for i in range(h // 3, h * 2 // 3):# 遍历每一列for j in range(w):pixel = im_pixel[j, i]# print("i = ", i, ",j = ", j, "pixel = ", pixel)# 判断pixel是否小人所在的位置# 当该点的RGB值约为56,56,82的时候就可以认为是小人所在的像素点了if (51 < pixel[0] < 61 and 51 < pixel[1] < 61 and 72 < pixel[2] < 102):# 把当前的点添加到points数组中points.append((j, i))  # (x,y)# 记录下y的值if i > piece_y_max:piece_y_max = i# print("piece_y_max = %d" % (piece_y_max,))# 1.2 在小人y坐标的最大值那些像素点中,计算出x的平均值,作为小人底座的x的值。bottom_x = []for x, y in points:if y == piece_y_max:bottom_x.append(x)piece_x = sum(bottom_x) // len(bottom_x)# print("piece_x = %d" % (piece_x,))# 1.3 y坐标的最大值减去一个偏移值,就作为小人底座的y值。(注意:该偏移值不同的设备是不同的,同一台设备不同场景下是一样的)piece_y = piece_y_max - 20  # 偏移值1130-110=20# print("piece_y = %d" % (piece_y,))# 2计算 目标格子的中心点# 2.1计算目标格子的x值points = []# 只取中间1/3进行扫描for i in range(h // 3, h * 2 // 3):if len(points) > 0:break# 取坐标的一个点作为背景的参照物last_pixel = im_pixel[0, i]# 逐个扫描右边的点for j in range(w):pixel = im_pixel[j, i]# 把当前点与最左边的点比较 如果RGB差异比较大 则认为是目标点# 排除该点为小人像素点56,56,82的可能性,BUGif not (54 < pixel[0] < 141 and 54 < pixel[1] < 130 and 69 < pixel[2] < 172):if (abs(pixel[0] - last_pixel[0]) + abs(pixel[1] - last_pixel[1])+ abs(pixel[2] - last_pixel[2]) > 10):points.append((j, i))top_x = []for x, y in points:top_x.append(x)board_x = sum(top_x) // len(top_x)# print("board_x = %d" % (board_x,))# 2.2计算目标格式子y值# 屏幕中心的值center_x = w / 2 + 20  # x的偏差是20center_y = h / 2 + 20  # y的偏差是20,园# 格子高和宽的比例height_per_width = 262 / 455# 计算出目标格子的y值(需要转换成整数)# 从piece_x调到board_x 如果piece_x < board_x则表示从左往右跳# 如果piece_x > board_x 则表示从右往左跳if piece_x < board_x:board_y = int(center_y - height_per_width * (board_x - center_x))else:  # 从右往左跳board_y = int(center_y + height_per_width * (board_x - center_x))# print("board_y = %d" % (board_y,))return piece_x, piece_y, board_x, board_y# 距离与时间的转换def distance_to_time(self, distance):# 当0分的时候 距离为 527.5234591939964 时间为713p = 713 / 527.5234591939964  # 该算法后面待优化press_time = distance * preturn press_time

# operations.py
# _*_ coding:utf-8 _*_
__author__ = 'WoLykos'import os
import datetimefrom PIL import Image# 实现控制安卓
class Operation:# 构造方法def __int__(self):pass# 截屏def screen_cap(self):filename = time = datetime.datetime.now().strftime("%H%M%S")+".png"# 截屏并保存到手机cmd = "adb shell screencap -p /sdcard/auto.png"os.system(cmd)# 拷贝到电脑cmd = "adb pull /sdcard/auto.png "+"img/"+filenameos.system(cmd)# 打开图像文件return Image.open("img/"+filename)# 控制屏幕进行跳动def jump(self, src, dst, press_time):# print(press_time)press_time = int(press_time)cmd = "adb shell input swipe %d %d %d %d %d" % (int(src[0]), int(src[1]),int(dst[0]), int(dst[1]),press_time)print(cmd)os.system(cmd)

大功告成!!

谢谢各位。。

转载于:https://www.cnblogs.com/WoLykos/p/9241448.html

跳一跳小外挂(附完整代码)相关推荐

  1. 基于汇编实现的欢乐QQ堂小游戏 附完整代码

    本次实现制作了汇编版的QQ堂,使用了VGA 320x200 256色视频显示, FAT12文件系统.时钟中断,nasm + gcc联合编译,通过端口设置调色板.其中除了AI,游戏界面.逻辑等均由汇编实 ...

  2. 毕业设计:基于汇编实现的欢乐QQ堂小游戏 附完整代码

    本次实现制作了汇编版的QQ堂,使用了VGA 320x200 256色视频显示, FAT12文件系统.时钟中断,nasm + gcc联合编译,通过端口设置调色板.其中除了AI,游戏界面.逻辑等均由汇编实 ...

  3. html页面数字滚动,Vue.js大屏可视化数据数字滚动翻转跳转效果(通俗易懂附完整代码)...

    原文:Vue.js大屏可视化数据数字滚动翻转跳转效果(通俗易懂附完整代码) 大屏数字滚动翻转效果来源于最近工作中element后台管理页面一张大屏的UI图,该UI图上有一个模块需要有数字往上翻动的效果 ...

  4. php跳一跳小游戏,原生JS实现的跳一跳小游戏完整实例

    本文实例讲述了原生JS实现的跳一跳小游戏.分享给大家供大家参考,具体如下: 以下说的是闲暇编写的一个小游戏--跳一跳,类似于微信的跳一跳,大体实现功能有: 1.先随机生成地图: 2.按住按钮释放后完成 ...

  5. html实现跳跳棋游戏,原生JS实现的跳一跳小游戏完整实例

    本文实例讲述了原生JS实现的跳一跳小游戏.分享给大家供大家参考,具体如下: 以下说的是闲暇编写的一个小游戏--跳一跳,类似于微信的跳一跳,大体实现功能有: 1.先随机生成地图: 2.按住按钮释放后完成 ...

  6. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一) 本文目录: 一.[旋转的精灵女孩]案例运行效果 二.Three.js简介 三.Three.js代码正常运行显示条件 (1)不载入 ...

  7. 当微信遇上 10 万战绩的「跳一跳」外挂,程序员还能“逍遥”多久?

    点击上方"CSDN",选择"置顶公众号" 关键时刻,第一时间送达! 一款热门游戏,普通用户玩的是乐趣,而对于程序员来说,走的是非常人之路,以各种花样技术方法获取 ...

  8. H5版仿制微信跳一跳小游戏,网页版仿微信跳一跳小游戏源码,实现了跳一跳的基本核心功能

    H5版仿制微信跳一跳小游戏,网页版仿微信跳一跳小游戏源码,实现了跳一跳的基本核心功能 完整代码下载地址:H5版仿制微信跳一跳小游戏,网页版仿微信跳一跳小游戏源码 运行截图 Project setup ...

  9. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三) 本篇目录: 六.完整构建整个[旋转的精灵女孩]实例 (1).新建.启动webGL工程空间 (2).构建项目的目录层次结构 (2. ...

最新文章

  1. 计算机与材料成型与控制方面的应用,广东科技学院
  2. 小玩流媒体播放——HLS流媒体点播系统
  3. Codeforces 833B 题解(DP+线段树)
  4. Android GIS开发系列-- 入门季(11) Callout气泡的显示
  5. boost::mp11::mp_set_push_back相关用法的测试程序
  6. 计算机用的机械硬盘的工作原理,为啥一震就坏?机械硬盘的构造原理是什么?...
  7. apache mesos_Apache Mesos:编写自己的分布式框架
  8. 业内首款云原生技术中台产品云原生 Stack 来了
  9. hibernate mysql 读写分离_SpringBoot集成Spring Data JPA及读写分离
  10. 企业微信登陆服务器设置,企业微信怎么登入
  11. saltstackmysql return报错
  12. 内涵社区APP,一款集内涵段子,百思不得其姐,煎蛋于一身的搞笑社区
  13. 域名解析ip地址的过程
  14. 在vue项目中使用阿里云播放器
  15. TOM企业邮箱注册流程是什么,如何开通邮箱
  16. 【Linux】Ubuntu 20.04 wifi 问号连接不上解决方法
  17. 祥云杯2022 writeup
  18. 苹果手机如何用短信信息服务器,Iphone双卡双待如何发信息? 苹果双卡手机发短信的方法...
  19. IIS上解决ASP.Net第一次访问慢的处理
  20. GSMA宣布了首批2017世界移动大会-上海主题演讲嘉宾名单

热门文章

  1. 熊啸锋社群营销系列:社群营销高手不愿透露的秘密策划模型
  2. matlab在线环境
  3. 缺陷测试简介及案例分析
  4. NTC MF58 10k J3950K ±5% 玻封热敏电阻数据CSV
  5. 深度解读:云网融合的多云网络
  6. 机器学习新-统计机器学习第二版
  7. pystrich生成code128、ean13、qrcode二维码
  8. Java获取IP地址和VUE获取IP地址。
  9. k8s 出现各种问题解决方案
  10. oracle导出where,Oracle exp导出加where指定条件