大家好,我是公众号3分钟学堂的郭立员~
前言
昨天群里有群友问这个问题今天就来说一说~
游戏背包大多都是排列整齐的方格子,所以我们遍历背包物品其实就是遍历每个方格子的物品,我在网上随便找了一个背包图片。
下面我就把遍历背包物品所涉及的知识点详细的给大家讲一下:
一、识别物品的常用命令
对于按键来说,屏幕画面上的任何东西都可以视为图片,所以识别背包物品本质还是识别图片,常用的方式就是找图命令或者多点找色命令。
而涉及到遍历了,说明是有多个要识别的图片,所以这时候找图和多点找色就有些不同了。
对于找图命令来说,通常使用的是找“单图”的功能,并且找图命令也很少用到返回值。
是不是有些奇怪,找图命令不是有返回intx,inty坐标吗,为啥说它很少用到返回值,其实找图得到的坐标值intx,inty,只是找图命令对变量的重新赋值,这就相当于下面这种代码写法
dim intx
intx=5
traceprint intx
在代码中intx=5,就是给变量intx重新赋值5,找图命令就是把找图得到的坐标通过赋值的方式给了intx,inty。
当翻看找图命令的介绍时会发现找图命令是有返回值的,不过写法是不同的。
普通找图的写法:
Dim intX, intY
FindPic 0, 0, 0, 0, "Attachment:1.png","000000",0, 0.8, intX, intY
If intX >-1 then
TracePrint "找到啦,坐标是"&intX&","&intY
Else
TracePrint "没找到"
End If
带返回值写法:
Dim intX, intY,返回值
返回值=FindPic(0, 0, 0, 0, "Attachment:1.png|Attachment:2.png","000000",0, 0.8, intX, intY)
'需要用函数返回值时要加个括号
If 返回值>-1 then
TracePrint "找到的图片序号为"&返回值&",坐标为"&intX&","&intY
Else
TracePrint "全部没找到"
End If
两种写法的相同之处:
findpic命令的所有参数都一样
两种写法的不同之处:
①有返回值的写法需要把所有参数放入到括号里面
findpic(参数1,参数2……)
②图片部分是有多个图片,并且每个图片之间用竖线“|”分隔。
"Attachment:1.png|Attachment:2.png"
重点来了,找图命令的返回值到底是什么?
返回找到的图片的序号,从0开始索引.如果没找到返回-1 ,当我知道图片序号后,通过反推就知道是序号对应的是哪张图片了。
很明显如果找多张图片,这种带有返回值的写法非常适合。
那么多点找色有没有这种写法呢?
没有!
但是有一种方法对于找“单图”和多点找色都适用:循环找图找色法
找图:就是截取一张图片,按照图片特征去指定范围内比对
多点找色:选取多特征点颜色坐标,在指定范围内找到相同特征的颜色点。
这种是单一执行的方式,循环执行就是每个循环周期更换一张图或者一组多特征点颜色坐标。
具体思路是预先准备多个图片或者多组多特征点颜色坐标,把它们融入到循环之中,如循环找图:
预先把图片名称存入到数组中,然后通过for循环的计次变量“i”控制每次循环按顺序调用数组里面图片名称。
dim 图片={"1.png","2.png","3.png","4.png","5.png","6.png"}
Dim intX, intY
For i = 1 To 6
FindPic 0, 0, 0, 0, "Attachment:"&图片[i],"000000",0, 0.8, intX, intY
If intX >-1 then
TracePrint "找到啦,坐标是"&intX&","&intY
Else
TracePrint "没找到"
End If
Next
多点找色要复杂一些:
Dim IntX,IntY
FindMultiColor 0,0,0,0,"FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757",0,0.9,intX,intY
If intX > -1 Then
TracePrint "找到啦,坐标在"&intX&","&intY
Else
TracePrint "没找到"
End If
多点找色的颜色特征是2个参数
①主色:"FFFFFF"
②多特征颜色坐标:"4|1|2F9772-000000|123456-101010,3|7|378757"
Dim 颜色1={"FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"}
Dim 颜色2={"FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"}
Dim 颜色3={"FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"}
Dim 颜色信息={颜色1,颜色3,颜色3}
Dim IntX,IntY
For i = 1 To 3
FindMultiColor 0,0,0,0,颜色信息[i][1],颜色信息[i][2],0,0.9,intX,intY
If intX > -1 Then
TracePrint "找到啦,坐标在"&intX&","&intY
Else
TracePrint "没找到"
End If
Next
颜色信息这里我是分开3个数组写的,有些作者喜欢写在一起,看个人习惯,也可以这样写:
Dim 颜色信息={_
{"颜色1","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"},_
{"颜色2","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"},_
{"颜色3","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"}_
}
Dim IntX,IntY
For i = 1 To len(颜色信息)
FindMultiColor 0,0,0,0,颜色信息[i][2],颜色信息[i][3],0,0.9,intX,intY
If intX > -1 Then
TracePrint "找到啦,坐标在"&intX&","&intY
Else
TracePrint "没找到"
End If
Next
当然如果命名比较有规律如果图片1,图片2,图片3……,也可以使用拼接的方式,如:图片&i
了解循环找图找色,也给它封装个函数,加个返回值
traceprint 找多色()
Function 找多色()
Dim 颜色信息={_
{"颜色1","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"},_
{"颜色2","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"},_
{"颜色3","FFFFFF","4|1|2F9772-000000|123456-101010,3|7|378757"}_
}
Dim IntX,IntY
For i = 1 To len(颜色信息)
FindMultiColor 0,0,0,0,颜色信息[i][2],颜色信息[i][3],0,0.9,intX,intY
If intX > -1 Then
TracePrint "找到啦,坐标在"&intX&","&intY
找多色 = i
Exit Function
Else
TracePrint "没找到"
End If
Next
End Function
写到这里基本把遍历找多图和找多个“多点找色”写完了,至于使用哪种,全看你个人喜好了。
二、遍历所有格子的范围坐标
(1)坐标范围的表示方法
在按键里面涉及到坐标范围都是用两个坐标点的4个数值表示,如下图
具体来说会取坐标范围的左上角坐标和右下角坐标组成范围(x1,y1,x2,y2)
如果我们现在已知左上角坐标(x1,y1)和范围的宽度和高度,能不能写出按键所需的坐标范围,如图所示:
范围需要(x1,y1,x2,y2)的写法,但是(x2,y2)是未知的坐标(?,?),需要我们计算出来得出:
x2=x1 x
y2=y1 y
所谓范围坐标(x1,y1,x2,y2)就变成了(x1,y1,x1 x,y1 y)
为啥要这样写?其实是为了减少变量的数量。
一个背包有大量的格子,每个格子的宽度和高度是一样的,所以x,y是固定值(常量)
在通常写法中,如果想要把上面第一个格子的红色范围,移动覆盖第二个范围,修改(x1,y1,x2,y2),而刚刚的写法(x1,y1,x1 x,y1 y)中由于x和y是固定值,只需要修改x1,y1即可以实现坐标范围的偏移。
(2)获取所有格子左上角点的坐标
经过简化后,我们要遍历的每一个格子的范围坐标,就变成了遍历每个格子左上角点的坐标,注意点⑧后就换行了,因为它是第一行最后一个左上角的点,千万不要把最后一个右上角点标上。
这是一个8*5的背包,一共有5行8列的格子,现在的要求是遍历所有格子左上角的坐标。
点①作为已知的坐标点(x1,y1)属于一个固定值(常量)
点②是在点①的基础上加一个格子的宽度x,之后每个格子都是在前一个格子的基础上 x
点⑧是在点①的基础上加一个格子的高度y,之后换行的每个格子都是在上面一个格子的基础上 y
假定点①的坐标是(x1,y1),写一个循环的代码把所有格子的左上角点的坐标都遍历出来,注意一定要写上点①,很容易忽略掉。
先写第一行格子的代码:为了方便调试输出我写上具体的数字
Dim x1=10
Dim y1=10
Dim x=80
Dim y=80
For i = 0 To 7
TracePrint x1 x*i,y1
Next
这里有一个有意思的知识,就是循环是0到7,而不是1到8,按理说我要写的是点①到点⑧的左上角坐标,循环不应该是1到8吗?
并不是,这里起始点没有点0,是从点①开始的,那么点①和起始点是同一个点,点①的坐标就是x1 0*x,点⑧和点①相差7个x,所以循环写0-7比较合适。
一行格子遍历完了,接下来是第二行、第三行……在列的方向上的遍历了。
5行格子,循环写0到4,一样的道理就不重复了。
Dim x1=10
Dim y1=10
Dim x=80
Dim y=80
For j = 0 To 4
For i = 0 To 7
TracePrint x1 x*i,y1 y*j
Next
Next
通过双重循环之后,就得到所有格子左上角点的坐标了。
(3)把范围坐标和遍历左上角坐标结合起来
有没有发现范围坐标用到变量x1,y1,x,y,而遍历左上角坐标也是用到变量x1,y1,x,y,这不巧了吗~
遍历左上角的坐标写法是:x1 x*i,y1 y*j
范围坐标 x1,y1,x1 x,y1 y
把左上角的坐标代入到范围坐标中,也就是x1全部换成x1 x*i,把y1全部换成y1 y*j
结果是:x1 x*i,y1 y*j,x1 x*i x,y1 y*j y
有强迫症的朋友可以合并一下同类项
x1 x*i,y1 y*j,x1 x*(i 1),y1 y*(j 1)
把它放到循环里面
Dim x1=10
Dim y1=10
Dim x=80
Dim y=80
For j = 0 To 4
For i = 0 To 7
TracePrint x1 x*i,y1 y*j,x1 x*(i 1),y1 y*(j 1)
Next
Next
输出结果:
每循环一次就更换一个范围坐标,也就是下一个格子的范围,当所有循环结束了,就遍历了所有格子的范围了。
三、遍历背包
在第一步我讲了遍历一个格子图片的方法,在第二步我讲了遍历每一个格子的范围坐标,这两步一结合就是遍历整个背包物品了。
最后一步的代码我就不写了, 不然很多人就直接拿代码走人了,根本不看讲解过程,也不给我文章点赞啥的。。。
提示一点,把遍历一个格子图片的代码放入到遍历范围坐标的代码里面就行。
=正文完=