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()
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)