Python跨文件调用Name列表遇索引越界,求角色与名称传递方案
问题解决:角色数据跨模块传递与索引越界修复
核心问题原因
当你在File2中导入File1(PlayerCreate)时,File1的main()函数并未执行——只有当File1作为独立程序运行(__name__ == "__main__")时,菜单才会启动并填充Name和S_Role列表。直接导入模块时,这两个列表是空的,自然会触发索引越界错误。
正确的做法是让菜单流程完成输入后,主动启动战斗模块,并将输入的数据通过函数参数传递,而非依赖模块全局变量。
修改后的代码实现
File1(PlayerCreate.py)
调整菜单逻辑,添加「开始游戏」按钮,点击后关闭菜单并传递角色数据到战斗模块:
import pygame import pygame_menu import random Roles = [['WARRIOR'], ['TANK']] Name = [] S_Role = [] def get_name(name): Name.clear() # 避免重复输入 Name.append(name) print("我的名字是:", name) def get_role(selected_role, index): # pygame_menu的dropselect回调会返回(选中值, 索引)两个参数 S_Role.clear() S_Role.append(selected_role) print("选择的职业:", selected_role) def start_game(): # 关闭菜单并启动战斗模块 pygame_menu.events.EXIT import play play.main(Name, S_Role) def main(): pygame.init() surface = pygame.display.set_mode((800, 550)) menu = pygame_menu.Menu('欢迎创建角色', 800, 550, theme=pygame_menu.themes.THEME_BLUE) menu.add.text_input('角色1名称:', onreturn=get_name) menu.add.dropselect('选择职业:', Roles, onchange=get_role) menu.add.button('开始游戏', start_game) menu.mainloop(surface) if __name__ == "__main__": main()
File2(play.py)
修改main()函数,接收传递的角色数据,补充必要的类定义和游戏逻辑:
import pygame # 玩家角色类 class warrior: def __init__(self, x, y, name, hp, attack, speed, role): self.x = x self.y = y self.name = name self.hp = hp self.max_hp = hp self.attack = attack self.speed = speed self.role = role self.alive = True def update(self): pass def draw(self, screen): # 绘制角色名称 font = pygame.font.Font(None, 36) name_text = font.render(self.name, True, (255,255,255)) screen.blit(name_text, (self.x + 20, self.y - 30)) # 绘制角色(示例用矩形代替) pygame.draw.rect(screen, (0,150,255), (self.x, self.y, 60, 80)) def attack(self, target): target.hp -= self.attack if target.hp <= 0: target.hp = 0 target.alive = False # 血条类 class HealthBar: def __init__(self, x, y, current_hp, max_hp): self.x = x self.y = y self.max_hp = max_hp self.width = 150 self.height = 20 def draw(self, screen, current_hp): ratio = current_hp / self.max_hp pygame.draw.rect(screen, (255,0,0), (self.x, self.y, self.width, self.height)) pygame.draw.rect(screen, (0,255,0), (self.x, self.y, self.width * ratio, self.height)) # 游戏初始化 pygame.init() screen_width = 800 screen_height = 550 bottom_panel = 150 screen = pygame.display.set_mode((screen_width, screen_height)) clock = pygame.time.Clock() fps = 60 action_cooldown = 0 action_wait_time = 30 current_Warrior = 1 # 敌方角色 Enemy1 = warrior(600, 260, "敌方战士", 100, 5, 3, "Warrior") def draw_bg(): screen.fill((40,40,60)) def draw_panel(): pygame.draw.rect(screen, (80,80,80), (0, screen_height - bottom_panel, screen_width, bottom_panel)) def main(char_names, char_roles): # 检查是否有输入数据 if not char_names or not char_roles: print("请先输入角色名称并选择职业") return # 创建玩家角色 Char1 = warrior(200, 260, char_names[0], 100, 5, 3, char_roles[0][0]) Char1_health_bar = HealthBar(100, screen_height - bottom_panel + 40, Char1.hp, Char1.max_hp) Enemy_health_bar = HealthBar(550, screen_height - bottom_panel + 40, Enemy1.hp, Enemy1.max_hp) run = True while run: clock.tick(fps) draw_bg() draw_panel() # 绘制血条 Char1_health_bar.draw(screen, Char1.hp) Enemy_health_bar.draw(screen, Enemy1.hp) # 绘制角色 Char1.update() Char1.draw(screen) Enemy1.update() Enemy1.draw(screen) # 玩家行动逻辑 if Char1.alive and current_Warrior == 1: action_cooldown += 1 if action_cooldown >= action_wait_time: Char1.attack(Enemy1) current_Warrior = 2 action_cooldown = 0 # 敌方行动逻辑 if Enemy1.alive and current_Warrior == 2: action_cooldown += 1 if action_cooldown >= action_wait_time: Enemy1.attack(Char1) current_Warrior = 1 action_cooldown = 0 # 退出事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False pygame.display.update() pygame.quit()
关键优化点
- 数据传递方式:用函数参数传递角色名称和职业,替代不可靠的全局变量依赖
- 菜单流程闭环:添加「开始游戏」按钮,确保输入完成后才启动战斗逻辑
- 数据去重:在输入回调中清空列表,避免重复添加数据
- 完善游戏逻辑:补充角色绘制、血条显示、敌我交互等基础功能,确保游戏能正常运行
内容的提问来源于stack exchange,提问作者Tian Hock Woo
相关产品推荐
相关产品推荐

