我在Tiled Editor程序中制作了一个* tmx映射。然后,我尝试将其导入到我的游戏中。当我将变量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
我认为这与我的图层有关。我的地图只有一层。仍然我的脚本不起作用。我还对地图使用了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
答案 0 :(得分:2)
因为图块似乎仅位于(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
答案 1 :(得分: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地图元素。记录下要显示的地图子坐标很容易,然后生成-在需要查看时说右边一栏。