Issue with sprites in pygame

47 views Asked by At

I am making a 2d game with lvls at lvl 4 a box should appear, after passing lvl 4 it should dissappear and be removed form the boxes list. Its removed from the boxes list but still appears on the screen. Please help me fix it.

I am making a 2d game with lvls at lvl 4 a box should appear, after passing lvl 4 it should dissappear and be removed form the boxes list. Its removed from the boxes list but still appears on the screen. Please help me fix it. I was expecting that at lvl 5 boxes list should hhave been empty and box sprite should have been dissapeared. List does get empty but the box doesn't dissappear.

import pygame

pygame.init()

clock = pygame.time.Clock()

win_res = [800, 600]

window = pygame.display.set_mode(win_res)
pygame.display.set_caption("Mini Golf")

bg_color = (120, 200, 255)
bg_image = pygame.image.load("data/images/background.png")
ground = pygame.image.load("data/images/ground.png").convert_alpha()
ground.set_colorkey((255, 255, 255))


class Sling_Shot(pygame.sprite.Sprite):
    def __init__(self, x, y, vel):
        super().__init__()
        self.image = pygame.image.load("data/images/sling_shot.png").convert_alpha()
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.vel = vel


class Stone(pygame.sprite.Sprite):
    def __init__(self, x, y, vel):
        super().__init__()
        self.image = pygame.image.load("data/images/stone.png")
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.vel = vel
        self.fired = False

    def update(self):
        if self.fired:
            self.rect.y -= self.vel


class Bird(pygame.sprite.Sprite):
    def __init__(self, x, y, vel, moving, direction):
        super().__init__()
        self.image = pygame.image.load("data/images/bird.png").convert_alpha()
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.vel = vel
        self.moving = moving
        self.dir = direction

    def update(self):
        if self.moving:
            self.rect.x += self.vel * self.dir
            if self.rect.x <= 100 or self.rect.x + self.rect.width >= 700:
                self.vel = -self.vel


def lvl_selector(lvl):
    birds = []

    match lvl:
        case 1:
            bird = Bird(365, 85, 2, False, 1)
            birds.append(bird)

        case 2:
            bird = Bird(365, 85, 2, True, 1)
            birds.append(bird)
            bird2 = Bird(365, 85, 2, True, 1)
            birds.append(bird2)

        case 3:
            bird = Bird(365, 85, 2, True, 1)
            bird2 = Bird(365, 205, 2, True, -1)
            birds.append(bird)
            birds.append(bird2)

        case 4:
            bird = Bird(365, 85, 2, True, 1)
            birds.append(bird)

        case 5:
            bird = Bird(365, 85, 2, True, -1)
            birds.append(bird)

    return birds


class Box(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load("data/images/box.png").convert_alpha()
        self.image.set_colorkey((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y


def box_selector(lvl):
    boxes = []

    match lvl:
        case 4:
            box = Box(590, 119)
            boxes.append(box)

        case _:
            boxes = []

    return boxes


def game_loop():
    sling_shot = Sling_Shot(375, 500, 5)
    stone = Stone(387.5, 485, 5)

    lvl = 3

    boxes = []

    all_sprites = pygame.sprite.Group()
    all_sprites.add(sling_shot, stone)
    birds = lvl_selector(lvl)
    for bird in birds:
        all_sprites.add(bird)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONUP:
                stone.fired = True

        x = pygame.mouse.get_pos()[0]  # Get only the x-coordinate of the mouse

        if 120 <= x <= 670:
            sling_shot.rect.x = x - 25

        if not stone.fired:
            stone.rect.x = sling_shot.rect.x + 17.5

        if pygame.sprite.collide_rect(stone, sling_shot) and stone.vel < 0:
            stone.vel = -stone.vel  # Stop the stone when it hits the slingshot
            stone.rect.y = sling_shot.rect.y - 15
            stone.fired = False

            # Reset the stone's position if needed
            if not stone.fired:
                stone.rect.x = sling_shot.rect.x + 17.5

        for bird in birds.copy():
            if pygame.sprite.collide_rect(stone, bird):
                bird.kill()
                birds.remove(bird)
                if not birds:
                    stone.rect.y = sling_shot.rect.y-12.5
                    stone.rect.x = sling_shot.rect.x
                    stone.fired = False
                    lvl += 1
                    birds = lvl_selector(lvl)
                    boxes = box_selector(lvl)

        print(len(boxes))

        for bird in birds:
            all_sprites.add(bird)

        for box in boxes:
            if pygame.sprite.collide_rect(stone, box):
                stone.vel = -stone.vel

        if lvl == 4:
            for box in boxes:
                all_sprites.add(box)
            for bird in birds:
                if bird.rect.x + bird.rect.width >= 580 and bird.rect.y == 85:
                    bird.vel = -bird.vel

        if stone.rect.y <= 0 or stone.rect.y + stone.rect.width >= win_res[1]:
            stone.rect.y = sling_shot.rect.y - 12.5
            stone.rect.x = sling_shot.rect.x
            stone.fired = False

            # Clear the old birds
            for bird in birds:
                bird.kill()
            birds.clear()

            # Add new birds for the current level
            birds.extend(lvl_selector(lvl))
            boxes = box_selector(lvl)

        window.blit(bg_image, (0, 0))
        window.blit(ground, (0, 40))

        all_sprites.draw(window)
        all_sprites.update()

        pygame.display.update()
        clock.tick(60)

    pygame.quit()


game_loop()
1

There are 1 answers

0
Rabbid76 On BEST ANSWER

It is not enough to remove the sprite from the list, you also need remove the pygame.sprite.Sprite object from the pygame.sprite.Group. Sprites can be removed with pygame.sprite.Sprite.kill or pygame.sprite.Group.remove. e.g.:

def box_selector(lvl, boxes, sprite_group):
    
    match lvl:
        case 4:
            box = Box(590, 119)
            sprite_group.add(box)
            boxes.append(box)
            
        case _:
            sprite_group.remove(boxes)
            boxes.clear()
box_selector(lvl, boxes, all_sprites)