时间:2023-10-21 14:27:59来源:互联网
最近刷了一段时间提灯与地下城这个游戏,太肝了[吐舌],毛都干没了,于是想制作一个替我刷图的脚本,说干就干,总结下思路。
总思路是 识别当前地图 --> 与地图中可以交互的点交互 --->识别当前地图。
当然这种是比较简单的思路,后期可以拓展。
准备
思路是使用opencv识别人物,道具和怪物等元素,但是考虑到怪物种类不一而足,素材收集也非一日之功,于是转换思路,从小地图入手,小地图的图标是种类固定的,像这样:
buff
怪物
出口
青蛙
宝石
金币
这里注意,采集到的图标需要和手机或者模拟器的图标一一对应。小地图的图片可以通过adb screencap命令获取或者minicap也是可以的。
首先观察小地图的长框可以发现是275 x 275,进一步观察可以发现分为11*11的格子,然而上面两格比较容易匹配出错,所以我们可以用一个11x9的整数数组来表示地图分布:
地图等分
func GetDevidedCentralPoint(piecesX ,piecesY int,src gocv.Mat)[][]int{//formed up a vector of (11-2)*11 //use line to devide the map picture into 9x11 pieceswidth:=src.Cols()height:=src.Rows()lgr.Debug("width:%v height:%v",width,height)WPP:=width/piecesYHPP:=height/piecesXres:=make([][]int,piecesX)green := color.RGBA{0, 255, 0, 0}for i:=0;i
20 && uint8(g)>20 && uint8(b)>20){//lgr.Debug("current point(%v,[%d,%v,%v]) color is : %v",pt,uint8(r),uint8(g),uint8(b),colour)//gocv.Circle(&src,pt,2,green,1)resInY[j]=1}else{resInY[j]=0}}}res[i]=resInY}return res}
然后再分别匹配上面收集的图标,匹配到就将地图数组中对应的位置改为相应的数字,定义如下:
/*-1 for store, 0 for unknow status, 1 for path, 2 for hero,3 for exit,4 for gold,5 for pet ,6 for enermys ,7 for iron box,8 for red box,9 for buff , 13 for frog,-2 for goldbox,-3 for temple, */const heroImg= "./asset/hero.jpg"const enermyImg= "./asset/enermy.jpg"const exitImg= "./asset/exit.jpg"const goldImg= "./asset/gold.jpg"const gemImg= "./asset/gem.jpg"const redboxImg= "./asset/redbox.jpg"const templeImg= "./asset/temple.jpg"const IronboxImg= "./asset/Ironbox.jpg"const buffImg= "./asset/buff.jpg"const petImg= "./asset/pet.jpg"const pet1Img= "./asset/pet1.jpg"const pet2Img= "./asset/pet2.jpg"const pet3Img= "./asset/pet3.jpg"const frogImg= "./asset/frog.jpg"const selectorImg= "./asset/selector.jpg"const storeImg= "./asset/store.jpg"const goldboxImg= "./asset/goldbox.jpg"const canceImg= "./asset/cancel.jpg"const piecesX=9const piecesY=11
然后,将采集到的地图元素与当前地图一一匹配,使用的方法是之前提过的gocv.MatchTemplate()方法,然后使用gocv.MinMaxLoc()得到可信度和对应的坐标,代码如下:
func MatchTarget(imgTempl,imgSrc ,imgSrc1 gocv.Mat,type_ int ,res [][]int){ result:=gocv.NewMat() defer result.Close() m :=gocv.NewMat() blue := color.RGBA{0, 0, 255, 0} gocv.MatchTemplate(imgTempl,imgSrc,&result,gocv.TmCcoeffNormed,m) //gocv.MatchTemplate(imgTempl,imgSrc,&result,1,m) m.Close() minValue,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result) if maxConfidence < 0.9 { lgr.Debug("Max confidence of %f is too low. MatchTemplate could not find template in scene.", maxConfidence) return } width:=imgSrc.Cols()height:=imgSrc.Rows()WPP:=width/piecesYHPP:=height/piecesX for { //lgr.Debug("The most possible location is : %v,value is : %v",maxLoc,maxConfidence) rect:=image.Rect(maxLoc.X,maxLoc.Y,maxLoc.X imgTempl.Cols(),maxLoc.Y imgTempl.Rows())indx:=(maxLoc.X imgTempl.Cols()/2)/WPPindy:=(maxLoc.Y imgTempl.Rows()/2)/HPP pt:=image.Pt(indy,indx) lgr.Debug("x:%v ,y:%v %v,type:%v",indy,indx,maxLoc,type_) if type_==2{ HeroPosition=pt }res[indy][indx]=type_ if type_==3{ExitPosition=pt Dtm:=time.Since(starttime) wtm:=time.Duration(10)*time.Minute kc:=40 if killedCnt
然后就是寻路的算法,我自己使用的是A*算法,大家有兴趣的可以自己去实现一下.
最后附上脚本运行的录屏。
提灯与地下城游戏测评,黑暗深渊中的光明之灯
2024-03-13
提灯与地下城10月23日密令是什么,最新密令位置介绍
2023-11-01
提灯与地下城毕业装备宠物怎么搭配,提灯与地下城眩晕法杖装备与宝宝搭配攻略
2023-09-13
提灯与地下城宠物最强组合,萌新开荒露露搭配攻略
2024-03-21
提灯与地下城怎么合成宝石,提灯与地下城宝石合成攻略
2023-09-20
提灯与地下城密令大全,提灯密令大全,游戏开服
2023-09-02
提灯与地下城近战法师,提灯贩剑,最强近战法师
2024-03-15
提灯与地下城70级契约兽哪个强,提灯VS契约兽谁更强
2023-06-27
提灯与地下城前期开荒宠物推荐,三大神宠推荐,快速升级
2023-12-19
提灯与地下城大魔导师最强技能,攻略看这领先一周
2024-03-12