Как импортировать карту TMX в Pygame? - PullRequest
0 голосов
/ 12 февраля 2019

Я сделал карту * tmx в программе Tiled Editor.Затем я попытался импортировать его в свою игру.Когда я изменяю переменную layers на 0, она работает, но на экране остается только 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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я думаю, что ответ @ gurbuz уже охватил большую часть этого, поэтому я представлю почти тот же ответ, но с моим собственным вращением;)

Итак, ваша карта TMX определяет сетку текстурированных плиток, которые составляютэкран, полный карты / уровня / что угодно.Как и керамическая плитка для пола, каждая из них обрабатывается индивидуально и укладывается на пол индивидуально.

Код в вопросе выглядит правильно, чтобы найти (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

Так что, как только карта «преобразована» в поверхность, можно просто перетянуть эту поверхность в пигмеюscreen:

# 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, необходимые для отображения.Легко записать, какие подчиненные координаты карты отображаются, а затем перейти к генерации - скажем, столбец с правой стороны, когда это должно появиться.

0 голосов
/ 13 февраля 2019

Поскольку плитка кажется только (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)

Кстати, извините за мой язык.Надеюсь, работает.

Редактировать: Вы можете посмотреть это видео подробно для импорта карты TMX в Pygame.Ссылка на видео: https://www.youtube.com/watch?v=QIXyj3WeyZM

...