关于Python玩“跳一跳” iOS+Win 硬件实现的介绍?

Python014

关于Python玩“跳一跳” iOS+Win 硬件实现的介绍?,第1张

原项目地址:wangshub/wechat_jump_game

教你用Python来玩微信跳一跳

本项目源码:yangyiLTS/wechat_jump_game_iOS

目前已有的iOS跳一跳辅助需要macOS环境下的WebDriverAgentRunner。而现在介绍的方法在Windows环境下物理实现,不需要macOS也不需要越狱。

先上效果

运行环境&工具

Python 3.6 in Windows

Python Pillow库

局域网环境

iToools Airplayer

树莓派或arduino (本文使用树莓派)

SG90 舵机

杜邦线、纸板

一小块海绵

橙子或其它多汁水果(可选)

基本思路使用iOS自带Airplay服务将游戏画面投影到电脑上。使用Pillow库截取电脑屏幕,获得游戏画面。分析图片,计算出跳跃距离,乘以时间系数获得按压时间。将按压时间发送至树莓派,树莓派控制舵机点击手机屏幕。原理&步骤

舵机&控制器部分

树莓派(OS:Raspbian Jessie)连接上局域网,下载servo_control.py到树莓派。拿一根杜邦线粘在舵机的摆臂上,并且固定好舵机在纸板上,如图:

取一小块海绵,约10mm*10mm*5mm,不必太精确。海绵中间挖一个小洞。大概是这样:

海绵上滴水浸透,放在手机屏幕上“再来一次”的位置。杜邦线的另一头插进橙子。(触发电容屏需要在屏幕上形成一个电场,我尝试过连接干电池负极的方案,但是效果不理想,最后不得已拿了室友的一个橙子。当然,一直捏着或者含着导线也是可以的。)

