多人Pong游戏分数更新后立即重置为初始值问题求助
多人Pong游戏分数重置问题
我正在开发一款多人Pong游戏,核心功能正常,但分数无法正常更新。服务端通过Ball类的score()函数更新玩家分数并同步给客户端:满足得分条件时分数会加1,但下一次循环迭代时分数就被重置为0。
相关代码
Ball类的分数检测函数
def score(self, p): if self.x <= 10: print('true') p.score += 1 elif self.x >= 890: print('true') p.score += 1
Player类定义
class Player: def __init__(self, x, y, width, height, color): self.x = x self.y = y self.width = width self.height = height self.color = color self.rect = (x, y, width, height) self.vel = 7 self.score = 0
服务端调用分数函数的代码片段
while True: if current_player > 0: clock = pygame.time.Clock() clock.tick(60) print(players[current_player].score) ball.score(players[current_player]) print(players[current_player].score) ball_data = ball.move(players[0], players[1])
完整服务端相关代码
players = [ Player(10, 300 - PLAYER_HEIGHT/2, PLAYER_WIDTH, PLAYER_HEIGHT, WHITE), Player(880, 300 - PLAYER_HEIGHT/2, PLAYER_WIDTH, PLAYER_HEIGHT, WHITE) ] ball = Ball(WIDTH, HEIGHT, 10, WHITE) def handle_client(conn, current_player): print(f'[NEW CONNECTION] {addr} connected') conn.send(pickle.dumps([players[current_player], ball])) # 0 is player and 1 is ball reply = '' ball_data = ball while True: if current_player > 0: clock = pygame.time.Clock() clock.tick(60) print(players[current_player].score) ball.score(players[current_player]) print(players[current_player].score) ball_data = ball.move(players[0], players[1]) try: data = pickle.loads(conn.recv(2048)) players[current_player] = data if not data: print('DISCONNETED') break else: if current_player == 0: reply = [players[1], ball_data] else: reply = [players[0], ball_data] conn.sendall(pickle.dumps(reply)) except: remove_player() player_reset() ball_reset() break print('Lost connection') conn.close()
调试输出

问题原因及修复方案
核心问题
每次服务端接收客户端数据时,执行players[current_player] = data,而客户端传回的Player对象是初始化状态(score为0),直接覆盖了服务端已更新分数的实例,导致下一次循环分数被重置。
修复步骤
- 避免直接覆盖Player实例:只同步客户端需要更新的属性(位置、速度等),保留服务端维护的分数状态:
try: data = pickle.loads(conn.recv(2048)) # 仅更新客户端同步的属性,保留score players[current_player].x = data.x players[current_player].y = data.y players[current_player].rect = data.rect players[current_player].vel = data.vel if not data: print('DISCONNETED') break else: if current_player == 0: reply = [players[1], ball_data] else: reply = [players[0], ball_data] conn.sendall(pickle.dumps(reply)) except: remove_player() player_reset() ball_reset() break
- 修正得分逻辑:原
score()函数会给当前玩家加分数,不符合Pong规则(左边界触球应让右方玩家得分,右边界触球应让左方玩家得分):
def score(self, players): scored = False if self.x <= 10: # 球碰左边界,右侧玩家(索引1)得分 players[1].score += 1 scored = True elif self.x >= 890: # 球碰右边界,左侧玩家(索引0)得分 players[0].score += 1 scored = True if scored: # 得分后重置球位置 self.reset() print('得分!')
内容的提问来源于stack exchange,提问作者r1chu
相关产品推荐
相关产品推荐

