Pygame开发贪吃蛇时苹果Surface仅在游戏冻结时显示该如何解决
问题原因分析
- 你在一帧内调用了两次
pygame.display.flip()刷新屏幕:先调用apple.spawn()绘制苹果并刷新,此时屏幕上只有苹果;紧接着调用snake.move()最终执行snake.draw(),第一步就用绿色填充了整个画布覆盖了苹果,绘制完蛇后再次刷新,此时用户看到的画面就只有蛇,苹果被覆盖掉了。 - 只有游戏结束时
fps被设为0,snake.draw()不会执行,苹果绘制并刷新后没有后续的覆盖操作,就会停留在屏幕上。fps调高后闪现是因为两次刷新间隔过短,人眼会偶尔捕捉到第一次刷新的苹果画面。
修复方案
调整绘制逻辑,统一每帧的绘制和刷新流程:
- 移除
Apple.spawn()和Snake.draw()中的pygame.display.flip()调用 - 每帧先清空画布,再依次绘制苹果、蛇,最后统一刷新一次屏幕
- 移除
Snake.draw()中的画布填充操作,放到主循环统一处理
修复后的完整代码
import random import pygame class Game: def __init__(self): pygame.init() self.board = pygame.display.set_mode((400, 400)) self.apple = Apple(self.board) self.snake = Snake(self.board, self) self.direction = 'right' self.going = True self.fps = 5 def play(self): clock = pygame.time.Clock() while self.going: clock.tick(self.fps) for event in pygame.event.get(): if event.type == pygame.QUIT: self.going = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: self.direction = 'left' if event.key == pygame.K_RIGHT: self.direction = 'right' if event.key == pygame.K_UP: self.direction = 'up' if event.key == pygame.K_DOWN: self.direction = 'down' # 统一绘制逻辑 self.board.fill((0, 255, 0)) # 每帧先清空画布 self.apple.spawn() self.snake.move(self.direction) pygame.display.flip() # 全部绘制完成后统一刷新 def game_over(self): self.fps = 0 def get_fps(self): return self.fps class Snake: def __init__(self, board, game): self.board = board self.image = pygame.Surface((10, 10)) self.game = game self.length = 5 self.x = [10] * self.length self.y = [10] * self.length def move(self, direction): for i in range(self.length-1, 0, -1): self.x[i] = self.x[i-1] self.y[i] = self.y[i-1] if direction == 'right': self.x[0] += 10 if direction == 'left': self.x[0] -= 10 if direction == 'up': self.y[0] -= 10 if direction == 'down': self.y[0] += 10 if self.x[0] == self.board.get_width() or self.x[0] == -10 or\ self.y[0] == self.board.get_height() or self.y[0] == -10: self.game.game_over() if self.game.get_fps() != 0: self.draw() def draw(self): # 移除fill和flip操作 for i in range(self.length): self.board.blit(self.image, (self.x[i], self.y[i])) class Apple: def __init__(self, board): self.board = board self.image = pygame.Surface((10, 10)) self.image.fill(pygame.color.Color('red')) # 调整随机坐标范围,避免苹果超出屏幕、和蛇网格不对齐 self.x = random.randint(0, (self.board.get_width()-10)//10)*10 self.y = random.randint(0, (self.board.get_height()-10)//10)*10 def spawn(self): self.board.blit(self.image, (self.x, self.y)) # 移除flip操作 if __name__ == '__main__': game = Game() game.play()
内容的提问来源于stack exchange,提问作者Uponn
相关产品推荐
相关产品推荐

