使用Libtcod在Python中创建/导入自定义地图?

时间:2015-01-03 01:56:43

标签: python roguelike libtcod

我一直在用Python创建一个Roguelike,使用Libtcod!

然而,我遇到的一个主要障碍是 - 我完全不知道如何制作一个CUSTOM地图(例如,我定义了细胞以及它们需要的元素),或者,如果它&#39可能 - 如何使用Libtcod将自定义地图导入Python。

截至目前,我正在使用一种定义,即在某些模式(房间数量,没有交叉点等)之后必须渲染地图 - 但我希望这样做,以便我可以导入已定制的地图 - 或实际上只是为一个定义,所以我可以在给定的标准下加载它。

非常感谢有关此主题的任何帮助,谢谢! :)

1 个答案:

答案 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]那样引用坐标而不是我在示例代码中使用的单维数组。

世界是你的牡蛎! :)只需将数据转换为可以读取的结构,然后检查您感兴趣的坐标。