大家好,我是郭立员~
前言
昨天在群里聊到一个游戏验证码,如下图所示:

由于这个验证比较简单,今天我们不讲怎么过这个验证,而是讲一个有意思的,怎么才能开发出这种防挂机的验证。
下面我就用按键模拟一下这个验证的实现过程。
一、准备工作
①、一张背景图

②、多张物品图片

二、游戏验证的展示
①、使用设备雷电9模拟器,横屏分辨率1280*720
经测试这个分辨率可以准确获取到用户点击的坐标。
②、使用悬浮窗展示验证
三、原理
①、验证的图片展示

验证分为3个区域,背景图、题目区和答题区。
选出3个物品,显示在题目区的位置,然后在答题区随机生成3个坐标,然后让选出的3个物品显示在答题区。
为了书写代码方便,我只选择的3个物品图,省去了从众多物品随机选择的过程,简化了代码逻辑。
FW.NewFWindow("浮窗名", 100, 50, 885, 613)
FW.AddImageView "浮窗名", "背景图片", "/sdcard/pictures/验证图/bg.jpg", 0, 0, 885, 613
FW.AddImageView "浮窗名", "图1", "/sdcard/pictures/验证图/1.jpg", 370,100, 70, 70
FW.AddImageView "浮窗名", "图2", "/sdcard/pictures/验证图/2.jpg", 490, 100, 70, 70
FW.AddImageView "浮窗名", "图3", "/sdcard/pictures/验证图/3.jpg", 610, 100, 70, 70
Dim rect = {100,270,700,500}
For i = 1 To 3
Dim sj1 = int((rect[3]-rect[1]+1)*rnd())+rect[1]
Dim sj2 = int((rect[4]-rect[2]+1)*rnd())+rect[2]
FW.AddImageView "浮窗名", "答案"&i, "/sdcard/pictures/验证图/"&i&".jpg", sj1, sj2, 70, 70
Next
FW.Show ("浮窗名")
②、知道自己出的验证的答案
这个验证的答案就是在答题区随机生成的3个坐标,我们需要用数组记录下来。
需要注意相对坐标和绝对坐标的转换,随机数是相对于背景图片,存入数组的坐标要是相对于手机屏幕的,所以在代码中我加上偏移。
Dim arr = {null}
Dim rect = {100,270,700,500}
For i = 1 To 3
Dim sj1 = int((rect[3]-rect[1]+1)*rnd())+rect[1]
Dim sj2 = int((rect[4]-rect[2]+1)*rnd())+rect[2]
arr[i]={null}
arr[i][1] = sj1 +100
arr[i][2]= sj2 +50
Next
TracePrint "答案是:",encode.TableToJson(arr)
输出结果
答案是:[[696,486],[439,454],[439,521]]
③、获取用户的点击坐标,并在图片上面做上标记

Dim ans = {null}
For i = 1 To 3
Dim 坐标表 = zm.CatchTouchPoint(1)
FW.AddTextView "浮窗名", "坐标" & i, i, 坐标表[1][1] - 100, 坐标表[1][2] - 50, 30, 30
ans[i]={null}
ans[i][1] = 坐标表[1][1]
ans[i][2]= 坐标表[1][2]
Next
TracePrint "用户的答案是:",encode.TableToJson(ans)
如果你使用过“获取用户点击坐标”这个命令,可能会发现我并没有同时获取3个点的坐标,而是每次获取1个点坐标,重复执行3次。
这是因为“获取用户点击坐标”命令是阻断型的命令,如果一次性获取3个点的坐标,就没法在用户点一个坐标就标注一个位置。
使用单次获取1个坐标,就能加上标注位置的功能了。
当用户点击完,同样用数组存储上每次点击的坐标值。
用户的答案是:[[730,522],[472,488],[479,555]]
④、验证用户点击的正确性
对于程序来说,验证点击的正确性就是比对两个数组的相似程度。
答案是:[[696,486],[439,454],[439,521]]
用户的答案是:[[730,522],[472,488],[479,555]]
这里我没有说是比对两个数组是否相同,而是比对相似程度,就是因为用户很难点到我们生成的坐标点上,只要用户点击的坐标点接近我们设置的就判定为有效。
看一下具体图解:

答案点是左上角的点,有效区域是70*70,也就是用户点击的坐标和答案点的差值在0-70就是有效点击。
代码如下:
For i = 1 To 3
If 0 < ans[i][1] - arr[i][1] < 70 and 0 < ans[i][2] - arr[i][2] < 70 Then
Else
TracePrint "用户答案错误"
Exit For
End If
If i = 3 Then
TracePrint "用户答案正确"
End If
Next
四、最终效果展示:
