1

I have a game I made with Pygame and I added a "small" update to where a sprite changes to another sprite for 80ms when pressing space, this makes the whole game lag (not just when pressing space but all the time). Can anyone help? :)

Here is SOME of the code BEFORE the "update":

man.py

class Man(Sprite):
    def __init__(self, ai_settings, screen):
        super().__init__()
        self.screen = screen

        # Load the image of the man and get its rect.
        self.image = pygame.image.load('images/man_gun_large.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Man firing gun sprite
        self.fire = pygame.image.load('images/man_gun_large_fire.bmp')
        self.fire_rect = self.fire.get_rect()
        self.screen_fire_rect = self.screen.get_rect()

        self.ai_settings = ai_settings

        # Start each new man at the bottom center of the screen.
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        self.fire_rect.centerx = self.screen_rect.centerx
        self.fire_rect.top = self.screen_rect.bottom

        # Store a decimal value for the man's center.
        self.center = float(self.rect.centerx)

        # Movement flags
        self.moving_right = False
        self.moving_left = False

        self.orientation = False

    def update(self):
        # Update the man's center value, not the rect
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.man_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.man_speed_factor

        # Update rect object from self.center.
        self.rect.centerx = self.center

    def blitme(self):
        # Draw sprite
        self.screen.blit(self.image, self.rect)

        # Flip sprite depending on right/left key
        if self.orientation == "Right":
            self.screen.blit(self.image, self.rect)
        elif self.orientation == "Left":
            self.screen.blit(pygame.transform.flip(self.image, True, False), 
            self.rect)

game_functions.py

def fire_bullet(ai_settings, bullets, screen, man):
    # Fire a bullet as long as max bullets is not reached
    # Create a new bullet and add it to the bullets group.
    if len(bullets) < ai_settings.bullets_allowed:
        fire_sound.play()
        new_bullet = Bullet(ai_settings, screen, man)
        bullets.add(new_bullet)

And here is the same code AFTER the "update":

man.py

class Man(Sprite):
    # --- SNIP ---

        # A field to keep track of timeout
        self.timeout = 0

    def update(self):
        # --- SNIP ---

        clock = pygame.time.Clock()
        dt = clock.tick(60)

        if self.timeout > 0:
            self.timeout = max(self.timeout - dt, 0)

    def blitme(self):
        # --- SNIP ---

        # Change into firesprite when pressing space
        elif self.timeout > 0 and self.orientation == 'Right':
            self.screen.blit(self.fire, self.rect)
        elif self.timeout > 0 and self.orientation == 'Left':
            self.screen.blit(pygame.transform.flip(self.fire, True, False), 
            self.rect)

game_functions.py

def fire_bullet(ai_settings, bullets, screen, man):
    # --- SNIP ---
        man.timeout = 80
Rabbid76
  • 202,892
  • 27
  • 131
  • 174

1 Answers1

0

The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():

This method should be called once per frame.

You need to call clock.tick(60) once per frame, not once for each updated object. If you have more than one object, the method will be called more than once per frame and the game slows down as the number of objects increases.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174