PyGame 当我尝试将精灵添加到屏幕时滞后

PyGame lags when I try to add sprites to the screen

我正在尝试在 PyGame 中制作外星人入侵,当我 blit 宇宙飞船和子弹一切顺利时,但当我尝试从 sprite 组中绘制外星人时,游戏突然滞后。我已经尝试使用 convert() 函数,但即使在使用它之后它仍然滞后。 主要:

 import sys
    import pygame
    from settings import Settings
    from ship import Ship
    from bullet import Bullet 
    from alien import Alien 
    
    
    class AlienInvasion:
        """Overall class to manage game assests and behavior"""
        def __init__(self):
            """Initialize the game and create resources"""
            pygame.init()
            self.settings = Settings()
            self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
    
            
            pygame.display.set_caption("Alien Invasion")
    
            self.ship = Ship(self)
            self.bullets = pygame.sprite.Group()
            self.aliens = pygame.sprite.Group()
    
    
        def run_game(self):
            """Start the main loop for the game"""
            while True:
                clock.tick(60)
                self._check_events()
                self.ship.update()
                self._update_bullets()
                self._create_fleet()
                self._update_aliens()
                self._update_screen()
    
        def _check_events(self):
            #watch for keyboard and mouse events
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    self._check_keydown_events(event)
    
                elif event.type == pygame.KEYUP:
                    self._check_keyup_events(event)
    
        def _check_keydown_events(self, event):
            """Respond to keypress"""
            if event.key == pygame.K_RIGHT:
                self.ship.moving_right = True
            elif event.key == pygame.K_LEFT:
                self.ship.moving_left = True
            elif event.key == pygame.K_UP:
                self.ship.moving_up = True
            elif event.key == pygame.K_DOWN:
                self.ship.moving_down = True 
            elif event.key == pygame.K_q:
                sys.exit()
            elif event.key == pygame.K_SPACE:
                self._fire_bullet()
                self.ship.firing = True
    
    
        def _check_keyup_events(self, event):
            if event.key == pygame.K_RIGHT:
                self.ship.moving_right = False
            elif event.key == pygame.K_LEFT:
                self.ship.moving_left = False
            
    
        def _fire_bullet(self):
            if len(self.bullets) < self.settings.bullets_allowed:
                new_bullet = Bullet(self)
                self.bullets.add(new_bullet)
    
        def _update_bullets(self):
            self.bullets.update()
            #delete bullets
            for bullet in self.bullets.copy():
                if bullet.rect.bottom <= 0:
                    self.bullets.remove(bullet)
    
        def _update_aliens(self):
            """Update position of aliens"""
            self.aliens.update()
    
        def _create_fleet(self):
            alien = Alien(self)
            alien_width,alien_height = alien.rect.size
            available_space_x = self.settings.screen_width - (2 * alien_width)
            number_aliens_x = available_space_x // (2 * alien_width)
            #determine number of rows that fit on the screen
            ship_height = self.ship.rect.height
            available_space_y = self.settings.screen_height - (3*alien_height) - ship_height
            number_aliens_y = available_space_y // (2* alien_height)
            for row_number in range(number_aliens_y):
                for alien_number in range(number_aliens_x):
                    self._create_alien(alien_number, row_number)
    
        def _create_alien(self,alien_number,row_number):
            """Create alien and place it in a row"""
            alien = Alien(self)
            alien_width, alien_height = alien.rect.size
            alien.x = alien_width + 2 * alien_width * alien_number
            alien.rect.y = alien_height + 2 * alien_width * row_number 
            alien.rect.x = alien.x
            self.aliens.add(alien)
            
    
                    
        def _update_screen(self):
            self.screen.fill(self.settings.bg_color)
            self.ship.blitme()
            for bullet in self.bullets.sprites():
                bullet.draw_bullet()
            self._create_fleet()
            self.aliens.draw(self.screen)
    
            pygame.display.flip()
            
    if __name__ == '__main__':
        ai = AlienInvasion()
        ai.run_game(

外星人文件 this is the alien class 存储外星人。我已经将我的图像转换为 .bmp 文件,我也尝试过使用 convert() 函数,但它仍然滞后。

import pygame 
from pygame.sprite import Sprite 

class Alien(Sprite):
    """class that represents a single alien in a fleet"""
    def __init__(self, ai_game):
        #intialize alien and set position
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings

        #load alien image
        self.image = pygame.image.load('images/alien.bmp').convert()
        self.rect = self.image.get_rect()

        #start the alien at the top left of the screen
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        #store alien exact horizontal position
        self.x = float(self.rect.x)

    def update(self):
        #move alien to the right 
        self.x += self.settings.alien_speed
        self.rect.x = self.x

 

告诉我们你在每一帧都创建了舰队。因此,新的外星人会在每一帧中附加到 Group 并且你必须绘制比必要更多的外星人。更糟糕的是,'images/alien.bmp' 被加载到 class Alien 的构造函数中,因此必须在每一帧中加载多个图像:

class AlienInvasion:
   # [...]

   def _update_screen(self):
       # [...]

       self._create_fleet() # <----
       self.aliens.draw(self.screen) 

我建议在构建第一个外星人时将图像加载到 class 变量一次:
(参见 Class and Instance Variables

class Alien(Sprite):
    
    alienimage = None

    """class that represents a single alien in a fleet"""
    def __init__(self, ai_game):
        # [...]

        #load alien image
        if self.alienimage == None:
            self.alienimage = pygame.image.load('images/alien.bmp').convert()
        self.image = self.alienimage

        # [...]

在主应用程序循环之前创建队列:

class AlienInvasion:
    # [...]
    
    def run_game(self):
        
        self._create_fleet() # <---- ADD

        """Start the main loop for the game"""
        while True:
            clock.tick(60)
            self._check_events()
            self.ship.update()
            self._update_bullets()
            # self._create_fleet() <---- DELETE
            self._update_aliens()
            self._update_screen()

    # [...]

    def _update_screen(self):
       # [...]

       # self._create_fleet() <---- DELETE
       self.aliens.draw(self.screen)