使用Tiled与Pygame加载精灵表时地图旋转翻转问题求助
地图加载旋转翻转与精灵表错误修复
问题描述
用Tiled生成4个CSV格式游戏地图文件,加载基础层(草地、泥土等)时地图旋转翻转,完全无法识别,同时精灵表加载的图像不正确,调整变量后仍未解决。
相关截图
- 预期地图效果:

- 实际运行效果:

- 使用的精灵表:

原代码
import pygame,sys from pygame.locals import * import csv running = True pygame.init() screen = pygame.display.set_mode((1280, 900)) def load_sprite_sheet(x_range, y_range, sprite_w, sprite_h): x_coord = 16 * x_range y_coord = 16 * y_range width = sprite_w height = sprite_h sheet = pygame.image.load("assets/TileMap/tilemap_packed.png").convert_alpha() single_image = sheet.subsurface((x_coord, y_coord, width, height)) print(x_coord, y_coord) return single_image grass_layout = "assets/TileMap/layout_grass.csv" grasses = { "0": load_sprite_sheet(0, 0, 16, 16), "1": load_sprite_sheet(1, 0, 16, 16), "3": load_sprite_sheet(2, 0, 16, 16), "12": load_sprite_sheet(0, 1, 16, 16), "13": load_sprite_sheet(1, 1, 16, 16), "14": load_sprite_sheet(2, 1, 16, 16), "24": load_sprite_sheet(0, 2, 16, 16), "25": load_sprite_sheet(1, 2, 16, 16), "26": load_sprite_sheet(2, 2, 16, 16), "36": load_sprite_sheet(0, 3, 16, 16), "37": load_sprite_sheet(1, 3, 16, 16), "38": load_sprite_sheet(2, 3, 16, 16), "39": load_sprite_sheet(3, 3, 16, 16), "40": load_sprite_sheet(4, 3, 16, 16), "41": load_sprite_sheet(5, 3, 16, 16), "42": load_sprite_sheet(6, 3, 16, 16), "43": load_sprite_sheet(7, 3, 16, 16), } while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False pygame.quit() screen.fill('BLUE') with open(grass_layout, 'r') as csv_file: grasses_map = csv.reader(csv_file) for x_index, row in enumerate(grasses_map, 0): for y_index, col in enumerate(row, 0): if col in grasses.keys(): screen.blit(grasses[col], (x_index * 16, y_index * 16)) pygame.display.update()
问题分析与修复
1. 地图旋转翻转问题
原因:Tiled导出的CSV按行从上到下存储地图,每行对应地图的横向一行;但原代码把行索引当作x坐标、列索引当作y坐标绘制,直接导致地图旋转90度,同时颠倒了横向顺序。
修复方法:将行索引对应y轴坐标,列索引对应x轴坐标,修正绘制逻辑:
with open(grass_layout, 'r') as csv_file: grasses_map = csv.reader(csv_file) # 行索引对应y轴,列索引对应x轴 for y_index, row in enumerate(grasses_map): for x_index, col in enumerate(row): if col in grasses: screen.blit(grasses[col], (x_index * 16, y_index * 16))
2. 精灵表加载错误问题
原因:从精灵表截图和ID映射来看,Tiled的tile ID规则是 ID = 行号 * 每行tile数量 + 列号(这里每行有12个tile,所以ID间隔为12),你的映射逻辑本身正确,但存在两个潜在问题:
- 部分tile ID未在
grasses字典中定义,导致对应位置无法渲染; - 若精灵表存在内边距/外边距,
x_coord和y_coord的计算需要额外加上间距值。
修复建议:
- 检查Tiled导出设置,确保CSV的tile ID从0开始,且与精灵表排列顺序一致;
- 若精灵表有间距,修改
load_sprite_sheet函数加入间距计算(比如每个tile间有2像素间距,就把x_coord = 16 * x_range + 2 * x_range); - 补全所有需要用到的tile ID映射,避免遗漏导致的空白。
修改后的完整代码
import pygame,sys from pygame.locals import * import csv running = True pygame.init() screen = pygame.display.set_mode((1280, 900)) def load_sprite_sheet(x_range, y_range, sprite_w, sprite_h): x_coord = 16 * x_range y_coord = 16 * y_range width = sprite_w height = sprite_h sheet = pygame.image.load("assets/TileMap/tilemap_packed.png").convert_alpha() single_image = sheet.subsurface((x_coord, y_coord, width, height)) return single_image grass_layout = "assets/TileMap/layout_grass.csv" grasses = { "0": load_sprite_sheet(0, 0, 16, 16), "1": load_sprite_sheet(1, 0, 16, 16), "2": load_sprite_sheet(2, 0, 16, 16), # 补全遗漏的ID "3": load_sprite_sheet(3, 0, 16, 16), "12": load_sprite_sheet(0, 1, 16, 16), "13": load_sprite_sheet(1, 1, 16, 16), "14": load_sprite_sheet(2, 1, 16, 16), "24": load_sprite_sheet(0, 2, 16, 16), "25": load_sprite_sheet(1, 2, 16, 16), "26": load_sprite_sheet(2, 2, 16, 16), "36": load_sprite_sheet(0, 3, 16, 16), "37": load_sprite_sheet(1, 3, 16, 16), "38": load_sprite_sheet(2, 3, 16, 16), "39": load_sprite_sheet(3, 3, 16, 16), "40": load_sprite_sheet(4, 3, 16, 16), "41": load_sprite_sheet(5, 3, 16, 16), "42": load_sprite_sheet(6, 3, 16, 16), "43": load_sprite_sheet(7, 3, 16, 16), } while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False pygame.quit() screen.fill('BLUE') with open(grass_layout, 'r') as csv_file: grasses_map = csv.reader(csv_file) for y_index, row in enumerate(grasses_map): for x_index, col in enumerate(row): if col in grasses: screen.blit(grasses[col], (x_index * 16, y_index * 16)) pygame.display.update()
内容的提问来源于stack exchange,提问作者AndrewRoman
相关产品推荐
相关产品推荐

