目前大热的微信小游戏“跳一跳”令很多人趋之若鹜,更有脑洞大开的爱好者开发出了各种“外挂”。今天,小编就为您解读一下这些“神奇”的“外挂”背后的算法。
常规思路
找到棋子的x,y
找到目标平台中心点的x,y
计算两点像素距离(橙色)
按压时间 = 距离 × 系数
缺点:这个方法得到的结果是直线的像素距离,于是不同屏幕尺寸下,感官上相同的跳跃距离,像素距离确是不同的,这就需要手动设置不同系数(一大堆的congif)。
那么能不能更直观地设置跳跃所需要的时间呢?
1.UI自适应
实测 4:3/16:9/2:1 三类屏幕比例,得到如下结果。
游戏内UI
游戏主画面按宽度适配,垂直居中。
其他界面元素四角定位,比如关闭右上角,分数左上角。
这里是一个重要信息,游戏主画面是根据宽度缩放的。
再来一局
核心UI是16:9,然后fit到窗口。
这样就能找准按钮的位置了。
2.简化方案
从绝对距离到比例关系
根据我们上一节提到的宽度适配原则。
假设两个方块离得非常远,刚好斜着隔开整个屏幕,跳跃时间假设是1秒。
那么如果把目标平台移近一半,那跳跃需要时间是不是就是0.5秒呢?
也就是说 把跳跃距离,从像素的绝对距离,转化为相对的比例关系。
从斜边到邻边
另外,因为游戏视角固定。
所以斜边的比例关系,可以用X轴的水平的比例关系替代。
那么,跳跃距离就转化为起点到目标的水平距离和屏幕宽度的正比例关系。
不再需要获取Y轴位置。
那么,接下来总结一下公式吧。
按压时间=跳全屏宽度需要的时间× (起点和目标的横向距离/屏幕宽度)
distanceX = abs(board_x-piece_x) #起点到目标的水平距离
shortEdge = min(im.size) #屏幕宽度
jumpPercent = distanceX/shortEdge #跳跃百分比
jumpFullWidth = 1700 #跳过整个宽度 需要按压的毫秒数
press_time = round(jumpFullWidth*jumpPercent) #按压时长
优点:省略了所有 Y 轴的取值,并且自适应所有设备。(实测 4:3/16:9/2:1都成功。原方案的所有配置文件都不需要了。)
图为X、Y轴坐标的测算
3.误差的估算
上一次从另一个方向跳过来且未落在中心
可能下次起跳位置需要修正(紫色)
不过误差并不大,除非当前格子很大。
加上还有模拟器卡顿或者其他细微的影响,所以这点偏移基本忽略,目前没有看到方案适配这个。
之所以不必纠结误差,因为即使每次偏移中心10%,不考虑平台大小,也要连续累积10次才会掉落。
也就是棋子要往一个方向跳10次,概率(1/2)^(10-1)=1/512,其实很低的。
实际过程中,由于终端性能造成的延迟对分数影响更大,所以,我们依赖性能更高的终端来运算。因此,我们看到的很多朋友们都用PC来运行脚本并用控制手机进行游戏。
閱讀更多 電子曰 的文章