-1
我到處都在網上看,我還沒有找到如何創建一個基本的隨機地牢生成技術。Pygame隨機地下城發電
我一直在試驗自己的隨機數字列表,並將它們分配給寬度高度和位置等,但我似乎無法得到它的工作。
如果有人能指引我訪問某個網站,或者指引我朝着正確的方向發展,那我會很高興,但我有點缺乏經驗。提前致謝。
我到處都在網上看,我還沒有找到如何創建一個基本的隨機地牢生成技術。Pygame隨機地下城發電
我一直在試驗自己的隨機數字列表,並將它們分配給寬度高度和位置等,但我似乎無法得到它的工作。
如果有人能指引我訪問某個網站,或者指引我朝着正確的方向發展,那我會很高興,但我有點缺乏經驗。提前致謝。
這裏有一個隨機地牢發電機,從RogueBasin拍攝,這在一般很多關於該主題和流氓喜歡文章的例子:
# Class to produce random map layouts
from random import *
from math import *
class dMap:
def __init__(self):
self.roomList=[]
self.cList=[]
def makeMap(self,xsize,ysize,fail,b1,mrooms):
"""Generate random layout of rooms, corridors and other features"""
# makeMap can be modified to accept arguments for values of failed, and percentile of features.
# Create first room
self.size_x = xsize
self.size_y = ysize
# initialize map to all walls
self.mapArr=[]
for y in range(ysize):
tmp = []
for x in range(xsize):
tmp.append(1)
self.mapArr.append(tmp)
w,l,t=self.makeRoom()
while len(self.roomList)==0:
y=randrange(ysize-1-l)+1
x=randrange(xsize-1-w)+1
p=self.placeRoom(l,w,x,y,xsize,ysize,6,0)
failed=0
while failed<fail: #The lower the value that failed< , the smaller the dungeon
chooseRoom=randrange(len(self.roomList))
ex,ey,ex2,ey2,et=self.makeExit(chooseRoom)
feature=randrange(100)
if feature<b1: #Begin feature choosing (more features to be added here)
w,l,t=self.makeCorridor()
else:
w,l,t=self.makeRoom()
roomDone=self.placeRoom(l,w,ex2,ey2,xsize,ysize,t,et)
if roomDone==0: #If placement failed increase possibility map is full
failed+=1
elif roomDone==2: #Possiblilty of linking rooms
if self.mapArr[ey2][ex2]==0:
if randrange(100)<7:
self.makePortal(ex,ey)
failed+=1
else: #Otherwise, link up the 2 rooms
self.makePortal(ex,ey)
failed=0
if t<5:
tc=[len(self.roomList)-1,ex2,ey2,t]
self.cList.append(tc)
self.joinCorridor(len(self.roomList)-1,ex2,ey2,t,50)
if len(self.roomList)==mrooms:
failed=fail
self.finalJoins()
def makeRoom(self):
"""Randomly produce room size"""
rtype=5
rwide=randrange(8)+3
rlong=randrange(8)+3
return rwide,rlong,rtype
def makeCorridor(self):
"""Randomly produce corridor length and heading"""
clength=randrange(18)+3
heading=randrange(4)
if heading==0: #North
wd=1
lg=-clength
elif heading==1: #East
wd=clength
lg=1
elif heading==2: #South
wd=1
lg=clength
elif heading==3: #West
wd=-clength
lg=1
return wd,lg,heading
def placeRoom(self,ll,ww,xposs,yposs,xsize,ysize,rty,ext):
"""Place feature if enough space and return canPlace as true or false"""
#Arrange for heading
xpos=xposs
ypos=yposs
if ll<0:
ypos+=ll+1
ll=abs(ll)
if ww<0:
xpos+=ww+1
ww=abs(ww)
#Make offset if type is room
if rty==5:
if ext==0 or ext==2:
offset=randrange(ww)
xpos-=offset
else:
offset=randrange(ll)
ypos-=offset
#Then check if there is space
canPlace=1
if ww+xpos+1>xsize-1 or ll+ypos+1>ysize:
canPlace=0
return canPlace
elif xpos<1 or ypos<1:
canPlace=0
return canPlace
else:
for j in range(ll):
for k in range(ww):
if self.mapArr[(ypos)+j][(xpos)+k]!=1:
canPlace=2
#If there is space, add to list of rooms
if canPlace==1:
temp=[ll,ww,xpos,ypos]
self.roomList.append(temp)
for j in range(ll+2): #Then build walls
for k in range(ww+2):
self.mapArr[(ypos-1)+j][(xpos-1)+k]=2
for j in range(ll): #Then build floor
for k in range(ww):
self.mapArr[ypos+j][xpos+k]=0
return canPlace #Return whether placed is true/false
def makeExit(self,rn):
"""Pick random wall and random point along that wall"""
room=self.roomList[rn]
while True:
rw=randrange(4)
if rw==0: #North wall
rx=randrange(room[1])+room[2]
ry=room[3]-1
rx2=rx
ry2=ry-1
elif rw==1: #East wall
ry=randrange(room[0])+room[3]
rx=room[2]+room[1]
rx2=rx+1
ry2=ry
elif rw==2: #South wall
rx=randrange(room[1])+room[2]
ry=room[3]+room[0]
rx2=rx
ry2=ry+1
elif rw==3: #West wall
ry=randrange(room[0])+room[3]
rx=room[2]-1
rx2=rx-1
ry2=ry
if self.mapArr[ry][rx]==2: #If space is a wall, exit
break
return rx,ry,rx2,ry2,rw
def makePortal(self,px,py):
"""Create doors in walls"""
ptype=randrange(100)
if ptype>90: #Secret door
self.mapArr[py][px]=5
return
elif ptype>75: #Closed door
self.mapArr[py][px]=4
return
elif ptype>40: #Open door
self.mapArr[py][px]=3
return
else: #Hole in the wall
self.mapArr[py][px]=0
def joinCorridor(self,cno,xp,yp,ed,psb):
"""Check corridor endpoint and make an exit if it links to another room"""
cArea=self.roomList[cno]
if xp!=cArea[2] or yp!=cArea[3]: #Find the corridor endpoint
endx=xp-(cArea[1]-1)
endy=yp-(cArea[0]-1)
else:
endx=xp+(cArea[1]-1)
endy=yp+(cArea[0]-1)
checkExit=[]
if ed==0: #North corridor
if endx>1:
coords=[endx-2,endy,endx-1,endy]
checkExit.append(coords)
if endy>1:
coords=[endx,endy-2,endx,endy-1]
checkExit.append(coords)
if endx<self.size_x-2:
coords=[endx+2,endy,endx+1,endy]
checkExit.append(coords)
elif ed==1: #East corridor
if endy>1:
coords=[endx,endy-2,endx,endy-1]
checkExit.append(coords)
if endx<self.size_x-2:
coords=[endx+2,endy,endx+1,endy]
checkExit.append(coords)
if endy<self.size_y-2:
coords=[endx,endy+2,endx,endy+1]
checkExit.append(coords)
elif ed==2: #South corridor
if endx<self.size_x-2:
coords=[endx+2,endy,endx+1,endy]
checkExit.append(coords)
if endy<self.size_y-2:
coords=[endx,endy+2,endx,endy+1]
checkExit.append(coords)
if endx>1:
coords=[endx-2,endy,endx-1,endy]
checkExit.append(coords)
elif ed==3: #West corridor
if endx>1:
coords=[endx-2,endy,endx-1,endy]
checkExit.append(coords)
if endy>1:
coords=[endx,endy-2,endx,endy-1]
checkExit.append(coords)
if endy<self.size_y-2:
coords=[endx,endy+2,endx,endy+1]
checkExit.append(coords)
for xxx,yyy,xxx1,yyy1 in checkExit: #Loop through possible exits
if self.mapArr[yyy][xxx]==0: #If joins to a room
if randrange(100)<psb: #Possibility of linking rooms
self.makePortal(xxx1,yyy1)
def finalJoins(self):
"""Final stage, loops through all the corridors to see if any can be joined to other rooms"""
for x in self.cList:
self.joinCorridor(x[0],x[1],x[2],x[3],10)
# ----------------------------------------------------------------------------
# Main
# ----------------------------------------------------------------------------
startx=20 # map width
starty=10 # map height
themap= dMap()
themap.makeMap(startx,starty,110,50,60)
for y in range(starty):
line = ""
for x in range(startx):
if themap.mapArr[y][x]==0:
line += "."
if themap.mapArr[y][x]==1:
line += " "
if themap.mapArr[y][x]==2:
line += "#"
if themap.mapArr[y][x]==3 or themap.mapArr[y][x]==4 or themap.mapArr[y][x]==5:
line += "="
print line
有很多不同的方法來創建一個隨機地牢,一個common one正在使用Binary space partitioning (BSP)。
另外請確保看看libtcod,它也提供了該算法的實現。
你需要展示你試過的東西,並且詢問具體的問題,例如「這裏是我用來生成隨機地牢的代碼,但我期望X和Y發生了」 –
雖然我的回答可能不會當你發佈你的代碼時,它們會有很大的不同,你仍然應該將它包含在你的問題中。簡單地要求資源/網站/建議被認爲是無關緊要的。因此,請添加您目前爲止的內容,也許我也可以幫助您解決問題。 – sloth