基本属性
定义当前地牢的等级,地图长宽,房间数量,房间的最小最大长度,如下
class Map:
def __init__(self):
self.width = 30
self.heigh = 30
self.level = 1
self.roomNum = 5
self.map = np.zeros((self.heigh,self.width))
self.roomMin = 3
self.roomMax = 11
生成房间
编写initRoom()
随机生成房间,限制最多循环次数,为了简单起见,先做一个不会重叠的房间。基本思路是:随机房间的中心点,随机房间的长宽,再进行判断房间有无重叠(在后续会生成通道,简单起见在这里也保证房间不会紧贴),若无重叠,房间有效,房间数加1。贴代码
def initRoom(self):
count = 0
roomCount = 1
while True:
count += 1
if count > 300:
break
if roomCount > self.roomNum:
break
x = random.randint(1,self.width-1)
y = random.randint(1,self.heigh-1)
wd = random.randint(self.roomMin,self.roomMax)
ht = random.randint(self.roomMin, self.roomMax)
r1 = ceil(y - ht/2)
r2 = ceil(y + ht/2)
c1 = ceil(x - wd/2)
c2 = ceil(x + wd/2)
if r1 < 1:
r1 = 1
if r2 >= self.heigh - 1:
r2 = self.heigh - 2
if c1 < 1:
c1 = 1
if c2 >= self.width - 1:
c2 = self.width - 2
w = c2 - c1 + 1
h = r2 - r1 + 1
if h / w >= 3 or w / h >= 3: #保证房间不是细长的
continue
judge = self.isValidRoom(r1,r2,c1,c2)
if judge == 0:
roomCount += 1
self.room.append(Room(r1,r2,c1,c2))
for i in range(r1,r2):
for j in range(c1,c2):
self.map[i,j] = 1
def isValidRoom(self,r1,r2,c1,c2):
#检测有无覆盖
for i in range(r1,r2):
for j in range(c1,c2):
if self.map[i,j] == 1:
return -1
#检测有无紧贴房间
for i in range(r1,r2):
if self.map[i,c1-1] == 1 or self.map[i,c2+1] == 1:
return 2
for i in range(c1,c2):
if self.map[r1-1,i] == 1 or self.map[r2+1,i] == 1:
return 2
return 0
看一下效果
生成墙壁
编写initTile()
生成包围房间和通道的墙壁,直接贴代码
def initTile(self):
offset = [[-1,0],[0,-1],[1,0],[0,1],[-1,-1],[1,1],[1,-1],[-1,1]]
for i in range(self.heigh):
for j in range(self.width):
if self.map[i,j] == 0:
tag = 0
for it in offset:
if i+it[0] >= self.heigh or j+it[1] >= self.width or i+it[0] < 0 or j+it[1] < 0:
continue
if self.map[i+it[0],j+it[1]] != 3 and self.map[i+it[0],j+it[1]] != 4:
tag += self.map[i+it[0],j+it[1]]
if tag:
self.map[i,j] = 3
效果
生成门口
随机选取房间的一个外围点当做房门,思路是在房间的长宽内随机两个数作为偏移量,预定义好四个方向的覆盖模板对偏移量进行加权和偏置,在这里我编写房间的类,加进地图的属性列表里。
除此之外,房间连通的思路是:在所有房间列表中随机抽出两个房间,将这两个房间连通,再随机选一个房间加回原来的房间列表,直至最后列表里只剩下一个房间。那么现在先来生成房门,代码如下
class Room():
def __init__(self,r1,r2,c1,c2):
w = c2 - c1
h = r2 - r1
self.width = w
self.height = h
self.cx = c1 + ceil(w/2)
self.cy = r1 + ceil(h/2)
self.xStart = c1
self.xEnd = c2 - 1
self.yStart = r1
self.yEnd = r2 - 1
def randomTile(self):
direction = random.randint(0,3)
dir = [[0,1,-1,0],[1,0,0,-1],[1,0,0,self.height],[0,1,self.width,0]]
x_off = random.randint(0,self.width-1)
y_off = random.randint(0,self.height-1)
x = self.xStart + x_off*dir[direction