舵机连接上树莓派,电源使用5v(Pin #04,Pin #06),舵机控制线接在GPIO18(Pin #12)。

需要根据实际安装位置调整舵机高点和低点位置(范围: 2.5~12.5)

servo_down = 3.8 servo_up = 5

最终效果

Windows 部分

下载Airplayer(免安装,暂无捆绑)

配置Airplayer,画质什么的统统调到最高。启动iPhone上的Airplay,然后可以在电脑上看到iPhone画面,游戏运行时需要Airplayer全屏显示。

安装Pillow库,本文使用Pillow库的ImageGrab截屏,截屏代码:

im = ImageGrab.grab((654, 0, 1264, 1080)) im.save('a.png', 'png')

下载wechat_jump_auto_iOS_Win.py,我的显示器分辨率是1920*1080,手机是iPhone7。如果使用不同的设备需要更改时间系数等参数。

由于Airplay传输画面时会压缩,获取的游戏画面会有颜色偏差。我修改了原算法的一些参数,增大了颜色上的宽容度,在测试中已经达到一个比较好的准确率。

wechat_jump_auto_iOS_Win.py 计算出跳跃距离后,会调用socket库把跳跃时间发送到树莓派上,其中ip地址需要修改为实际树莓派的ip地址。

ip_addr = 'rasp_ip'

运行打开游戏画面,Airplayer窗口全屏树莓派上运行servo_control.py ,监听9999端口,等待Win的计算结果Windows运行wechat_jump_auto_iOS_Win.py海绵放在“再来一次”的位置可以自动重新开始,然后就会一直自动刷分问题&其它

由于是物理点击屏幕,会产生一定的操作误差。操作误差由时间常数误差、舵机运动时间、杜邦线触点插进海绵的深度等等因素引起。而当前使用的算法在一种情况下会出现误差叠加的问题。

Z形路径误差累积过程

舵机的摆动角度和时间系数没有绝对的数值,需要慢慢尝试,当前使用的时间系数是2.43。

可以使用arduino + pyfirmata组合控制舵机,成本比较低,不需要网络传输计算结果。因为我的arduino前些天送给了女票,所以还没有使用arduino的方案。

这个游戏在跳了200+次之后方块会变的非常小(如题图),已经不是普通人类所能做到的。研究了外挂之后才知道手玩高分有多难,大家还是不要刷分了,会没朋友的。

1、打开手机的开发者选项,本人小米手机,系统android 7.0(miui 9.1),设置->我的设备->全部参数(点击miui版本5次,即可开启开发者模式)

2、设置->更多设置(倒数第三个就是开发者选项)->开启USB调试,使用数据线连接手机和电脑

3、在电脑上安装adb驱动,下载地址:http://download.csdn.net/download/guochao198975/10189371

打开安装软件

4、点击Device Manager,选择usb连接的设备,单击Install,安装前会有一个叹号,安装后如下图,会出现Android Phone.

如果没有出现USB连接的设备,则说明手机没有进入usb调试模式,或者手机没有连接好.如果一直有感叹号说明驱动没有安装成功.

5、安装好驱动后,还需要在电脑上下载adb工具,这里注意一定要下载1.0.31以上的版本,网上很多能下载的高的版本都是假的(实际很多都是1.0.26),

推荐下载地址:http://download.csdn.net/download/guochao198975/10188060(版本为1.0.39)

解压工具到自己指定的目录下,我解压的目录是C:UsersAaronadb

6、我们还需要为adb工具配置环境变量,配置的目的是为后续python程序正常调用adb工具做准备,如果不配置,那么必须把adb工具和python文件放到同一目录下(不建议这么做).

右键计算机,点击属性->高级系统设置->环境变量,在系统变量中的Path中添加自己的adb工具目录路径.(注意:我这里是win7系统,其他系统可行百度,大同小异)

7、这里adb就可以正常运行了,打开cmd,输入 abd version,可以正常显示你的adb工具版本号

输入adb devices 可正常显示 abd设备列表.那么就表示一切顺利.

可是现实情况往往都不怎么一帆风顺.这中间我遇到了两种问题.

第一个问题是提示"adb not found"

解决方法如下,右键计算机->属性->设备管理器->如下图右键Android Composite ADB Interface,选择详细信息,属性中选择硬件Id,查看值中如下图截图的四个字符(实际是十六进制的编码),我的是"2717",在自己用户的主目录下,找到.android目录(注意前面的"."),查看是否存在adb_usb.ini文件,如果存在修改即可,如果不存在需要新建一个.用文本编辑器打开,打开后输入"0x2717"image.png,保存即可.重新拔插数据线,

此问题解决,可再次在cmd中查看adb devices,即可正常显示设备列表.

第二个问题是虽然可以正常显示驱动列表,但是状态是"adb offline ",此问题就是为什么选在adb版本1.0.31以上的原因了,这是之前adb工具真的安卓4以上手机的bug,在1.0.31以上版本已经解决.

8、在cmd上输入adb kill-server 然后重新拔插usb线之后,就可以连接adb 了

9、这时我们可以开始部署python环境了,具体怎么部署python环境,我就不说明了,网上资料很多,相信看此教程的都有点python基础,没有的话自行百度.

这里需要强调的是需要引用一些类库.(如果提示ImportError: No module named 'numpy'

表示,没有安装numpy 或没有安装好。使用命令pip install numpy,即可自动安装)

10、下载微信跳一跳python程序.下载地址:http://download.csdn.net/download/guochao198975/10189554

11、在手机端打开微信跳一跳.在电脑端命令行运行wechat_jump_auto.py.按照提示,输入y,回车,神奇的事情发生了,微信跳一跳的小人自动蹦了.(温馨提示不要太高分哦~~~~)

python学习网,大量的免费python视频教程,欢迎在线学习!

Python程序开发之简单小程序实例

(11)小 游戏 -跳动的小球

一、项目功能

用户控制挡板来阻挡跳动的小球

二、项目分析

根据项目功能自定义两个类,一个用于控制小球在窗体中的运动,一个用于接收用户按下左右键时,挡板在窗体中的运动。在控制小球的类中,我们还需要考虑当小球下降时,碰到挡板时的位置判断。

三、程序源代码

源码部分截图:

源码:

#!/usr/bin/python3.6

# -*- coding: GBK -*-

#导入相应模块

from tkinter import *

import random

import time

#自定义小球的类 Ball

class Ball:

# 初始化

def __init__(self,canvas,paddle,color):

#传递画布值

self.canvas=canvas

#传递挡板值

self.paddle=paddle

#画圆并且保存其ID

self.id=canvas.create_oval(10,10,25,25,fill=color)

self.canvas.move(self.id,245,100)

#小球的水平位置起始列表

start=[-3,-2,-1,1,2,3]

#随机化位置列表

random.shuffle(start)

self.x=start[0]

self.y=-2

self.canvas_heigh=self.canvas.winfo_height()#获取窗口高度并保存

self.canvas_width=self.canvas.winfo_width()

#根据参数值绘制小球

def draw(self):

self.canvas.move(self.id,self.x,self.y)

pos=self.canvas.coords(self.id)#返回相应ID代表的图形的当前坐标(左上角和右上角坐标)

#使得小球不会超出窗口

pad=self.canvas.coords(self.paddle.id)#获取小球挡板的坐标

if pos[1]=self.canvas_heigh or(pos[3]>=pad[1] and pos[2]>=pad[0] and pos[2]