Search code examples
pythonpygame

How to use sprites in PyGame?


I want to draw 3 rows of rectangles. In doing so, I want to use pygame.sprite. Group(). I get the error message: TypeError: 'type' object is not subscriptable.I checked the error message here. Unfortunately I still don't understand why I get this error message. My pygame knowledge is not that deep.

import pygame, sys
import random
pygame.init()
clock = pygame.time.Clock()
bg = (173,216,230)
breite = 1000
hoehe = 800
screen = pygame.display.set_mode((breite,hoehe))

class Boden:
    def __init__(self):      
        self.blocks = []
        self.spalten =20
        self.sp = breite // self.spalten # breite des rechtecks
        self.ho = 10 # höhe des rechtecks
        self.zeilen = 3
        self.counter_z = -1 
        self.counter_s = -1        
    def bauboden(self):  
        self.counter_z +=0
        for i in range(self.zeilen):
            self.counter_z += 1          
            for j in range(self.spalten):
                self.counter_s += 1 
                block =  pygame.Rect[(i * self.ho,self.sp * j,self.sp,self.ho)]              
                alle_sprites.add(block) 
                self.blocks.add(self.block)


alle_sprites = pygame.sprite.Group() 
boden = pygame.sprite.Group()
boden = Boden()
boden.bauboden()

alle_sprites.add(boden)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()        
    alle_sprites.draw(screen)    
    pygame.display.flip()
    clock.tick(120)

Solution

  • Your first problem has nothing to do with pygame.sprite.Group(). However, pygame.Rect is an object:

    block = pygame.Rect[(i * self.ho,self.sp * j,self.sp,self.ho)]

    block =  pygame.Rect(i * self.ho,self.sp * j,self.sp,self.ho)
    

    But still you can't add a pygame.Rect to a pygame.sprite.Group().

    alle_sprites.add(block)

    You have to create a pygame.sprite.Sprite object. Here is a very basic example for using a Sprite in pygame (see also Sprite):

    repl.it/@Rabbid76/PyGame-Sprite

    import pygame
    
    pygame.init()
    window = pygame.display.set_mode((400, 400))
    clock = pygame.time.Clock()
    
    class Player(pygame.sprite.Sprite):
        
        def __init__(self, center_pos, image):
            super().__init__() 
            self.image = image
            self.rect = self.image.get_rect(center = center_pos)
        
        def update(self, surf):
            keys = pygame.key.get_pressed()
            self.rect.x += (keys[pygame.K_d]-keys[pygame.K_a]) * 5
            self.rect.y += (keys[pygame.K_s]-keys[pygame.K_w]) * 5
            self.rect.clamp_ip(surf.get_rect())
    
    player_surf = pygame.image.load('Bird64.png').convert_alpha()
    player = Player(window.get_rect().center, player_surf)
    all_sprites = pygame.sprite.Group([player])
    
    run = True
    while run:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    
        all_sprites.update(window)
    
        window.fill(0)
        all_sprites.draw(window)
        pygame.display.flip()
    
    pygame.quit()
    exit()
    

    An image can be loaded to a pygame.Surface object with pygame.image.load. See How to draw images and sprites in pygame?.

    A pygame.sprite.Sprite encapsulates an pygame.Surface object and an pygame.Rect object. It should have and an image and a rect attribute. image stores the sprite and rect stores the position and size of the sprite.

    pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.

    The latter delegates to the update method of the contained pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update():

    Calls the update() method on all Sprites in the Group. [...]

    The former uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():

    Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]

    The Sprites in the Groups can be removed and thus destroyed by calling pygame.sprite.Sprite.kill. When the object is no longer referenced, it is destroyed:

    The Sprite is removed from all the Groups that contain it. This won't change anything about the state of the Sprite. It is possible to continue to use the Sprite after this method has been called, including adding it to Groups.