为什么我的 pygame 程序运行时间越长越慢?

Why is my pygame program gradually getting slower the longer it runs?

我正在制作一个平台游戏,玩家可以通过交换背景颜色来改变地形。所有机制都正常运行,但我的程序 运行s 的速度逐渐变得非常慢,我不知道为什么。我试过在一些地方整理我的代码,但我似乎无法以恒定的速度将它达到 运行。为什么会发生这种情况,我该如何解决?感谢你们提供的任何帮助或提示!

这是我的完整代码:

import pygame, sys
clock = pygame.time.Clock()
from pygame.locals import *
pygame.init()

window_size = (900,600)
window = pygame.display.set_mode(window_size)
pygame.display.set_caption('Pygame Platformer')

moving_right = False
moving_left = False

unit = 30
fall = 10
jump = -10
p_speed = 3.4

black =  (  0,   0,   0)
white =  (225, 225, 225)
teal =   (  0, 100, 100)
orange = (200,  75,   0)
grey =   ( 60,  60,  60)
red =    (170,   0,   0)

current_color = black
dark_color = grey
color_1 = teal
color_2 = red

game_map = [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','2','2','2','2','2','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['2','2','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2'],
            ['1','1','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','1','1'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','3'],]

##############################################################################

class player():
    def __init__(self):
        self.rect = pygame.Rect(100,100,unit,unit)
        self.vertical_momentum = 0
        self.player_movement = []
        self.jump_timer = 0
    def movement(self):
        self.player_movement = [0,0]
        if moving_right == True:
            self.player_movement[0] += p_speed
        if moving_left == True:
            self.player_movement[0] -= p_speed
        self.player_movement[1] += self.vertical_momentum
        self.vertical_momentum += 0.4
        if self.vertical_momentum > fall:
            self.vertical_momentum = fall
    def draw(self, display):
        pygame.draw.rect(display, dark_color, (self.rect.x, self.rect.y, unit, unit))
        
class room_0():
    def __init__(self, block_map):
        self.block_map = game_map
        self.dark_blocks = []
        self.color_blocks = []
    def draw(self, window):
        global tile_rects
        tile_rects = []
        y = 0
        for layer in self.block_map:
            x = 0
            for tile in layer:
                if tile == '1':
                    if current_color != color_1:
                        current_room.color_blocks.append(color_block(color_1, x*unit, y*unit))
                        tile_rects.append(pygame.Rect(x*unit,y*unit,unit,unit))
                elif tile == '2':
                    if current_color != color_2:
                        current_room.color_blocks.append(color_block(color_2, x*unit, y*unit))
                        tile_rects.append(pygame.Rect(x*unit,y*unit,unit,unit))
                elif tile == '3':
                    self.dark_blocks.append(dark_block(x*unit,y*unit))
                    tile_rects.append(pygame.Rect(x*unit,y*unit,unit,unit))
                x += 1
            y += 1        
        for i in self.dark_blocks:
            i.draw(window)
        for i in self.color_blocks:
            i.draw(window)

class dark_block():
    def __init__(self, x_position, y_position):
        self.x = x_position
        self.y = y_position
    def draw(self, window):
        pygame.draw.rect(window, dark_color, (self.x, self.y, unit, unit))
        
class color_block():
    def __init__(self, color, x_position, y_position):
        self.co = color
        self.x = x_position
        self.y = y_position
    def draw(self, window):
        pygame.draw.rect(window, self.co, (self.x, self.y, unit, unit))

tile_rects = []

p = player()

def collision_test(rect,tiles):
    hit_list = []
    for tile in tiles:
        if rect.colliderect(tile):
            hit_list.append(tile)
    return hit_list

def move(rect,movement,tiles):
    collision_types = {'top':False,'bottom':False,'right':False,'left':False}
    rect.x += movement[0]
    hit_list = collision_test(rect,tiles)
    for tile in hit_list:
        if movement[0] > 0:
            rect.right = tile.left
            collision_types['right'] = True
        elif movement[0] < 0:
            rect.left = tile.right
            collision_types['left'] = True
    rect.y += movement[1]
    hit_list = collision_test(rect,tiles)
    for tile in hit_list:
        if movement[1] > 0:
            rect.bottom = tile.top
            collision_types['bottom'] = True
        elif movement[1] < 0:
            rect.top = tile.bottom
            collision_types['top'] = True
    return rect, collision_types

def object_movement():
    global tile_rects
    p.movement()
    p.rect,collisions = move(p.rect,p.player_movement,tile_rects)

    if collisions['bottom'] == True:
        p.jump_timer = 0
        p.vertical_momentum = 0
    else:
        p.jump_timer += 1
    if collisions['top'] == True:
        p.vertical_momentum = 0

def redraw_game_window():
    window.fill(current_color)
    current_room.draw(window)
    p.draw(window)
    pygame.display.update()

##############################################################################
rooms = [room_0(game_map)]
current_room = rooms[0]

t = 0

while True: # game loop
    
    t +=1
    print(t)

    for event in pygame.event.get(): # event loop
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key == K_d:
                moving_right = True
            if event.key == K_a:
                moving_left = True
            if event.key == K_SPACE:
                if p.jump_timer < 5:
                    p.vertical_momentum = jump
            if event.key == K_LEFT:             # color swapping
                if current_color != color_1:
                    current_color = color_1
                    dark_color = black
                else:
                    current_color = black
                    dark_color = grey
            if event.key == K_RIGHT:
                if current_color != color_2:
                    current_color = color_2
                    dark_color = black
                else:
                    current_color = black
                    dark_color = grey
        if event.type == KEYUP:
            if event.key == K_d:
                moving_right = False
            if event.key == K_a:
                moving_left = False
        
    object_movement()
    redraw_game_window()
    clock.tick(60)

这个问题是因为容器(列表)self.dark_blocksself.color_blocks 在每一帧都被重新填充,但是你没有清除它们。因此,容器中的元素数量不断增长。由于此列表的内容是在每一帧中绘制的,因此性能会下降。你看不到这种效果,因为列表的元素是在彼此之上绘制的。

清除 room_0.draw 开头的 self.dark_blocksself.color_blocks,在清除 tile_rects 之后:

class room_0():
    # [...]

    def draw(self, window):
        global tile_rects
        tile_rects = []

        self.dark_blocks = []
        self.color_blocks = []

        # [...]