请求适配现有加载逻辑的PyGame关卡编辑器实现代码
PyGame关卡编辑器:实现关卡导出至TXT文件的完整代码
以下是适配你现有load_map函数的关卡导出实现,以及可直接运行的关卡编辑器完整代码,包含地图绘制、画笔切换和保存功能:
核心导出函数:save_map
和你读取地图的load_map对应,这个函数把二维列表格式的关卡数据写入TXT文件:
def save_map(path, game_map): # 将二维列表转换为每行字符串的格式 map_str = '\n'.join([''.join(row) for row in game_map]) with open(path + '.txt', 'w') as f: f.write(map_str)
完整关卡编辑器代码
整合你的现有渲染逻辑,添加编辑器交互和保存功能:
import pygame import sys # 初始化Pygame pygame.init() # 配置参数 SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 TILE_SIZE = 16 # 初始地图尺寸(可按需调整) MAP_WIDTH = 50 MAP_HEIGHT = 30 # 创建窗口和小地图 display = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) minimap = pygame.Surface((MAP_WIDTH*TILE_SIZE//4, MAP_HEIGHT*TILE_SIZE//4)) pygame.display.set_caption("关卡编辑器") # 加载纹理(替换为你的实际图片路径,示例用纯色矩形占位) dirt_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) dirt_img.fill((101, 67, 33)) grass_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) grass_img.fill((34, 139, 34)) grass_right_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) grass_right_img.fill((46, 139, 87)) grass_left_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) grass_left_img.fill((0, 100, 0)) dirt_right_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) dirt_right_img.fill((139, 69, 19)) dirt_left_img = pygame.Surface((TILE_SIZE, TILE_SIZE)) dirt_left_img.fill((160, 82, 45)) abyss = pygame.Surface((TILE_SIZE, TILE_SIZE)) abyss.fill((0, 0, 0)) # 初始化空地图(全0表示空白) game_map = [['0' for _ in range(MAP_WIDTH)] for _ in range(MAP_HEIGHT)] current_tile = '1' # 默认选中的砖块类型 scroll = [0, 0] # 地图滚动偏移 def load_map(path): f = open(path + '.txt','r') data = f.read() f.close() data = data.split('\n') game_map = [] for row in data: # 确保每行长度一致,避免加载出错 if row: game_map.append(list(row.ljust(MAP_WIDTH, '0'))[:MAP_WIDTH]) # 确保地图高度符合设定,不足则补全 while len(game_map) < MAP_HEIGHT: game_map.append(['0' for _ in range(MAP_WIDTH)]) return game_map[:MAP_HEIGHT] def save_map(path, game_map): map_str = '\n'.join([''.join(row) for row in game_map]) with open(path + '.txt', 'w') as f: f.write(map_str) # 主循环 running = True while running: display.fill((50, 50, 50)) minimap.fill((30, 30, 30)) tile_rects = [] y = 0 # 渲染地图(沿用你的原有逻辑) for layer in game_map: x = 0 for tile in layer: draw_pos = (x*TILE_SIZE - scroll[0], y*TILE_SIZE - scroll[1]) minimap_pos = (x*TILE_SIZE//4, y*TILE_SIZE//4) if tile == '1': display.blit(dirt_img, draw_pos) minimap.blit(dirt_img, minimap_pos) elif tile == '2': display.blit(grass_img, draw_pos) minimap.blit(grass_img, minimap_pos) elif tile == '3': display.blit(grass_right_img, draw_pos) minimap.blit(grass_right_img, minimap_pos) elif tile == '4': display.blit(grass_left_img, draw_pos) minimap.blit(grass_left_img, minimap_pos) elif tile == '5': display.blit(dirt_right_img, draw_pos) minimap.blit(dirt_right_img, minimap_pos) elif tile == '6': display.blit(dirt_left_img, draw_pos) minimap.blit(dirt_left_img, minimap_pos) elif tile == '7': display.blit(abyss, draw_pos) if tile != '0': tile_rects.append(pygame.Rect(x*TILE_SIZE, y*TILE_SIZE, TILE_SIZE, TILE_SIZE)) x += 1 y += 1 # 绘制小地图到屏幕角落 display.blit(minimap, (SCREEN_WIDTH - minimap.get_width() - 10, 10)) # 处理输入事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 键盘事件:切换砖块、保存地图、滚动地图 if event.type == pygame.KEYDOWN: # 数字键1-7切换当前画笔 if event.key == pygame.K_1: current_tile = '1' elif event.key == pygame.K_2: current_tile = '2' elif event.key == pygame.K_3: current_tile = '3' elif event.key == pygame.K_4: current_tile = '4' elif event.key == pygame.K_5: current_tile = '5' elif event.key == pygame.K_6: current_tile = '6' elif event.key == pygame.K_7: current_tile = '7' elif event.key == pygame.K_0: current_tile = '0' # 擦除模式 # 按S键保存地图 elif event.key == pygame.K_s: save_map("my_level", game_map) print("地图已保存为my_level.txt") # 方向键滚动地图 elif event.key == pygame.K_LEFT: scroll[0] -= TILE_SIZE elif event.key == pygame.K_RIGHT: scroll[0] += TILE_SIZE elif event.key == pygame.K_UP: scroll[1] -= TILE_SIZE elif event.key == pygame.K_DOWN: scroll[1] += TILE_SIZE # 鼠标事件:放置/擦除砖块 if event.type == pygame.MOUSEBUTTONDOWN: # 计算鼠标对应的地图坐标 mouse_x, mouse_y = pygame.mouse.get_pos() map_x = (mouse_x + scroll[0]) // TILE_SIZE map_y = (mouse_y + scroll[1]) // TILE_SIZE # 确保坐标在地图范围内 if 0 <= map_x < MAP_WIDTH and 0 <= map_y < MAP_HEIGHT: if event.button == 1: # 左键放置砖块 game_map[map_y][map_x] = current_tile elif event.button == 3: # 右键擦除砖块 game_map[map_y][map_x] = '0' # 显示操作提示 font = pygame.font.SysFont(None, 24) text = font.render(f"当前砖块: {current_tile} | 按S保存 | 数字键切换 | 右键擦除", True, (255,255,255)) display.blit(text, (10, 10)) pygame.display.flip() pygame.quit() sys.exit()
使用说明
- 数字键
1-7切换要放置的砖块类型,0键切换为擦除模式 - 鼠标左键点击地图放置砖块,右键点击擦除砖块
- 方向键滚动地图以查看超出屏幕的区域
- 按
S键将当前地图保存为my_level.txt文件 - 加载现有地图:将初始化
game_map的代码替换为game_map = load_map("your_level_name")(无需加.txt后缀)
内容的提问来源于stack exchange,提问作者vividacorn
相关产品推荐
相关产品推荐

