Pygame精灵组内对话无法更新问题求助
对话更新不同步问题
对话索引已更新,但屏幕上的文本未同步更新。玩家处于NPC范围内时按空格键应更新对话,但目前仅在碰撞时显示第一个索引的对话,离开NPC或按空格键均无变化,理论上npc_list应更新self.image并重绘。
初始化NPC相关代码
self.npcs = [ [[450,500,[]]],] self.npc_dialogue = [['Hi','Bye']] self.npc_dialogue_sizes = [(25,50),(25,50)] self.npc_list = pygame.sprite.Group() #x,y,size,dialog,path_list for i,npc in enumerate(self.npcs[self.level]): new_npc = Npc((npc[0],npc[1]),self.npc_dialogue_sizes,self.npc_dialogue[0],npc[2]) self.npc_list.add(new_npc)
场景显示逻辑
def display_stages(self,screen): clock = pygame.time.Clock() running = True #Break if exit goes into a cutscene maybe use -1 and then update the level. dialog = False npc = None while running: if self.stages.level>=len(self.stages.exits) or self.state!=0: break for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() keys = pygame.key.get_pressed() if keys[pygame.K_SPACE]: if dialog and npc!=None: #Update a single npc list dialogue npc.update() print('Update') screen.fill(white) dialog, npc = self.npc_dialog() if dialog and npc!=None: npc.draw_dialog(screen) self.stages.draw(screen) pygame.display.flip() clock.tick(FPS) def npc_dialog(self): for npc in self.stages.npc_list: gets_hit = npc.rect.colliderect(self.stages.player.rect) if gets_hit: return True, npc return False, None
场景绘制方法
def draw(self,screen): if self.level < len(self.boundaries): screen.blit(self.image,self.rect) self.npc_list.draw(screen)
NPC类定义
class Npc(pygame.sprite.Sprite): def __init__(self,position,size,dialog,path_list): pygame.sprite.Sprite.__init__(self) print(size,position,dialog) self.sizes = size self.image = pygame.Surface(self.sizes[0]) self.rect = self.image.get_rect() self.rect.topleft = position self.path_list = path_list # rework size and position to n*elements with dialog size positions = [] for i in range(len(size)): positions.append(position) self.dialog = Dialog(positions,size,dialog) def update(self): #self.dialog.update() print(self.dialog.index,len(self.dialog.size)) if self.dialog.index < len(self.dialog.size)-1: self.dialog.update() def draw_dialog(self,screen): print(self.dialog.dialog[self.dialog.index]) if self.dialog.index < len(self.dialog.size)-1: print('Updating drawing') text = self.dialog.font.render(self.dialog.dialog[self.dialog.index], True, white) self.image.blit(text, (self.dialog.dialog_text_offset,self.dialog.dialog_text_offset))
Dialog类定义
class Dialog(): def __init__(self,position,size,dialog): self.index = 0 self.dialog = dialog self.sizes = size self.size = self.sizes[self.index] self.positions = position self.pos = position[self.index] self.image = pygame.Surface(self.size, pygame.SRCALPHA) self.rect = pygame.Rect((0,0), self.size) self.font = pygame.font.Font(None,32) self.rect.topleft = self.pos self.dialog_background = (0, 0, 255, 127) self.dialog_text_offset = 5 def update(self): self.size = self.sizes[self.index] self.pos = self.positions[self.index] self.index += 1
问题分析与修复方案
- Dialog更新顺序错误:原
update()先赋值尺寸再自增索引,导致索引与尺寸不匹配,应先自增索引再更新尺寸。 - 对话框未重绘背景:每次更新对话时没有重新创建
image或清空背景,旧文本会叠加在新文本上,需要每次绘制时重新生成背景并填充颜色。 - 按键检测逻辑问题:使用
key.get_pressed()会导致按住空格连续触发更新,改用KEYDOWN事件实现单次触发。 - 离开NPC未重置对话:玩家离开NPC范围后,对话索引未重置,再次靠近时无法从头显示对话,需添加重置逻辑。
修改后的关键代码片段
修正Dialog类的update方法
def update(self): self.index += 1 if self.index < len(self.sizes): self.size = self.sizes[self.index] self.pos = self.positions[self.index]
修正NPC的draw_dialog方法
def draw_dialog(self,screen): # 重新生成对话框背景,避免文本叠加 self.image = pygame.Surface(self.sizes[self.dialog.index]) self.image.fill(self.dialog.dialog_background) # 渲染当前索引的文本 text = self.dialog.font.render(self.dialog.dialog[self.dialog.index], True, white) self.image.blit(text, (self.dialog.dialog_text_offset, self.dialog.dialog_text_offset)) # 将对话框绘制到屏幕 screen.blit(self.image, self.rect.topleft)
修正按键检测为KEYDOWN事件
for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE and dialog and npc is not None: npc.update() print('Update')
添加离开NPC时重置对话的逻辑
# 在类中新增属性self.last_npc = None def npc_dialog(self): current_npc = None for npc in self.stages.npc_list: if npc.rect.colliderect(self.stages.player.rect): current_npc = npc self.last_npc = current_npc return True, current_npc # 离开所有NPC范围,重置对话索引 if self.last_npc is not None: self.last_npc.dialog.index = 0 self.last_npc = None return False, None
内容的提问来源于stack exchange,提问作者Arundeep Chohan
相关产品推荐
相关产品推荐

