Python Forum
[PyGame] Sprites just randomly appear and dissapear in my pygame.sprite.GoupeSingle
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Sprites just randomly appear and dissapear in my pygame.sprite.GoupeSingle
#1
I am programming my first "real" game in pygame and now I ran into a Problem.

So I am trying to program the mainmenu of a game and it is already working that if I press the quit button, it quits and if I press the start button, it goes right into the game. But if i want to press the option button, my program should go into the options and for that I need to remove the start, the quit and the options sprite out of the group, so it can draw on the screen. After that I want to paint the screen black so the buttons dissapear and also I want to add a knew button at the bottom which says "back to menu..

So my problem is, that when I kill the sprites, only the option sprite gets killed, the other ones are just randomly getting added to the group again and I have no clue why. So in this case, when I want to go into the options, only the options button dissapears.


game.py

import pygame, turtle, sys
from Images import *
from level import *

#Hauptmenü

def update_Hauptmenü():
    if Hauptmenü_active == True:
        start.run(screen)
        options.run(screen)
        quit.run(screen)
        if start.collision(mouse_pos) == True:
            return False
        options.collision(mouse_pos,screen)
        quit.collision(mouse_pos)
        pygame.display.update()

def quit():
    pygame.quit()
    sys.exit()

def Hauptmenü():
    return update_Hauptmenü()

class Level:
    def __init__(self,level_data,surface):

        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self,layout):

        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()
        
        for row_index,row in enumerate(layout):
            for col_index,cell in enumerate(row):
                x = col_index * tile_size
                y = row_index * tile_size

                if cell == "X":
                    tile = Tile((x,y),tile_size)
                    self.tiles.add(tile)
                if cell == "P":
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)

    def scroll_x(self):
        player = self.player.sprite
        player_x = player.rect.centerx
        direction_x = player.direction.x

        if player_x < 400 and direction_x < 0:
            self.world_shift = 8
            player.speed = 0
        elif player_x > 1520 and direction_x > 0:
            self.world_shift = -8
            player.speed = 0
        else:
            self.world_shift = 0
            player.speed = 8

    def horizontal_movement_collision(self):
        player = self.player.sprite
        player.rect.x += player.direction.x * player.speed

        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left

    def vertikal_movement_collision(self):
        player = self.player.sprite
        player.apply_gravity()

        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom

    def update_game(self):
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        self.scroll_x()

        self.player.update()
        self.horizontal_movement_collision()
        self.vertikal_movement_collision()
        self.player.draw(self.display_surface)
pygame.init()

clock = pygame.time.Clock()

screen = pygame.display.set_mode((screen_width, screen_height))
background_sound = pygame.mixer.Sound("Background-Music.mp3")
background_sound.set_volume(0.7)
background_sound.play(loops = -1)
def_run = True
start = Start()
options = Options()
level = Level(level_map,screen)
quit = Quit()
btm = Btm()
menu_active = True
Hauptmenü_active = True
game_active = False

while True:

    print(start)
    print(options)
    print(quit)

    mouse_pos = pygame.mouse.get_pos()

    if Hauptmenü() == False:
        Hauptmenü_active = False
        game_active = True

    if Hauptmenü_active == True:
        screen.fill("black")
        Hauptmenü()

    if game_active == True:
        screen.fill("black")
        level.update_game()   
        
    
    pygame.display.update()
    clock.tick(60)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
Images.py

import pygame, sys

