我似乎无法将表面正确地块化到屏幕上

I can't seem to properly blit surfaces onto screen

这是我的代码,我试图了解如何能够将我创建的表面显示到主屏幕 SCREEN 上。我将迷宫绘制到另一个表面上,然后将该表面复制到主屏幕上。然后我将 PacMan 表面 blit 到主屏幕上,我也试图将背景图像 blit 到屏幕上。我的问题是如何正确地对它们进行 blit,例如我是先对迷宫进行 blit,然后对 PacMan 然后对背景进行 blit,或者对它们进行 blit 的正确顺序是什么?

至于 PacManBite 功能,我正在更新 PacManStartSurface 以使其具有咬点的效果,但随后我也更新了整个屏幕,有没有办法正确使用 pygame.update() 函数,因为我认为这就是屏幕容易闪烁的原因?

我还想使用 SCREEN.fill(BLACK) 以便它可以摆脱 PacMan 留下的任何痕迹,但出于某种原因我不知道将它放在我的主循环中的什么位置。任何帮助将不胜感激。

import pygame

pygame.init()
pygame.display.set_caption("Pac-Man")

# Sets the size of the screen via (WIDTH, HEIGHT)
SCREEN_WIDTH = 475
SCREEN_HEIGHT = 608
# Speed of Characters
SPEED = 1
# Frames per second, how fast the game runs
FPS = 50
# Colors (RED,GREEN,BLUE)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)

HIGH_SCORE = 0

# Sets the WIDTH and HEIGHT of the window
WINDOW = (SCREEN_WIDTH, SCREEN_HEIGHT)
# Displays the screen
SCREEN = pygame.display.set_mode(WINDOW)
CLOCK = pygame.time.Clock()

PacManStartSurface = pygame.transform.scale(pygame.image.load 
                                           ("PacManStart.png").convert(), 
                                           (25, 25))
