地图可以用Tiled制作,通过pytmx这个扩展来读取。当然你也可以自己写程序来读取Tiled生成的tmx地图文件,其实就是个xml。
寻路嘛,用A*算法好了。这是我自己写的实现代码段,供你参考。对了,tmx的数据我预处理成了二维元组传入astart类。pathPoint是一个辅助类。
class point(object):
def __init__(self,x,y):
self.__x=x
self.__y=y
def getx(self):
return self.__x
def setx(self,x):
self.__x=x
x=property(getx,setx)
def gety(self):
return self.__y
def sety(self,y):
self.__y=y
y=property(gety,sety)
class pathPoint(point):
def __init__(self,x,y,parent=None,ValG=0,ValH=0):
point.__init__(self, x, y)
self.parent=parent
self._valF=ValG+ValH
self._valG=ValG
self._valH=ValH
def _getValG(self):
return self._valG
def _setValG(self, value):
self._valG = value
self._valF=self._valG+self._valH
ValG = property(_getValG, _setValG)
def _getValH(self):
return self._valH
def _setValH(self, value):
self._valH = value
self._valF=self._valG+self._valH
ValH = property(_getValH, _setValH)
def _getValF(self):
return self._valF
ValF = property(_getValF)
class aStar(object):
def __init__(self,startX,startY,endX,endY,aMap):
self.startPoint=pathPoint(startX,startY)
self.endPoint=pathPoint(endX,endY)
self.Map=aMap
self.width=len(self.Map[0])
self.height=len(self.Map)
self.openTable=[]
self.closeTable=[]
def searchPath(self):
self.closeTable.append(self.startPoint)
searching=True
parentPoint=self.startPoint
while searching:
nowPoint=self.checkAround(parentPoint)
if nowPoint==None:
id=self.checkTable(self.openTable,parentPoint.x,parentPoint.y)
if id>=0:
del self.openTable[id]
id=self.checkTable(self.closeTable,parentPoint.x,parentPoint.y)
if id>=0:
searching=False
else:
self.closeTable.append(parentPoint)
if parentPoint.parent==None:
searching=False
else:
nowPoint=parentPoint.parent
elif nowPoint.x==self.endPoint.x and nowPoint.y==self.endPoint.y:
self.endPoint=nowPoint
searching=False
parentPoint=nowPoint
#print "closeTable:"
#for i in self.closeTable:
# print "("+str(i.x)+","+str(i.y)+":"+str(i.ValF)+" ) "
if nowPoint !=None:
return self.getPath()
else:
return []
def checkAround(self,p):
result=None
minF=999999
checkW=((1,0),(0,1),(-1,0),(0,-1))
tp=None
if p==None:
return result
#print "checkAround:"+"("+str(p.x)+","+str(p.y)+":"+str(p.ValF)+" ) "
for i in checkW:
tx=p.x+i[0]
ty=p.y+i[1]
#print "checking:"+"("+str(tx)+","+str(ty)+":"+" )"
if tx<0 or tx>=self.width or ty<0 or ty>=self.height:
#print "is out"
continue
tg=self.Map[ty][tx]
if tg<9999:
tg+=p.ValG
if self.checkTable(self.closeTable,tx,ty)>=0:
#print "is closed"
continue
th=self.calH(tx,ty)
tf=tg+th
inOpen=self.checkTable(self.openTable,tx,ty)
if inOpen<0:
tp=pathPoint(tx,ty,p,tg,th)
self.openTable.append(tp)
elif self.openTable[inOpen].ValF>=tf:
self.openTable[inOpen].ValG=tg
self.openTable[inOpen].ValH=th
self.openTable[inOpen].parent=p
tp=self.openTable[inOpen]
#print "valF:"+str(tf)
if tp!=None:
if minF>tp.ValF:
result=tp
minF=tp.ValF
#else:
#print "is break"
#if result!=None:
# print "this point is good:"+"("+str(result.x)+","+str(result.y)+":"+str(result.ValF)+" )"
return result
def getPath(self):
result=[]
geting=True
tp=self.endPoint
while geting:
#print "("+str(tp.x)+","+str(tp.y)+"),"
result.append((tp.x,tp.y))
if tp==None:
geting=False
elif tp.parent!=None:
tp=tp.parent
else:
geting=False
return result
def checkTable(self,tb,x,y):
for id,p in enumerate(tb):
if p.x==x and p.y==y:
return id
return -1
def calH(self,nx,ny):
return math.sqrt((self.endPoint.x-nx)**2)+math.sqrt((self.endPoint.y-ny)**2)
这是我用pygame做的一个astar算法演示程序截图。
