景澄手游网

提灯与地下城自动刷图教学(提灯与地下城自动刷图哪个好用)

编辑:景澄手游网 时间:2022-06-01 22:28:32

最近刷了一段时间提灯与地下城这个游戏,太肝了[吐舌],毛都干没了,于是想制作一个替我刷图的脚本,说干就干,总结下思路。yNQ景澄手游网

总思路是 识别当前地图 --> 与地图中可以交互的点交互 --->识别当前地图。yNQ景澄手游网

当然这种是比较简单的思路,后期可以拓展。yNQ景澄手游网

准备yNQ景澄手游网

思路是使用opencv识别人物,道具和怪物等元素,但是考虑到怪物种类不一而足,素材收集也非一日之功,于是转换思路,从小地图入手,小地图的图标是种类固定的,像这样:yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

buffyNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

怪物yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

出口yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

青蛙yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

宝石yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

金币yNQ景澄手游网

这里注意,采集到的图标需要和手机或者模拟器的图标一一对应。小地图的图片可以通过adb screencap命令获取或者minicap也是可以的。yNQ景澄手游网

首先观察小地图的长框可以发现是275 x 275,进一步观察可以发现分为11*11的格子,然而上面两格比较容易匹配出错,所以我们可以用一个11x9的整数数组来表示地图分布:yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

地图等分yNQ景澄手游网

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 pieces
	width:=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}
	for i:=0;i<piecesX;i++{
		resInY:=make([]int,piecesY)
		
		for j:=0;j<piecesY;j++{
			Img,err:=src.ToImage()
			if err!=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
	}
	return res
}

然后再分别匹配上面收集的图标,匹配到就将地图数组中对应的位置改为相应的数字,定义如下:yNQ景澄手游网

 yNQ景澄手游网

使用golang gocv制作提灯与地下城的自动刷图脚本,解放双手yNQ景澄手游网

/*-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=9
const piecesY=11

然后,将采集到的地图元素与当前地图一一匹配,使用的方法是之前提过的gocv.MatchTemplate()方法,然后使用gocv.MinMaxLoc()得到可信度和对应的坐标,代码如下:yNQ景澄手游网

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/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_)
        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<kc&&Dtm<wtm&&!IsFirstFloor{
                res[indy][indx]=0
            }
        }
        if type_==-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())
		
        if maxConfidence<0.9{
            break
        }
    
    }
    
   
  }
  
func GetNextMaxLoc(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)
    
    if startX<0 || startY <0 {
        startX = 0
        startY = 0
    }
    if endX >result.Cols()-1 || endY > result.Rows()-1{
        endX=result.Cols()-1
        endY=result.Rows()-1
    }
    
    for y:=startY;y<endY;y++{
        for x:=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)
    return maxLoc,maxConfidence
}

对每一个地图元素,调用MatchTarget 方法来刷新当前地图数组[][]rest,最后就得到了当前的地图元素。yNQ景澄手游网

然后就是寻路的算法,我自己使用的是A*算法,大家有兴趣的可以自己去实现一下.yNQ景澄手游网

最后附上脚本运行的录屏。yNQ景澄手游网

  • 整蛊游戏大全 超高画质手游(安卓) 未成年24小时可以玩的游戏 升级领1000红包的游戏 挂机打怪升级的手游 人气最高的手游排行榜

  • 精选游戏 更多
    相关攻略
    其他网友都在玩 更多
    玩家评论