在我冻结游戏之前,第二个表面不会出现在屏幕上

Second surface doesn't appear on screen until I freeze the game

我正在尝试 Pygame 并从经典开始,创建 Snake 游戏,问题是我尝试在棋盘上 blit 'apple' 但苹果没有出现直到我撞到墙上,这是我设置 fps = 0 并冻结游戏的时候。我注意到当我将 fps 增加到 100 或更多时,苹果开始出现和消失。

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.apple.spawn()
            self.snake.move(self.direction)

    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):
        self.board.fill((0, 255, 0))
        for i in range(self.length):
            self.board.blit(self.image, (self.x[i], self.y[i]))
        pygame.display.flip()


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())
        self.y = random.randint(0, self.board.get_height())

    def spawn(self):
        self.board.blit(self.image, (self.x, self.y))
        pygame.display.flip()


if __name__ == '__main__':
    game = Game()
    game.play()

在应用程序循环开始时清除显示并在应用程序循环结束时更新显示:

class Game:
    # [...]

    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()                    # <---
class Snake:
    # [...]

    def draw(self):
        # self.board.fill((0, 255, 0))                          <-- DELETE
        for i in range(self.length): 
            self.board.blit(self.image, (self.x[i], self.y[i]))
        # pygame.display.flip()                                 <-- DELETE
class Apple:
    # [...]

    def spawn(self):
        self.board.blit(self.image, (self.x, self.y))
        #pygame.display.flip()                          <-- DELETE

fill 清除整个 Surface。之前绘制的所有内容都丢失了。
在应用程序循环结束时更新一次显示就足够了。多次调用 pygame.display.update()pygame.display.flip() 会导致闪烁。