提灯与地下城自动挂机免费辅助_怎么自动挂机
最近刷了一段时间提灯与地下城这个游戏,太肝了,毛都干没了,于是想制作一个替我刷图的脚本,说干就干,总结下思路。
总思路是 识别当前地图 --> 与地图中可以交互的点交互 --->识别当前地图。
当然这种是比较简单的思路,后期可以拓展。
准备
思路是使用opencv识别人物,道具和怪物等元素,但是考虑到怪物种类不一而足,素材收集也非一日之功,于是转换思路,从小地图入手,小地图的图标是种类固定的,像这样:
buff
怪物
出口
青蛙
宝石
金币
这里注意,采集到的图标需要和手机或者模拟器的图标一一对应。小地图的图片可以通过adb screencap命令获取或者minicap也是可以的。
首先观察小地图的长框可以发现是275 x 275,进一步观察可以发现分为11*11的格子,然而上面两格比较容易匹配出错,所以我们可以用一个11x9的整数数组来表示地图分布:
地图等分
funcGetDevidedCentralPoint(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/piecesY HPP:=height/piecesX res:=make([][]int,piecesX) green := color.RGBA{0, 255, 0, 0} fori:=0;i<piecesX;i++{ resInY:=make([]int,piecesY) forj:=0;j<piecesY;j++{ Img,err:=src.ToImage() iferr!=nil{ lgr.Debug("Transform to image failed,err:",err) }else{ colour:=Img.At(WPP*j+WPP/2,HPP*i+HPP/2) pt:=image.Point{WPP*j+WPP/2,HPP*i+HPP/2} str:=fmt.Sprintf("%v",j) gocv.PutText(&src,str,pt,gocv.FontHersheySimplex,0.5,green,1) r,g,b,_:=colour.RGBA() if(uint8(r)>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 } returnres }
然后再分别匹配上面收集的图标,匹配到就将地图数组中对应的位置改为相应的数字,定义如下:
/*-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, */constheroImg= "./asset/hero.jpg"constenermyImg= "./asset/enermy.jpg"constexitImg= "./asset/exit.jpg"constgoldImg= "./asset/gold.jpg"constgemImg= "./asset/gem.jpg"constredboxImg= "./asset/redbox.jpg"consttempleImg= "./asset/temple.jpg"constIronboxImg= "./asset/Ironbox.jpg"constbuffImg= "./asset/buff.jpg"constpetImg= "./asset/pet.jpg"constpet1Img= "./asset/pet1.jpg"constpet2Img= "./asset/pet2.jpg"constpet3Img= "./asset/pet3.jpg"constfrogImg= "./asset/frog.jpg"constselectorImg= "./asset/selector.jpg"conststoreImg= "./asset/store.jpg"constgoldboxImg= "./asset/goldbox.jpg"constcanceImg= "./asset/cancel.jpg"constpiecesX=9constpiecesY=11
然后,将采集到的地图元素与当前地图一一匹配,使用的方法是之前提过的gocv.MatchTemplate()方法,然后使用gocv.MinMaxLoc()得到可信度和对应的坐标,代码如下:
funcMatchTarget(imgTempl,imgSrc ,imgSrc1 gocv.Mat,type_ int,res [][]int){ result:=gocv.NewMat() deferresult.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) ifmaxConfidence < 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/piecesY HPP:=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)/WPP indy:=(maxLoc.Y+imgTempl.Rows()/2)/HPP pt:=image.Pt(indy,indx) lgr.Debug("x:%v ,y:%v %v,type:%v",indy,indx,maxLoc,type_) iftype_==2{ HeroPosition=pt } res[indy][indx]=type_ iftype_==3{ ExitPosition=pt Dtm:=time.Since(starttime) wtm:=time.Duration(10)*time.Minute kc:=40ifkilledCnt<kc&&Dtm<wtm&&!IsFirstFloor{ res[indy][indx]=0} } iftype_==-1{ IsFirstFloor=true} gocv.Rectangle(&imgSrc1, rect, blue, 1) //lgr.Debug("outer result adress:%v",result)maxLoc,maxConfidence=GetNextMaxLoc(result,maxLoc,minValue,imgTempl.Cols(),imgTempl.Rows()) ifmaxConfidence<0.9{ break} } } funcGetNextMaxLoc(result gocv.Mat,maxLoc image.Point,minValue float32,templateW,templateH int)(image.Point,float32){ startX:=maxLoc.X-templateW startY:=maxLoc.Y-templateH endX :=maxLoc.X + templateW endY :=maxLoc.Y + templateH //lgr.Debug("Inner result adress:%v",result)ifstartX<0|| startY <0{ startX = 0startY = 0} ifendX >result.Cols()-1|| endY > result.Rows()-1{ endX=result.Cols()-1endY=result.Rows()-1} fory:=startY;y<endY;y++{ forx:=startX;x<endX;x++{ //ret:=result.GetFloatAt(y,x)//lgr.Debug("Get point (%v,%v) to %v",x,y,ret)result.SetFloatAt(y,x,minValue) //ret:=result.GetFloatAt(y,x)//lgr.Debug("set point (%v,%v) to %v",x,y,ret)} } _,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result) lgr.Debug("the point %v is max confidence point %v",maxLoc,maxConfidence) returnmaxLoc,maxConfidence }
对每一个地图元素,调用MatchTarget 方法来刷新当前地图数组[][]rest,最后就得到了当前的地图元素。
然后就是寻路的算法,我自己使用的是A*算法,大家有兴趣的可以自己去实现
-- 展开阅读全文 --
暂无评论,257人围观