You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame平台游戏运行15秒后卡顿变慢问题求助

Pygame平台游戏运行15秒后卡顿的原因及解决方法

问题描述

我正在开发一款尚未完成的Pygame平台游戏,初始运行流畅,但启动15秒后角色移动变得卡顿、游戏运行缓慢。

相关代码

class Game_Level(Main): #SUB CLASS FOR CREATING THE LEVEL  (INHERITANCE)
    #CONSTRUCTOR
    def __init__(self,x,y,scale_width,scale_height,speed,TILE_SIZE):
        self.TILE_SIZE = TILE_SIZE  #CREATES AN ATTRIBUTE CALLED TILE_SIZE AND ASSIGNS TO IT THE VALUE OF THE TILE_SIZE PARAMETER
        super().__init__(x,y,scale_width,scale_height,speed)
        #INSTANCE ATTRIBUTES
        self.TILE_SIZE = TILE_SIZE  #CREATES AN ATTRIBUTE CALLED TILE_SIZE AND ASSIGNS TO IT THE VALUE OF THE TILE_SIZE PARAMETER
        #CLASS ATTRIBUTES
        self.dirt_image = pygame.image.load('dirt_image1.jpg').convert() #IMAGE THAT IS DISPLAYED ON THE SCREEN AND USED FOR THE GAME MAP
        self.grass_image = pygame.image.load('grass_image1.jpg').convert() #IMAGE THAT IS DISPLAYED ON THE SCREEN AND USED FOR THE GAME MAP
        self.tile_rects = []

    def game_level(self):
        self.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','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','0','0','0','2','2','0','0','0','0','2','2','0','0','0','0','0'],
                        ['2','2','2','2','2','2','2','2','2','2','2','2','2','0','0','2','2'],
                        ['1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1'],
                        ['1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1'],
                        ['1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1'],
                        ['1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1']] 
        
        self.camera_value[0] += (self.player_rect.x-self.camera_value[0]-325) #X-AXIS
        self.camera_value[1] += (self.player_rect.y-self.camera_value[1]-325) #Y-AXIS
    
        next_row = 0
        for row in self.game_map: #LOOPS THROUGH EACH ROW
            each_block = 0
            for each_tile in row: #LOOPS THROUGH EVERY STRING IN THE ROW
                if each_tile == '1':
                    WINDOW.blit(self.dirt_image, (each_block * self.TILE_SIZE-self.camera_value[0], next_row * self.TILE_SIZE-self.camera_value[1]))
                if each_tile == '2':
                    WINDOW.blit(self.grass_image, (each_block * self.TILE_SIZE-self.camera_value[0], next_row * self.TILE_SIZE-self.camera_value[1]))
                if each_tile != '0':
                    self.tile_rects.append(pygame.Rect(each_block * self.TILE_SIZE, next_row * self.TILE_SIZE, self.TILE_SIZE, self.TILE_SIZE))
                each_block += 1
            next_row += 1
    
    def collision_test(self, tiles):
        hit_list = []
        for tile in tiles:
            if self.player_rect.colliderect(tile):
                hit_list.append(tile)
        return hit_list
    
    def collisions_with_tiles(self, movement, tiles):
        collision_types = {'top': False, 'bottom': False, 'right': False, 'left': False}
        self.player_rect.x += movement[0]
        hit_list = self.collision_test(tiles)
        for tile in hit_list:
            if movement[0] > 0:
                self.player_rect.right = tile.left
                collision_types['right'] = True
            elif movement[0] < 0:
                self.player_rect.left = tile.right
                collision_types['left'] = True
        self.player_rect.y += movement[1]
        hit_list = self.collision_test(tiles)
        for tile in hit_list:
            if movement[1] > 0:
                self.player_rect.bottom = tile.top
                collision_types['bottom'] = True
            elif movement[1] < 0:
                self.player_rect.top = tile.bottom
                collision_types['top'] = True
        return collision_types

    def player_movement(self):
        player_movement = [0, 0]
        if self.moving_right:
            self.moving_left = False
            player_movement[0] -= self.speed
        elif self.moving_left:
            self.moving_right = False
            player_movement[0] += self.speed
        player_movement[1] += self.player_y_momentum
        self.player_y_momentum += 0.3
        if self.player_y_momentum > 8:
            self.player_y_momentum = 8
        
        collisions = self.collisions_with_tiles(player_movement, self.tile_rects)

        if collisions['bottom']:
            self.player_y_momentum = 0
            self.air_timer = 0
        else:
            self.air_timer += 1
    
player = Game_Level(50,50,80,60,4,70)

def game_loop():
    clock = pygame.time.Clock()
    run = True
    while run: 
        clock.tick(FPS) #MAINTAIN 60 FPS
        WINDOW.fill(blue)
        #CALLING THE METHODS
        player.player_movement()
        player.game_level()
        player.player_keys() #ENCAPSULATION IS USED HERE- MY METHODS AND ATTRIBUTES ARE NOT ACCESSIBLE OUTSIDE THE OBJECT
        player.player_animation()
        pygame.display.update() #IT WON'T SHOW THE MOST RECENT THING I DREW UNLESS I MANUALLY UPDATE IT
        for event in pygame.event.get(): 
            if event.type == QUIT: 
                pygame.quit() #STOP PYGAME
                sys.exit() 

game_loop()

卡顿原因分析

核心问题在于tile_rects列表的无限增长:

  • 在game_level方法中,每次帧循环都会遍历游戏地图,将非0的tile矩形添加到self.tile_rects中,但从未清空这个列表。
  • 游戏每秒运行约60帧,每帧都会往列表里添加数十个Rect对象,15秒后列表会积累上千个重复的Rect。
  • 后续的collision_test和collisions_with_tiles方法需要遍历整个tile_rects列表做碰撞检测,随着列表越来越大,检测耗时呈线性增长,最终导致游戏卡顿。

解决方法

修改game_level方法,在生成新的tile矩形前先清空tile_rects列表:

def game_level(self):
    self.tile_rects.clear()  # 或者使用 self.tile_rects = []
    self.game_map = [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],                
                    # ... 原有地图代码 ...

这样每帧都会重新生成当前地图的tile矩形列表,避免重复积累,碰撞检测的耗时会保持稳定,游戏就能流畅运行。

内容的提问来源于stack exchange,提问作者CAKE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:10:36