上篇完成了强制性的新手引导,就是等待某个界面出来,再进行点点点,加上等待时间配合就可以完成。完成新手引导后,下一步是领取奖励补充一下游戏资源,需要模拟下点击图标进入不同的界面后再领取奖励的行为,比如1.任务完成,点击任务描述获得任务奖励2.进入日常奖励界面,点击每日免费的奖励3.进入其他的活动界面,如签到之类的玩法,每天自动拿些低保。游戏界面涉及到的内容一般分为UI层和游戏层,UI层是平面显示的东西,大部分的结构不会发生很大的变化;游戏层是一个沙盘或者比较大的操作空间,有滑动 ,随机出现和随机消失,元素显示也会比较自由;目前考虑的是先完成一些UI层图标的点击处理,后续再加入游戏层的操作。项目图片不宜直接放出,大概模拟下UI的布局,形容下怎么准确的识别到需要点到的图标。
一、UI界面的图标定位与点击设置
(UI部分布局图)
类似上面的布局,正常的想法比如需要点击邮件的图标,那么就把邮件的图标单独的圈出来识别,然后再进行点击。
但是个别游戏中的图标具有统一的规格或者相同的形状,就会导致图片识别错误。所以识别UI最好还是加上比较好识别的参考物,或者多个图标的整体截图再设置点击的锚点,这样会大大增加图片的识别准度 。(如下如红色框内为截图需要识别的图片会比上面单独的图标更加容易识别)
截取红色区域内的图片位置进行识别,双击截图打开图片设置,同一张图片设置锚点1、2、3的点击可以打开聊天界面,4、5、6分别打开背包、邮件、联盟,同一张图片还可以重复使用,也节省了保存图片的空间,其他任务、地图之类的图标也是类似的截图和设置,经过测试后逐个完善界面的点击方法。
BasicsConsoleSys.py脚本中加入点击图标打开界面、关闭界面的方法
#--基础功能类--
class BasicsConsoleSys:
#----------
#打开当前一级界面;界面名字,功能后面补全
def OpenScence(self,scenceName):
if scenceName =="地图":
self.CheckAndClikeImage(Template(r"tpl1647456292354.png", target_pos=4, record_pos=(0.01, 0.787), resolution=(549, 966)),0.5,"大地图")
elif scenceName=="英雄":
self.CheckAndClikeImage(Template(r"tpl1647456404858.png", record_pos=(-0.209, 0.82), resolution=(549, 966)),0.5,"英雄")
elif scenceName=="背包":
self.CheckAndClikeImage(Template(r"tpl1647456448722.png", record_pos=(-0.023, 0.82), resolution=(549, 966)),0.5,"背包")
elif scenceName=="邮件":
self.CheckAndClikeImage(Template(r"tpl1647456483699.png", record_pos=(0.17, 0.82), resolution=(549, 966)),0.5,"邮件")
elif scenceName=="联盟":
self.CheckAndClikeImage(Template(r"tpl1647456520081.png", target_pos=6, record_pos=(0.176, 0.821), resolution=(549, 966)),0.5,"联盟")
elif scenceName=="聊天":
self.CheckAndClikeImage(Template(r"tpl1647456566394.png", target_pos=2, record_pos=(0.072, 0.798), resolution=(549, 966)),0.5,"聊天")
elif scenceName=="任务":
self.CheckAndClikeImage(Template(r"tpl1647456639466.png", target_pos=1, record_pos=(-0.196, 0.75), resolution=(549, 966)),0.5,"任务")
elif scenceName=="头像":
self.CheckAndClikeImage(Template(r"tpl1647456716642.png", target_pos=1, record_pos=(-0.283, -0.718), resolution=(549, 966)),0.5,"打开头像")
elif scenceName=="部队详情":
self.CheckAndClikeImage(Template(r"tpl1647456716642.png", target_pos=5, record_pos=(-0.283, -0.718), resolution=(549, 966)),0.5,"部队详情")
elif scenceName=="vip":
self.CheckAndClikeImage(Template(r"tpl1647456802233.png", target_pos=8, record_pos=(-0.276, -0.729), resolution=(549, 966)),0.5,"打开vip")
elif scenceName=="燃油资源":
self.CheckAndClikeImage(Template(r"tpl1647456969522.png", target_pos=4, record_pos=(0.065, -0.772), resolution=(549, 966)),0.5,"打开燃油资源")
elif scenceName=="食物资源":
self.CheckAndClikeImage(Template(r"tpl1647457065242.png", target_pos=4, record_pos=(0.13, -0.769), resolution=(549, 966)),0.5,"打开食物资源")
elif scenceName=="钢铁资源":
self.CheckAndClikeImage(Template(r"tpl1647456969522.png", target_pos=5, record_pos=(0.065, -0.772), resolution=(549, 966)),0.5,"打开钢铁资源")
elif scenceName=="合金资源":
self.CheckAndClikeImage(Template(r"tpl1647457065242.png", record_pos=(0.13, -0.769), resolution=(549, 966)),0.5,"打开合金资源")
elif scenceName=="充值":
self.CheckAndClikeImage(Template(r"tpl1647456969522.png", target_pos=6, record_pos=(0.065, -0.772), resolution=(549, 966)),0.5,"充值")
elif scenceName=="第一建造队列":
print("点击第一建造队列")
self.CheckAndClikeImage(Template(r"tpl1647456869075.png", target_pos=5, record_pos=(-0.413, -0.576), resolution=(549, 966)),0.5,"第一建造队列")
elif scenceName=="第二建造队列":
self.CheckAndClikeImage(Template(r"tpl1647456869075.png", target_pos=8, record_pos=(-0.413, -0.576), resolution=(549, 966)),0.5,"第二建造队列")
elif scenceName=="活动":
self.CheckAndClikeImage(Template(r"tpl1647457583457.png", record_pos=(0.369, -0.665), resolution=(549, 966)),0.5,"活动")
elif scenceName=="重返都市":
self.CheckAndClikeImage(Template(r"tpl1647457562139.png", record_pos=(0.201, -0.69), resolution=(549, 966)),0.5,"重返都市")
else:
print("打开界面输入错误,找不到的界面")
#关闭一级界面,点击返回按钮
def CloseScence(self):
self.CheckAndClikeImage(Template(r"tpl1647454510626.png", record_pos=(-0.409, -0.696), resolution=(549, 966)),0.5,"返回按钮")
二、图片的识别度匹配和颜色的利用
游戏中的一些宝箱或者按钮,可能具有几个不同的状态,如宝箱有1.未开启状态2.已开启状态,按钮有1.高亮的状态(可点击)2.置灰的状态(不可点击),或者同个界面存在多个相同形状但是不同颜色的按钮。那么勾选上rgb选项和增加识别匹配度(threshold)会使类似场景的图片识别增加准确度。(AirTest的图片识别原理一些大佬的文章都有分析和较深入的介绍,这里只做简单的应用介绍)
三、一些界面功能的单独流程增加
当前游戏主界面中,已经测试过可以单独点击某个图标进入对应的系统界面了,那么根据自己的需要定制一些流程的方法,比如领取任务奖励、领取日常奖励、领取VIP的日常奖励之类的逻辑。
因为在第一次打开某个界面或者点击任务进行跳转时会触发强制性的引导,可以在新手剧情中加入对应的剧情片段,以便在触发的时候进行调用。比如首次打开VIP界面时,会有剧情教你领取日常奖励,所以每次进入VIP界面时,可以使用快速检测是否存在剧情再进行下一步的操作。
NoviceGuideSys.py增加剧情片段
#--新手指引类--
class NoviceGuideSys:
#-------------------
#检查是否存在剧情
def CheckExplainBe(self):
if basicsConsoleSys.CheckImageBe(Template(r"Image\\剧情讲解.png", record_pos=(0.033, -0.035), resolution=(542, 966)),"讲解剧情")==True:
print("存在剧情")
return True
else:
print("不存在剧情")
return False
#存在剧情时需要的点击操作;图片路径
def ClickWhenExplain(self,imagePath,imageName="图片"):
if self.CheckExplainBe()==True:
sleep(0.5)
pos = exists(imagePath)
if pos:touch(pos)
else:
print("没有找到点击的图片")
else:
print("讲解剧情不存在")
#训练勇者剧情-任务跳转后触发剧情
def NoviceGuideForTrain(self):
#点击训练营
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647453839323.png", record_pos=(0.003, 0.009), resolution=(549, 966)),1,"勇士训练营")
#点击建筑训练按钮
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647453870491.png", record_pos=(0.117, 0.175), resolution=(549, 966)),0.5,"建筑训练按钮")
#剧情时点击光圈1
self.ClickWhenExplain(Template(r"tpl1647453909211.png", record_pos=(0.003, 0.319), resolution=(549, 966)),"光圈1")
#剧情时点击光圈2
self.ClickWhenExplain(Template(r"tpl1647453958355.png", record_pos=(0.001, 0.503), resolution=(549, 966)),"光圈2")
#剧情时点击光圈3
self.ClickWhenExplain(Template(r"tpl1647453979314.png", record_pos=(0.001, 0.597), resolution=(549, 966)),"光圈3")
#点击训练按钮
sleep(1.0)
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647454023355.png", record_pos=(0.227, 0.796), resolution=(549, 966)),1,"建造按钮")
#点击返回按钮
basicsConsoleSys.CloseScence()
#VIP领取奖励剧情-打开VIP界面后触发
def NoviceGuideForVIP(self):
#剧情时点击光圈1
self.ClickWhenExplain(Template(r"tpl1647476256973.png", record_pos=(-0.003, -0.144), resolution=(549, 966)),"光圈1")
#剧情时点击光圈2
self.ClickWhenExplain(Template(r"tpl1647476307341.png", record_pos=(0.001, 0.058), resolution=(549, 966)),"光圈2")
#点击宝箱
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647475321164.png", record_pos=(0.362, -0.144), resolution=(549, 966)),1,"每日经验宝箱")
sleep(1.0)
#关闭获得奖励界面
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647475423797.png", target_pos=8, record_pos=(0.001, 0.056), resolution=(549, 966)),0.5,"关闭点数界面")
ActivitySys.py脚本增加重返都市奖励的获取
__author__ = "GH"
from airtest.core.api import *
auto_setup(__file__)
import sys
path2 = 'E:\\AirTestForSLG\\BasicsConsoleSys.air'
sys.path.append(path2)
#加载其他脚本实例
import BasicsConsoleSys
basicsConsoleSys = BasicsConsoleSys.BasicsConsoleSys()
#--活动类--包括重返都市、活动
class ActivitySys:
#=======================重返都市=======================
#h获取重返都市奖励
def GetRewardsForCity (self):
#如果领取按钮存在,则使用道具,不然就结束操作
if basicsConsoleSys.CheckImageBe_Quick(Template(r"tpl1647480471861.png", threshold=0.7, rgb=True, target_pos=5, record_pos=(0.332, -0.186), resolution=(549, 966)),"领取按钮"):
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647480471861.png", threshold=0.7, rgb=True, record_pos=(0.332, -0.186), resolution=(549, 966)),0.5,"领取按钮")
#缓冲测试使用
#sleep(1.0)
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647480732108.png", target_pos=8, record_pos=(0.005, 0.073), resolution=(549, 966)),1,"关闭奖励界面")
return self.GetRewardsForCity()
else:
print("不存在领取按钮,结束操作")
#关闭界面,独特的关闭按钮
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647480608076.png", rgb=True, record_pos=(0.414, -0.701), resolution=(549, 966)),0.5,"领取按钮")
#activitySys = ActivitySys() #单独脚本调试用
#activitySys.GetRewardsForCity() #单独脚本调试用
TaskSys.py增加任务奖励领取或者触发剧情的方法
__author__ = "GH"
from airtest.core.api import *
auto_setup(__file__)
import sys
path2 = 'E:\\AirTestForSLG\\BasicsConsoleSys.air'
path3 = 'E:\\AirTestForSLG\\NoviceGuideSys.air'
sys.path.append(path2)
sys.path.append(path3)
#加载其他脚本实例
import BasicsConsoleSys
import NoviceGuideSys
basicsConsoleSys = BasicsConsoleSys.BasicsConsoleSys()
noviceGuideSys = NoviceGuideSys.NoviceGuideSys()
#--任务类--包括主线任务、支线任务、每日任务
class TaskSys:
#判断当前是否任务场景
def CheckTaskScence(self):
if basicsConsoleSys.CheckImageBe(Template(r"tpl1647453652962.png", record_pos=(-0.203, 0.643), resolution=(549, 966)),"主线任务入口")==True:
print("存在任务入口")
return True
else:
print("不存在任务入口")
return False
#判断当前是否存在指引手指
def CheckFinger(self):
count = 0
while count<2:
if basicsConsoleSys.CheckImageBe_Quick(Template(r"手指.png", threshold=0.5, record_pos=(-0.077, 0.515), resolution=(549, 966)),"指引手指")==True:
print("存在指引手指")
return True
else:
count+=1
if count==2:
print("不存在指引手指")
return False
#判断当前是否锁住界面
def CheckRockScence(self):
#点击头像
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647452619229.png", record_pos=(-0.416, -0.729), resolution=(549, 966)),0.5,"头像")
#等待一下
sleep(2.0)
#如果没有打开就是被锁住了
if basicsConsoleSys.CheckImageBe_Quick(Template(r"tpl1647452732251.png", record_pos=(-0.001, 0.745), resolution=(549, 966)),"信息界面")==True:
print("界面没有锁住")
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647452835635.png", record_pos=(-0.407, -0.698), resolution=(549, 966)),0.5,"返回按钮")
return False
else:
print("界面被锁住了")
return True
#主线任务
def MainlineTask(self):
#判断当前是否存在任务界面
if self.CheckTaskScence()==True:
print("已经找到任务入口,需要点击")
#连续点击4次任务
count=0
while count<4:
basicsConsoleSys.CheckAndClikeImage(Template(r"tpl1647453652962.png", record_pos=(-0.203, 0.643), resolution=(549, 966)),0.5,"主线任务")
count+=1
#停留一下
sleep(1.0)
#点击完任务检测是否存在手指,存在手指证明没有奖励
if self.CheckFinger()==True:
print("存在手指,没有奖励")
#查看是否锁住屏幕
if self.CheckRockScence()==True:
print("屏幕被锁住,需要完成强制引导")
noviceGuideSys.NoviceGuideForTrain()
else:
print("没有锁住屏幕,结束任务操作")
else:
print("没有手指,重新执行主线任务")
return self.MainlineTask()
else:
print("没有找到任务入口,需要返回游戏主界面,存在任务入口才能任务操作")
#taskSys =TaskSys() #单独脚本调试用
#taskSys.MainlineTask() #单独脚本调试用
四、其他备注
1.在电脑端运行报错提示"RuntimeError: Invalid handle 0x1f0e84 passed to connect()",需要修改设备的ID成当前连接分配设备的ID即可。
2.类似一直在播放的动画中元素,进行识别时不是很好识别。比如指引你点某个地方的弱指引手指,会一直循环播放手指上下移动的点击动画,再加上手指指引可能会出现在游戏界面不同的地方,还有不同背景之类的干扰,更加的不好匹配。所以反而缩小识别的图像范围,降低匹配度会更加的适用。(适用一些独特造型的图标)