class Start(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Start.png")
        self.rect = self.image.get_rect(midbottom = (960,395))
        self.start = pygame.sprite.GroupSingle()
        self.start.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.start.update()
        self.start.draw(self.display_surface)
    def collision(self,mouse):
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    return True
                else:
                    return False

class Quit(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Quit.png")
        self.rect = self.image.get_rect(midbottom = (960,795))
        self.quit = pygame.sprite.GroupSingle()
        self.quit.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.quit.update()
        self.quit.draw(self.display_surface)
    def collision(self,mouse):
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    quit()

class Options(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Options.png")
        self.rect = self.image.get_rect(midbottom = (960,595))
        self.options = pygame.sprite.GroupSingle()
        self.options.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.options.update()
        self.options.draw(self.display_surface)
    def collision(self,mouse,screen):
        btm = Btm()
        start = Start()
        quit = Quit()
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.kill()
                    start.kill()
                    quit.kill()
                    btm.run(screen)

class Btm(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Backtomenu.png")
        self.rect = self.image.get_rect(midbottom = (960,850))
        self.btm = pygame.sprite.GroupSingle()
        self.btm.add(self)
    def run(self,screen):
        start = Start()
        options = Options()
        quit = Quit()
        self.kill()
        start.kill()
        quit.kill()
        print("______________")
        print(start)
        print(options)
        print(quit)
        self.display_surface = screen
        self.btm.update()
        screen.fill("black")
        self.btm.draw(self.display_surface)

####################################################################################################

class Tile(pygame.sprite.Sprite):
    def __init__(self,pos,size):
        super().__init__()
        self.image = pygame.Surface((size,size))
        self.image.fill("grey")
        self.rect = self.image.get_rect(topleft = pos )    

    def update(self,x_shift):
        self.rect.x += x_shift

class Player(pygame.sprite.Sprite):
    def __init__(self,pos):
        super().__init__()
        self.image = pygame.image.load("HTL.png")
        self.rect = self.image.get_rect(topleft = pos)
        
        
        self.direction = pygame.math.Vector2(0,0)
        self.speed = 8 
        self.gravity = 0.8
        self.jump_speed = -16

    def get_input(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0
    
        if keys[pygame.K_SPACE]:
            self.jump()

    def apply_gravity(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y

    def jump(self):
        self.direction.y = self.jump_speed

    def update  (self):
        self.get_input()
level.py

level_map = [
"                            ",
"         XXX                ",
"                            ",
" XX    XXX            XX    ",
" XX P                       ",
" XXXX         XX         XX ",
" XXXX       XX              ",
" XX    X  XXXX    XX  XX    ",
"       X  XXXX    XX  XXX   ",
"    XXXX  XXXXXX  XX  XXXX  ",
"XXXXxXXX  XXXXXX  XX  XXXX  "]

tile_size = 99
screen_width = 1920
screen_height = len(level_map) * tile_size
I have tried following the path, after the sprites should get killed but I did not find anything. I have also tried printing the groups before they get killed, after they got killed and in a while True loop to see where the problem is.
Reply
#2
update_Hauptmenu() calls pytame.display.update(), but it does nothing to "erase" sprites that have been removed. There is no erasing in Pygame, so if you want to erase something from the screen you have to paint over it, then draw all your sprites, and finally call display update() or flip().
Reply
#3
(Jan-12-2023, 08:28 PM)trueShadoWrr Wrote: I am programming my first "real" game in pygame and now I ran into a Problem.

So I am trying to program the mainmenu of a game and it is already working that if I press the quit button, it quits and if I press the start button, it goes right into the game. But if i want to press the option button, my program should go into the options and for that I need to remove the start, the quit and the options sprite out of the group, so it can draw on the screen. After that I want to paint the screen black so the buttons dissapear and also I want to add a knew button at the bottom which says "back to menu..

So my problem is, that when I kill the sprites, only the option sprite gets killed, the other ones are just randomly getting added to the group again and I have no clue why. So in this case, when I want to go into the options, only the options button dissapears.

You can Try found errors on StackOverflow
game.py

import pygame, turtle, sys
from Images import *
from level import *

#Hauptmenü

def update_Hauptmenü():
    if Hauptmenü_active == True:
        start.run(screen)
        options.run(screen)
        quit.run(screen)
        if start.collision(mouse_pos) == True:
            return False
        options.collision(mouse_pos,screen)
        quit.collision(mouse_pos)
        pygame.display.update()

def quit():
    pygame.quit()
    sys.exit()

def Hauptmenü():
    return update_Hauptmenü()

class Level:
    def __init__(self,level_data,surface):

        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0

    def setup_level(self,layout):

        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()
        
        for row_index,row in enumerate(layout):
            for col_index,cell in enumerate(row):
                x = col_index * tile_size
                y = row_index * tile_size

                if cell == "X":
                    tile = Tile((x,y),tile_size)
                    self.tiles.add(tile)
                if cell == "P":
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)

    def scroll_x(self):
        player = self.player.sprite
        player_x = player.rect.centerx
        direction_x = player.direction.x

        if player_x < 400 and direction_x < 0:
            self.world_shift = 8
            player.speed = 0
        elif player_x > 1520 and direction_x > 0:
            self.world_shift = -8
            player.speed = 0
        else:
            self.world_shift = 0
            player.speed = 8

    def horizontal_movement_collision(self):
        player = self.player.sprite
        player.rect.x += player.direction.x * player.speed

        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left

    def vertikal_movement_collision(self):
        player = self.player.sprite
        player.apply_gravity()

        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom

    def update_game(self):
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        self.scroll_x()

        self.player.update()
        self.horizontal_movement_collision()
        self.vertikal_movement_collision()
        self.player.draw(self.display_surface)
pygame.init()

clock = pygame.time.Clock()

screen = pygame.display.set_mode((screen_width, screen_height))
background_sound = pygame.mixer.Sound("Background-Music.mp3")
background_sound.set_volume(0.7)
background_sound.play(loops = -1)
def_run = True
start = Start()
options = Options()
level = Level(level_map,screen)
quit = Quit()
btm = Btm()
menu_active = True
Hauptmenü_active = True
game_active = False

while True:

    print(start)
    print(options)
    print(quit)

    mouse_pos = pygame.mouse.get_pos()

    if Hauptmenü() == False:
        Hauptmenü_active = False
        game_active = True

    if Hauptmenü_active == True:
        screen.fill("black")
        Hauptmenü()

    if game_active == True:
        screen.fill("black")
        level.update_game()   
        
    
    pygame.display.update()
    clock.tick(60)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
Images.py

import pygame, sys

class Start(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Start.png")
        self.rect = self.image.get_rect(midbottom = (960,395))
        self.start = pygame.sprite.GroupSingle()
        self.start.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.start.update()
        self.start.draw(self.display_surface)
    def collision(self,mouse):
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    return True
                else:
                    return False

class Quit(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Quit.png")
        self.rect = self.image.get_rect(midbottom = (960,795))
        self.quit = pygame.sprite.GroupSingle()
        self.quit.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.quit.update()
        self.quit.draw(self.display_surface)
    def collision(self,mouse):
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    quit()

class Options(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Options.png")
        self.rect = self.image.get_rect(midbottom = (960,595))
        self.options = pygame.sprite.GroupSingle()
        self.options.add(self)
    def run(self,screen):
        self.display_surface = screen
        self.options.update()
        self.options.draw(self.display_surface)
    def collision(self,mouse,screen):
        btm = Btm()
        start = Start()
        quit = Quit()
        if self.rect.collidepoint(mouse):
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.kill()
                    start.kill()
                    quit.kill()
                    btm.run(screen)

class Btm(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("Pygame-Graphics/Backtomenu.png")
        self.rect = self.image.get_rect(midbottom = (960,850))
        self.btm = pygame.sprite.GroupSingle()
        self.btm.add(self)
    def run(self,screen):
        start = Start()
        options = Options()
        quit = Quit()
        self.kill()
        start.kill()
        quit.kill()
        print("______________")
        print(start)
        print(options)
        print(quit)
        self.display_surface = screen
        self.btm.update()
        screen.fill("black")
        self.btm.draw(self.display_surface)

####################################################################################################

class Tile(pygame.sprite.Sprite):
    def __init__(self,pos,size):
        super().__init__()
        self.image = pygame.Surface((size,size))
        self.image.fill("grey")
        self.rect = self.image.get_rect(topleft = pos )    

    def update(self,x_shift):
        self.rect.x += x_shift

class Player(pygame.sprite.Sprite):
    def __init__(self,pos):
        super().__init__()
        self.image = pygame.image.load("HTL.png")
        self.rect = self.image.get_rect(topleft = pos)
        
        
        self.direction = pygame.math.Vector2(0,0)
        self.speed = 8 
        self.gravity = 0.8
        self.jump_speed = -16

    def get_input(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0
    
        if keys[pygame.K_SPACE]:
            self.jump()

    def apply_gravity(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y

    def jump(self):
        self.direction.y = self.jump_speed

    def update  (self):
        self.get_input()
level.py

level_map = [
"                            ",
"         XXX                ",
"                            ",
" XX    XXX            XX    ",
" XX P                       ",
" XXXX         XX         XX ",
" XXXX       XX              ",
" XX    X  XXXX    XX  XX    ",
"       X  XXXX    XX  XXX   ",
"    XXXX  XXXXXX  XX  XXXX  ",
"XXXXxXXX  XXXXXX  XX  XXXX  "]

tile_size = 99
screen_width = 1920
screen_height = len(level_map) * tile_size
I have tried following the path, after the sprites should get killed but I did not find anything. I have also tried printing the groups before they get killed, after they got killed and in a while True loop to see where the problem is.
Larz60+ write Feb-13-2023, 05:42 PM:
Vadanane,
What was your intent here?
Why the repost?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pygame, sprites, and rects menator01 12 2,001 Dec-07-2023, 02:37 AM
Last Post: Benixon
  player just randomly teleporting to the edge of a platform in pygame BliepMonster 5 2,350 Jan-26-2023, 10:12 PM
Last Post: deanhystad
  [PyGame] Pygame is treating blob_group as a surface, when I need it to treat it as a Sprite. Swagford 1 1,324 Jan-24-2023, 09:58 PM
Last Post: metulburr
  FileNotFoundError when I try putting sprite in Pygame zionkozisek 9 16,190 Dec-09-2020, 04:42 AM
Last Post: zionkozisek
  [PyGame] My Pygame Sprite not appearing... noodlespinbot 3 3,857 Oct-30-2020, 06:51 AM
Last Post: robinmurphy
  My Pygame Sprite not appearing... noodlespinbot 1 2,278 Apr-08-2020, 11:25 AM
Last Post: pyzyx3qwerty
  [PyGame] Sprite image.get_rect() moves sprite to 0, 0 michael1789 2 4,620 Dec-13-2019, 08:37 PM
Last Post: michael1789
  [PyGame] I found a way to generate sprites without .blit. Is it effecient? xBlackHeartx 19 8,520 Dec-07-2019, 01:06 PM
Last Post: metulburr
  Randomly selecting sprite from group? michael1789 5 4,148 Nov-14-2019, 10:43 PM
Last Post: michael1789
  Pygame sprite not moving michael1789 1 2,857 Nov-10-2019, 03:54 AM
Last Post: michael1789

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020