PacManStartRect = PacManStartSurface.get_rect(topleft = 
                                             (((SCREEN_WIDTH - 22) // 2),
                                             (SCREEN_HEIGHT + 225) // 2))

PacManSurface = pygame.transform.scale(pygame.image.load 
                                      ("PacManRight.png").convert(), (25, 25))
PacManRect = PacManStartSurface.get_rect(topleft = 
                                        (((SCREEN_WIDTH - 22) // 2),
                                        (SCREEN_HEIGHT + 225) // 2))

CurrentSurface = PacManStartSurface
CurrentRect = PacManStartRect

BackgroundSurface = pygame.image.load("Background.png").convert()

class PacMan():
    def __init__(self):
        self.LIVES = 3
        
class PowerUp(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("PowerUp.png")
                                            .convert(), (23, 23))
        self.mask = pygame.mask.from_surface(self.image)
        
class YellowGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("YellowGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class RedGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("RedGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class BlueGhost(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(pygame.image.load("BlueGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class PinkGhost(pygame.sprite.Sprite):
    def __init__(self):        
        self.image = pygame.transform.scale(pygame.image.load("PinkGhost.png")
                                           .convert(), (23, 23))
        self.rect = self.image.get_rect(topleft = (235, 347))
        self.mask = pygame.mask.from_surface(self.image)
        
class Maze():
    def __init__(self):
        self.DOTS = []
        self.WALLS = []
        self.BLOCK_WIDTH = 22
        self.BLOCK_HEIGHT = 22
        self.MARGIN = 3
        # 0 - Dots
        # 1 - Walls
        # 2 - Power Up
        # 3 - Empty Space
        # 4 - Ghosts
        self.MATRIX = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], \
                      [1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
                      [1,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,1], \
                      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
                      [1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1], \
                      [1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
                      [1,1,1,1,0,1,1,1,3,1,3,1,1,1,0,1,1,1,1], \
                      [3,3,3,1,0,1,3,3,3,3,3,3,3,1,0,1,3,3,3], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
                      [0,0,0,0,0,3,3,1,4,4,4,1,3,3,0,0,0,0,0], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
                      [3,3,3,1,0,1,3,3,3,3,3,3,3,1,0,1,3,3,3], \
                      [1,1,1,1,0,1,3,1,1,1,1,1,3,1,0,1,1,1,1], \
                      [1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
                      [1,2,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,2,1], \
                      [1,0,0,1,0,0,0,0,0,3,0,0,0,0,0,1,0,0,1], \
                      [1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1], \
                      [1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
                      [1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1], \
                      [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
                      [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
        self.MAZE_HEIGHT = (self.MARGIN + self.BLOCK_HEIGHT) \
                           * len(self.MATRIX)
        self.MAZE_WIDTH = (self.MARGIN + self.BLOCK_WIDTH) \
                          * len(self.MATRIX[0])
        
    def DrawGrid(self, MazeSurface):
        for ROW in range(len(self.MATRIX)):
            for COLUMN in range(len(self.MATRIX[0])):
                if self.MATRIX[ROW][COLUMN] == 0:
                    self.DOTS.append(pygame.draw.circle(MazeSurface, YELLOW, 
                                    [((self.MARGIN + self.BLOCK_WIDTH)
                                    * COLUMN + self.MARGIN) + 9,
                                    ((self.MARGIN + self.BLOCK_HEIGHT) 
                                    * ROW + self.MARGIN) + 50], 2))
                if self.MATRIX[ROW][COLUMN] == 1:
                    self.WALLS.append(pygame.draw.rect(MazeSurface, WHITE,
                                     [((self.MARGIN + self.BLOCK_WIDTH)
                                     * COLUMN + self.MARGIN) - 2,
                                     ((self.MARGIN + self.BLOCK_HEIGHT) 
                                     * ROW + self.MARGIN) + 41, 
                                     self.BLOCK_WIDTH, self.BLOCK_HEIGHT]))
                    

class Main(Maze):
    def __init__(self):
        # Inherits Maze class
        Maze.__init__(self)
        self.DIRECTION = ""
        self.SCORE = 0
        
    def Movement(self):
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT] and not key[pygame.K_UP] \
                              and not key[pygame.K_DOWN]:
            self.DIRECTION = "LEFT"
        elif key[pygame.K_RIGHT] and not key[pygame.K_UP] \
                               and not key[pygame.K_DOWN]:
            self.DIRECTION = "RIGHT"
        elif key[pygame.K_UP] and not key[pygame.K_LEFT] \
                            and not key[pygame.K_RIGHT]:
            self.DIRECTION = "UP"
        elif key[pygame.K_DOWN] and not key[pygame.K_LEFT] \
                              and not key[pygame.K_RIGHT]:
            self.DIRECTION = "DOWN"
            
    def ContinueMovement(self):
        if self.DIRECTION == "LEFT":
            CurrentRect.x -= SPEED
            self.WallDetection(-1, 0, CurrentRect)
        if self.DIRECTION == "RIGHT":
            CurrentRect.x += SPEED
            self.WallDetection(1, 0, CurrentRect)
        if self.DIRECTION == "UP":
            CurrentRect.y -= SPEED
            self.WallDetection(0, -1, CurrentRect)
        if self.DIRECTION == "DOWN":
            CurrentRect.y += SPEED
            self.WallDetection(0, 1, CurrentRect)

    def ChangeImage(self):
        global CurrentSurface
        if self.DIRECTION == "LEFT":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 180)
        if self.DIRECTION == "RIGHT":
            CurrentSurface = PacManSurface
        if self.DIRECTION == "UP":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 90)
        if self.DIRECTION == "DOWN":
            CurrentSurface = pygame.transform.rotate(PacManSurface, 270)
        
    def Teleport(self):
        if CurrentRect.right < 0:
            CurrentRect.right = SCREEN_WIDTH + 20
        if CurrentRect.left > SCREEN_WIDTH:
            CurrentRect.right = 0
    
    def WallDetection(self, x, y, CurrentRect):
        CurrentRect.right += x
        for wall in self.WALLS:
            collide = CurrentRect.colliderect(wall)
            if collide:
                if x < 0: 
                    CurrentRect.left = wall.right
                elif x > 0:
                    CurrentRect.right = wall.left
                break
        
        CurrentRect.top += y
        for wall in self.WALLS:
            collide = CurrentRect.colliderect(wall)
            if collide:
                if y < 0:
                    CurrentRect.top = wall.bottom
                if y > 0:
                    CurrentRect.bottom = wall.top
                break
            
    def EatDots(self):
        for ROW in range(len(self.MATRIX)):
            for COLUMN in range(len(self.MATRIX[0])):
                for DOT in self.DOTS:
                    chomp = CurrentRect.colliderect(DOT)
                    if chomp:
                        self.DOTS.remove(DOT)
                        self.MATRIX[ROW][COLUMN] = 3
                        self.SCORE += 10
                        return str(self.SCORE)
                        
    def EatGhosts(self):
        pass
    
    def EatPowerUp(self):
        pass
                
    def ShowText(self):
        Font = pygame.font.Font("emulogic.ttf", 15)
        OneUpText = Font.render("1UP", True, WHITE)
        OneUpTextRect = OneUpText.get_rect(center = (70, 10))
        OneUpScoreText = Font.render("00", True, WHITE)
        UpdateScore = Main.EatDots(self)
        if int(self.SCORE) > 0:
            OneUpScoreText = Font.render(UpdateScore, True, WHITE)
        OneUpScoreRect = OneUpScoreText.get_rect(center =
                                                ((SCREEN_WIDTH - 290) 
                                                // 2, 26))
        HighScoreText = Font.render("High Score", True, WHITE)
        HighScoreTextRect = HighScoreText.get_rect(center = 
                                                  (SCREEN_WIDTH // 2, 10))
        HighScoreNumber = Font.render("00", True, WHITE)
        HighScoreNumberRect = HighScoreNumber.get_rect(center = 
                                                      ((SCREEN_WIDTH + 90) 
                                                       // 2, 26))
        
        SCREEN.blit(OneUpText, OneUpTextRect)
        SCREEN.blit(OneUpScoreText, OneUpScoreRect)
        SCREEN.blit(HighScoreText, HighScoreTextRect)
        SCREEN.blit(HighScoreNumber, HighScoreNumberRect)
        
    def PacManBite(self):
        SCREEN.blit(PacManStartSurface, PacManStartRect)
        pygame.display.update()
    
Player = Main()

BackgroundImage = pygame.transform.scale(BackgroundSurface, 
                                        (Player.MAZE_WIDTH, 
                                         Player.MAZE_HEIGHT))
BackgroundRect = BackgroundImage.get_rect(topleft = (0, 41))

MazeSurface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT - 10))
MazeRect = MazeSurface.get_rect(topleft = ((SCREEN_WIDTH - 475, 
                                          SCREEN_HEIGHT - 608)))
Player.DrawGrid(MazeSurface)
    
'''
pregame = True
while pregame:
    if key button pressed:
        pregame = False
    run = True
'''

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            Player.Movement()
            Player.ChangeImage()
            Player.Teleport()   
            
    Player.ContinueMovement()
    Player.PacManBite()
    
    SCREEN.blit(MazeSurface, MazeRect)  
    MazeSurface.blit(CurrentSurface, CurrentRect)
    #SCREEN.blit(BackgroundImage, BackgroundRect)
    Player.ShowText()
    pygame.display.update()
    CLOCK.tick(FPS)
            
pygame.quit()

您必须 blit MazeSurface 上的 CurrentSurface,然后 blit SCREEN 上的 MazeSurface:

MazeSurface.blit(CurrentSurface, CurrentRect)
SCREEN.blit(MazeSurface, MazeRect)