我一直在用Python创建一个Roguelike,使用Libtcod!
然而,我遇到的一个主要障碍是 - 我完全不知道如何制作一个CUSTOM地图(例如,我定义了细胞以及它们需要的元素),或者,如果它&#39可能 - 如何使用Libtcod将自定义地图导入Python。
截至目前,我正在使用一种定义,即在某些模式(房间数量,没有交叉点等)之后必须渲染地图 - 但我希望这样做,以便我可以导入已定制的地图 - 或实际上只是为一个定义,所以我可以在给定的标准下加载它。
非常感谢有关此主题的任何帮助,谢谢! :)
答案 0 :(得分:0)
有很多有趣的方法可以将地图数据导入您的程序。
通常,使用roguelike,您将生成该数据。当然,这并非严格必要。
一种非常基本的生成方式是试用libtcod的高度图工具包。这是从我写过的游戏中提取的,可能会给你一个体面的想法如何解决问题。此代码从我的Map类中提取:
import random
import libtcodpy as libtcod
class Map
def __init__(self,w,h) :
self.width = w
self.height = h
self._hm = libtcod.heightmap_new(w,h)
self._cells = []
self.initMap()
def initMap(self) :
print "Initing map"
for y in range(self.height) :
for x in range(self.width) :
c = cell.Cell(x,y)
self._cells.append(c)
self.resetMap()
return
def resetMap(self):
print "Resetting map"
for y in range(self.height) :
for x in range(self.width) :
self._cells[x + y * self.width].reset()
## Heightmap generation
self.randomizeHeightmap()
for y in range(self.height) :
for x in range(self.width) :
alt = libtcod.heightmap_get_value(self._hm, x, y)
self._cells[x + y * self.width].dig(alt > 1)
def randomizeHeightmap(self) :
print "Setting up heightmap"
hills = 1000
hillSize = 7
halfX = self.width / 2
halfY = self.height / 2
libtcod.heightmap_clear(self._hm)
for i in range(hills) :
size = random.randint(0,hillSize)
hillX1 = random.randint(0,halfX - hillSize / 2)
hillY1 = random.randint(0,self.height)
hillX2 = random.randint(halfX + hillSize / 2, self.width)
hillY2 = random.randint(0,self.height)
libtcod.heightmap_add_hill(self._hm,hillX1, hillY1, size, size)
libtcod.heightmap_add_hill(self._hm,hillX2, hillY2, size, size)
libtcod.heightmap_normalize(self._hm, 0.0, 2.0)
[...]
注意我这里没有使用libtcod的地图功能。你当然可以,并且这将允许你使用内置的Field of View工具包(这非常棒!)。
Cell类的dig方法接受一个布尔值来确定该单元格是否可通过。在生成高度图之后,我将其标准化,使其仅包含0,1和2的值。然后,我只创建任何相应的单元格,最后得到一个"海拔高度" 2个墙壁,1个或0个开口。这给了我很好的平衡。
高度图功能非常适合创建具有圆形特征的有机排版,而不是roguelikes中经常出现的典型的方形地牢。
如果您正在寻找更多传统的地下城,那么libtcod附带了一个BSP工具包,专为此任务而设计。请参阅文档here。
还有一个令人难以置信的python教程,它有一个专门的地图部分here。
我过去曾使用过其他方法,包括但不限于读取简单的.bmp图像中的每个像素并解释rgb值,每个都指示地图中给定坐标的不同之处(红色可能是墙/开,蓝色可能表示是否存在屋顶等。)
但基本思路是只有一个坐标数组。它可以像数组或整数一样简单,其中0表示可通过,1表示墙,或者,就像我的情况一样,还有一组对象,它们还存储了对您的游戏有用的其他信息。
你可以使用一个二维数组(这有点容易缠绕你的头,有时候,你会像map[x][y]
而不是map[x + y*width]
那样引用坐标而不是我在示例代码中使用的单维数组。
世界是你的牡蛎! :)只需将数据转换为可以读取的结构,然后检查您感兴趣的坐标。