为何Score类中Team1Score、Team2Score变量在AddScore函数中无法更新?
问题描述
我编写了如下Score类的Python代码,问题在于AddScore()函数无法更新self.Team1Score或self.Team2Score变量,变量始终保持为0;但屏幕上渲染的分数却能变化,我不理解这一原因,请问是否需要为变量编写更新函数?
class Score: def __init__(self): self._Colour = (0, 0, 139) self.__x = 30 self.__y = 0 self._Shape = pygame.Rect((self.__x, self.__y), (200, 50)) self.Team1Score = 0. # THIS VARIABLE WILL NOT UPDATE IF 1 IS ADDED TO IT self.Team2Score = 0. # THIS VARIABLE WILL NOT UPDATE IF 1 IS ADDED TO IT self._Title = f"{self.Team1Score} - {self.Team2Score}" self._text_type = pygame.font.SysFont('arialunicode', 30).render(self._Title, True, (255, 255, 255)) self._text_rect = self._text_type.get_rect(center=self._Shape.center) self.Score = False self.teamRect1 = pygame.Rect((0, 0), (50, 50)) self.teamRect2 = pygame.Rect((210, 0), (50, 50)) self.TeamNames = [] self.Teams = [] def TeamSort(self, team): team_total = 0 for key, value in team.items(): if team_total == 2: break else: if value.Team not in self.TeamNames: self.TeamNames.append(value.Team) team_total += 1 for team in self.TeamNames: if len(self.Teams) == 2: break else: newName = (team[0:3].upper()) self.TeamNames.remove(team) self.Teams.append(newName) def DrawScore(self, window, team): pygame.draw.rect(window, self._Colour, self._Shape) window.blit(self._text_type, self._text_rect) self.DrawNames(window, team) def DrawNames(self, window, team): self.TeamSort(team) pygame.draw.rect(window, (255, 255, 255), self.teamRect1) pygame.draw.rect(window, (255, 255, 255), self.teamRect2) if len(self.Teams) == 2: teamOne = self.Teams[0] teamTwo = self.Teams[1] text_type1 = pygame.font.SysFont('arialunicode', 20).render(teamOne, True, (0, 0, 0)) text_type2 = pygame.font.SysFont('arialunicode', 20).render(teamTwo, True, (0, 0, 0)) window.blit(text_type1, (self.teamRect1.x, self.teamRect1.y + 10)) window.blit(text_type2, (self.teamRect2.x, self.teamRect2.y + 10)) def AddScore(self, p1, p2, window): print(self.Team1Score, self.Team2Score) if p1.Shooting: if p1.Colour == (255, 0, 0): self.Team1Score += 1. # THIS DOES NOT UPDATE THE VARIABLE IT STAYS AS 0 elif p2.Shooting: if not p1.Shooting and p1.Colour == (255, 255, 255): self.Team1Score += 1. # THIS DOES NOT UPDATE THE VARIABLE IT STAYS AS 0 if p1.Shooting: if p1.Colour == (255, 255, 255): self.Team2Score += 1 elif p2.Shooting: if not p1.Shooting and p1.Colour == (255, 0, 0): self.Team2Score += 1 pygame.draw.rect(window, self._Colour, self._Shape) self._Title = f"{self.Team1Score} - {self.Team2Score}" self._text_type = pygame.font.SysFont('arialunicode', 40).render(f"{self._Title}", True, (0, 0, 0)) window.blit(self._text_type, self._text_rect) def WinCalc(self): print(self.Team1Score, self.Team2Score) if self.Team1Score > self.Team2Score: return 'Team1' elif self.Team2Score > self.Team1Score: return 'Team2' else: return 'Draw'
问题分析与解决
核心原因:多实例冲突
屏幕分数能变化但变量打印始终为0,最大可能是你在代码中创建了多个Score实例:
- 一个实例被用来执行
AddScore逻辑(实际更新了该实例的分数) - 另一个实例负责屏幕渲染(所以你能看到分数变化)
- 但你打印的是未被更新的那个实例的
Team1Score/Team2Score,所以始终显示0
另外,AddScore的条件判断过于复杂,存在分支覆盖不全的风险,可能导致部分场景下分数确实没更新,但渲染时的字符串拼接让你产生了“分数变化”的错觉。
解决步骤
1. 确保全局只有一个Score实例
检查主循环或初始化代码,避免重复创建Score对象:
# 正确:全局只初始化一次 score_board = Score() # 错误:每次调用函数都创建新实例,导致数据不共享 def some_function(): score = Score() score.AddScore(...)
2. 简化AddScore的条件判断
复杂的嵌套条件容易出现逻辑漏洞,改成更清晰的写法:
def AddScore(self, p1, p2, window): # 先确定当前射击的玩家 shooter = p1 if p1.Shooting else p2 if p2.Shooting else None if shooter: # 根据玩家颜色更新对应队伍分数 if shooter.Colour == (255, 0, 0): self.Team1Score += 1 elif shooter.Colour == (255, 255, 255): self.Team2Score += 1 # 重新渲染分数到屏幕 pygame.draw.rect(window, self._Colour, self._Shape) self._Title = f"{self.Team1Score} - {self.Team2Score}" self._text_type = pygame.font.SysFont('arialunicode', 40).render(self._Title, True, (0, 0, 0)) window.blit(self._text_type, self._text_rect)
3. 无需额外编写更新函数
现有直接赋值的方式完全可行,只要保证操作的是同一个实例,变量就能正常更新。
验证方法
在__init__、AddScore、WinCalc中添加实例ID打印,确认是否操作的是同一个实例:
def __init__(self): print(f"Score实例ID: {id(self)}") # 其他初始化代码... def AddScore(self, p1, p2, window): print(f"AddScore操作的实例ID: {id(self)}") print(self.Team1Score, self.Team2Score) # 其他代码... def WinCalc(self): print(f"WinCalc操作的实例ID: {id(self)}") print(self.Team1Score, self.Team2Score) # 其他代码...
如果打印的ID不一致,就可以确认是多实例导致的问题。
内容的提问来源于stack exchange,提问作者Kelan Westwood
相关产品推荐
相关产品推荐

