2

我在 Tiled Editor 程序中制作了一个 *tmx 地图。然后我尝试将它导入到我的游戏中。当我将变量更改layers0它可以工作时,但屏幕上只有 1 个图块。我想在我的屏幕上打印整个地图。但我收到以下错误。

Traceback (most recent call last):
  File "C:\Users\LL\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytmx\pytmx.py", line 512, in get_tile_image
    layer = self.layers[layer]
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\LL\Desktop\Erik\RPG_project\RPG project\data\main.py", line 143, in <module>
    game_initialize()
  File "C:\Users\LL\Desktop\Erik\RPG_project\RPG project\data\main.py", line 117, in game_initialize
    map_setup()
  File "C:\Users\LL\Desktop\Erik\RPG_project\RPG project\data\main.py", line 140, in map_setup
    image = tmxdata.get_tile_image(0, 0, 2)
  File "C:\Users\LL\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytmx\pytmx.py", line 514, in get_tile_image
    raise ValueError
ValueError

我认为这与我的层次有关。我的地图只有 1 层。我的脚本仍然不起作用。我的地图也使用 Base64(压缩)。和 32 像素的大图块。

from pytmx import load_pygame

def map_setup():
    global image

    # Getting / Importing the map
    tmxdata = load_pygame("Tile_files\\mymap2.tmx")

    image = tmxdata.get_tile_image(0, 0, 1) # x, y, layer
4

2 回答 2

3

因为 tile 似乎只有 (0,0) 位置。你必须给层循环。我写了这段代码可能对你有帮助。

from pytmx import load_pygame, TiledTileLayer

def map_setup():
    global image

    # Getting / Importing the map
    tmxdata = load_pygame("Tile_files\\mymap2.tmx")
    width = tmxdata.width * tmxdata.tilewidth
    height = tmxdata.height * tmxdata.tileheight

    ti = tmxdata.get_tile_image_by_gid
    for layer in tmxdata.visible_layers:
        if isinstance(layer, TiledTileLayer):
            for x, y, gid, in layer:
                tile = ti(gid)
                if tile:
                    image = tmxdata.get_tile_image(x, y, layer)

顺便说一句,请原谅我的语言。希望有效。

编辑:您可以查看此视频详细了解在 pygame 中导入 tmx 地图。视频链接:https ://www.youtube.com/watch?v=QIXyj3WeyZM

于 2019-02-12T23:59:07.297 回答
1

我认为@gurbuz 的答案已经涵盖了大部分内容,所以我将提出大致相同的答案,但我自己的观点;)

因此,您的 TMX 地图定义了一个纹理瓷砖网格,它们组成了一个充满地图/关卡/任何内容的屏幕。就像陶瓷地砖一样,它们都是单独处理的,并单独放置在地板上。

问题中的代码看起来是正确的,可以在地图的第 0 层中找到 (0,0 / 左上角)单个图块并将其绘制到屏幕上。我怀疑它会产生错误,layer=1因为地图只包含一层。但是没有地图,就不可能知道。

要显示整个地图,有必要遍历.tmx文件中定义的每个图块,并将它们放置到表面上。然后可以将该表面简单地.blit添加到 pygame 窗口。

我拼凑了这个加载整个地图并将其渲染到表面的基本功能。这是一种天真的方法,因为这个图像可能很大。但它的目的是说明如何遍历地图元素并绘制它们。

# Convert HTML-like colour hex-code to integer triple tuple
# E.g.: "#892da0" -> ( 137, 45, 160 )
def hexToColour( hash_colour ):
    red   = int( hash_colour[1:3], 16 )
    green = int( hash_colour[3:5], 16 )
    blue  = int( hash_colour[5:7], 16 )
    return ( red, green, blue )

# Given a loaded pytmx map, create a single image which holds a 
# rendered version of the whole map.
def renderWholeTMXMapToSurface( tmx_map ):
    width  = tmx_map.tilewidth  * tmx_map.width
    height = tmx_map.tileheight * tmx_map.height

    # This surface could be huge
    surface = pygame.Surface( ( width, height ) )

    # Some maps define a base-colour, if so, fill the background with it
    if ( tmx_map.background_color ):
        colour = tmx_map.background_color
        if ( type( colour ) == str and colour[0].startswith( '#' ) ):
            colour = hexToColour( colour )
            surface.fill( colour )
        else:
            print( "ERROR: Background-colour of [" + str( colour ) + "] not handled" )

    # For every layer defined in the map
    for layer in tmx_map.visible_layers:
        # if the Layer is a grid of tiles
        if ( isinstance( layer, pytmx.TiledTileLayer ) ):
            for x, y, gid in layer:
                tile_bitmap = tmx_map.get_tile_image_by_gid(gid)
                if ( tile_bitmap ):
                    surface.blit( tile_bitmap, ( x * tmx_map.tilewidth, y * tmx_map.tileheight ) )
        # if the Layer is a big(?) image
        elif ( isinstance( layer, pytmx.TiledImageLayer ) ):
            image = get_tile_image_by_gid( layer.gid )
            if ( image ):
                surface.blit( image, ( 0, 0 ) )
        # Layer is a tiled group (woah!)
        elif ( isinstance( layer, pytmx.TiledObjectGroup ) ):
            print( "ERROR: Object Group not handled" )

    return surface

因此,一旦地图被“转换”为表面,就可以简单地将这个表面粘贴到 pygame 屏幕上:

# Before the main loop starts
tmx_map   = pytmx.load_pygame( "test.tmx", pixelalpha=True )
map_image = renderWholeTMXMapToSurface( tmx_map )

# Main loop
while not finished:
    ...
    pygame_screen.blit( map_image, ( 0, 0 ) )
    ...

更好的方法是只加载显示所需的 TMX 地图元素。很容易记录地图的哪些子坐标被显示,然后去生成——当它需要进入视图时,比如右边的列。

于 2019-02-13T22:06:45.997 回答