collide sound not playing in pygame

Viewed 37

I'm a newbie and following along to this tutorial to create a little endless runner in pygame. I'm finished with the code and now I want to add some polish, ie a sound that plays when the player collides with an object.

However, the code isn't working and I cannot figure out why. I've attempted tried to google it to little avail and I've implemented this suggestion and it's not working.

Here's what I have:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        player_walk_1 = pygame.image.load('Praxislabor/assets/graphics/pig_og.png').convert_alpha()         # initialize once, "self." can get called later
        player_walk_1 = pygame.transform.scale2x(player_walk_1)
        player_walk_2 = pygame.image.load('Praxislabor/assets/graphics/pig1_og.png').convert_alpha()
        player_walk_2 = pygame.transform.scale2x(player_walk_2)
        self.player_walk = [player_walk_1, player_walk_2]
        self.player_index = 0

        self.player_jump = pygame.image.load('Praxislabor/assets/graphics/pig1_og.png').convert_alpha()
        self.player_jump = pygame.transform.scale2x(self.player_jump)

        self.image = self.player_walk[self.player_index]
        self.rect = self.image.get_rect(bottomleft = (5, 268))
        self.gravity = 0

        self.jump_sound = pygame.mixer.Sound('Praxislabor/assets/audio/jump.wav')
        self.jump_sound.set_volume(0.8)

    def player_input(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and self.rect.bottom >= 268:
            self.gravity = -15
            self.jump_sound.play()

    def apply_gravity(self):
        self.gravity += 1
        self.rect.y += self.gravity
        if self.rect.bottom >= 268:
            self.rect.bottom = 268

    def animation_state(self):
        if self.rect.bottom > 268:
            self.image = self.player_jump
        else:
            self.player_index += 0.1
            if self.player_index >= len(self.player_walk):
                self.player_index = 0
            self.image = self.player_walk[int(self.player_index)]

    def update(self):
        self.player_input()
        self.apply_gravity()
        self.animation_state()

class Obstacle(pygame.sprite.Sprite):
    def __init__(self,type):
        super().__init__()
        
        if type == 'bird':
            bird_frame_1 = pygame.image.load('Praxislabor/assets/graphics/birb1.png').convert_alpha()
            bird_frame_1 = pygame.transform.scale2x(bird_frame_1)
            bird_frame_1 = pygame.transform.flip(bird_frame_1, 180, 0)
            bird_frame_2 = pygame.image.load('Praxislabor/assets/graphics/birb2.png').convert_alpha()
            bird_frame_2 = pygame.transform.scale2x(bird_frame_2)
            bird_frame_2 = pygame.transform.flip(bird_frame_2, 180, 0)
            self.frames = [bird_frame_1, bird_frame_2]
            y_pos = 230

        else: 
            if type == 'box':
                box1_surface = pygame.image.load('Praxislabor/assets/graphics/box1_og.png').convert_alpha()
                box1_surface = pygame.transform.scale2x(box1_surface)
                self.frames = [box1_surface]
                y_pos = 250
        
        self.animation_index = 0
        self.image = self.frames[self.animation_index]
        self.rect = self.image.get_rect(midbottom = (randint(900,1100),y_pos))

    def animation_state(self):
        self.animation_index += 0.1
        if self.animation_index >= len(self.frames):
            self.animation_index = 0
        self.image = self.frames[int(self.animation_index)]

    def update(self):
        self.animation_state()
        self.rect.x -= 6
        self.destroy()

    def destroy(self):
        if self.rect.x <= -100:
            self.kill()

And later where the problem lies:

def display_score():
    current_time = int(pygame.time.get_ticks() / 1000) - start_time                     # get ticks as int, divide to only display smaller numbers, substract play time
    score_surface = font.render(f'Score: {current_time}', False, '#536E75')             # f string converts integer to string
    score_rect = score_surface.get_rect(topleft = (5, 5))
    screen.blit(score_surface, score_rect)
    return current_time

def collisions(player, obstacles):
    collision_sound = pygame.mixer.Sound('Praxislabor/assets/audio/collision.wav')
    if obstacles:
        for obstacle_rect in obstacles:
            if player.colliderect(obstacle_rect):
                collision_sound.play()
                return False
    return True

def collision_sprite():
    if pygame.sprite.spritecollide(player.sprite,obstacle_group,False):                     # sprite, group, boolean
        obstacle_group.empty()
        return False
    else:
        return True

The if player.colliderect(obstacle_rect) does nothing, though I tried an earlier version that didn't have the classes yet, and THEN it works.

0 Answers
Related