Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更新距离与时间的计算关系(根据跳一跳源码计算) #841

Merged
merged 2 commits into from
Feb 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/1920x1080/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"press_coefficient": 1.392,
"piece_base_height_1_2": 20,
"piece_body_width": 70,
"head_diameter": 60,
"swipe": {
"x1": 500,
"y1": 1600,
Expand Down
35 changes: 20 additions & 15 deletions wechat_jump_auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
最后:根据两点的坐标算距离乘以系数来获取长按时间(似乎可以直接用 X 轴距离)
"""
from __future__ import print_function, division

import math
import os
import random
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:
Expand All @@ -31,13 +33,11 @@
print('请检查项目根目录中的 common 文件夹是否存在')
exit(-1)


VERSION = "1.1.1"
VERSION = "1.2.1"

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


# Magic Number,不设置可能无法正常执行,请根据具体截图从上到下按需
# 设置,设置保存在 config 文件夹中
config = config.open_accordant_config()
Expand All @@ -48,6 +48,8 @@
piece_base_height_1_2 = config['piece_base_height_1_2']
# 棋子的宽度,比截图中量到的稍微大一点比较安全,可能要调节
piece_body_width = config['piece_body_width']
# 图形中圆球的直径,可以利用系统自带画图工具,用直线测量像素,如果可以实现自动识别圆球直径,那么此处将可实现全自动。
head_diameter = config.get('head_diameter', 60)


def set_button_position(im):
Expand All @@ -58,17 +60,20 @@ def set_button_position(im):
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
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 是最小的按压时间
# 计算程序长度与截图测得的距离的比例
scale = 0.945 * 2 / head_diameter
actual_distance = distance * scale * (math.sqrt(6) / 2)
press_time = (-945 + math.sqrt(945 ** 2 + 4 * 105 * 36 * actual_distance)) / (2 * 105) * 1000
Copy link
Collaborator

@chenjiandongx chenjiandongx Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是写死了吗,数字固定的?945 这个就是根据源码得来的?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chenjiandongx e.BOTTLE = {
headRadius: .945,
bodyWidth: 2.34,
bodyDepth: 2.34,
bodyHeight: 3.2,
reduction: .005,
minScale: .5,
velocityYIncrement: 15,
velocityY: 135,
velocityZIncrement: 70
})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

下面的计算公式其实是在解一个一元二次方程

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实不是写死的,只是我把源码略掉了math.min的情况,源码对速度做了限制

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@baolw 可以贴一下源码里时间到速度的计算公式吗?

Copy link
Contributor Author

@baolw baolw Jan 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var i = (Date.now() - t.mouseDownTime) / 1e3;
t.bottle.velocity.vz = Math.min(i * d.BOTTLE.velocityZIncrement, 150), t.bottle.velocity.vz = +t.bottle.velocity.vz.toFixed(2), t.bottle.velocity.vy = Math.min(d.BOTTLE.velocityY + i * d.BOTTLE.velocityYIncrement, 180), t.bottle.velocity.vy = +t.bottle.velocity.vy.toFixed(2), t.direction = new o.Vector2(t.nextBlock.obj.position.x - t.bottle.obj.position.x, t.nextBlock.obj.position.z - t.bottle.obj.position.z), t.direction.x = +t.direction.x.toFixed(2), t.direction.y = +t.direction.y.toFixed(2);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@baolw 能问下二次方程代表的什么吗?谢谢!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个公式应该也不是很精确,不知道有没有考虑台子压缩高度,我解出的解析解带虚数,不好用js解,但是可以用线性近似解 t=(1/28)d,js中测试过可以确保无限combo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,确实没考虑

press_time = max(press_time, 200) # 设置 200ms 是最小的按压时间
press_time = int(press_time)
cmd = 'adb shell input swipe {x1} {y1} {x2} {y2} {duration}'.format(
x1=swipe_x1,
Expand Down Expand Up @@ -97,7 +102,7 @@ def find_piece_and_board(im):
scan_start_y = 0 # 扫描的起始 y 坐标
im_pixel = im.load()
# 以 50px 步长,尝试探测 scan_start_y
for i in range(int(h / 3), int(h*2 / 3), 50):
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]
Expand Down Expand Up @@ -129,7 +134,7 @@ def find_piece_and_board(im):
piece_y = piece_y_max - piece_base_height_1_2 # 上移棋子底盘高度的一半

# 限制棋盘扫描的横坐标,避免音符 bug
if piece_x < w/2:
if piece_x < w / 2:
board_x_start = piece_x
board_x_end = w
else:
Expand Down Expand Up @@ -162,19 +167,19 @@ def find_piece_and_board(im):
# 从上顶点往下 +274 的位置开始向上找颜色与上顶点一样的点,为下顶点
# 该方法对所有纯色平面和部分非纯色平面有效,对高尔夫草坪面、木纹桌面、
# 药瓶和非菱形的碟机(好像是)会判断错误
for k in range(i+274, i, -1): # 274 取开局时最大的方块的上下顶点距离
for k in range(i + 274, i, -1): # 274 取开局时最大的方块的上下顶点距离
pixel = im_pixel[board_x, k]
if abs(pixel[0] - last_pixel[0]) \
+ abs(pixel[1] - last_pixel[1]) \
+ abs(pixel[2] - last_pixel[2]) < 10:
break
board_y = int((i+k) / 2)
board_y = int((i + k) / 2)

# 如果上一跳命中中间,则下个目标中心会出现 r245 g245 b245 的点,利用这个
# 属性弥补上一段代码可能存在的判断错误
# 若上一跳由于某种原因没有跳到正中间,而下一跳恰好有无法正确识别花纹,则有
# 可能游戏失败,由于花纹面积通常比较大,失败概率较低
for j in range(i, i+200):
for j in range(i, i + 200):
pixel = im_pixel[board_x, j]
if abs(pixel[0] - 245) + abs(pixel[1] - 245) + abs(pixel[2] - 245) == 0:
board_y = j + 10
Expand All @@ -191,7 +196,7 @@ 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)
false_value, default_value)
i = input(prompt)
if not i:
return default
Expand Down