Search code examples
python-2.7pygamesprite

How to apply a sprite function to all the sprites in a sprite group?


I am rather new to programming and I am trying to figure out the basics of sprites.

So I have my sprite class, Bullet:

class Bullet(pygame.sprite.Sprite):
    def __init__(self,id_num):
        super(Bullet, self).__init__()
        self.image = pygame.image.load("bullet.png")
        self.rect = self.image.get_rect()
        self.id = id_num

    def test(self):
        print self.id

I created a sprite group, bullet_list, to put all the bullet sprites into.

Then when the mouse is clicked it will create a bullet, assign it a random id, and add it to the bullet_list group.

if event.type == pygame.MOUSEBUTTONUP:
    id_num = random.randint(1,5)
    fired_bullet = Bullet(id_num)
    bullet_list.add(fired_bullet)

Now here comes my problem... I can't figure out how to apply the test function to all the sprites in bullet_list. In this post it says to make iterate through bullet_list and apply the function to each instance. So I tried that, but when it prints out the id of the bullets, they're all the same when they should all be different.

    for i in bullet_list.sprites():
        fired_bullet.test()

I feel like the problem could be because all the bullets I create have the same name, fired_bullet.

I may be doing this completely wrong and it might be really simple so sorry in advance!

Here is my full code:

import pygame,sys,random
pygame.init()
screen = pygame.display.set_mode([800,500])

class Bullet(pygame.sprite.Sprite):
    def __init__(self,id_num):
        super(Bullet, self).__init__()
        self.image = pygame.image.load("bullet.png")
        self.rect = self.image.get_rect()
        self.id = id_num

    def test(self):
        print self.id

bullet_list = pygame.sprite.Group()

main = True
while main == True:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.MOUSEBUTTONUP:
            id_num = random.randint(1,5)
            fired_bullet = Bullet(id_num)
            bullet_list.add(fired_bullet)
            for i in bullet_list.sprites():
                fired_bullet.test()

Solution

  • If you're iterating through the group, you should be using the loop variable:

    for i in bullet_list.sprites():
        i.test()
    

    Although you should name it better, and you don't need to call sprites() - pygame sprite groups are iterables:

    for bullet in bullet_list:
        bullet.test()
    

    The fired_bullet variable is just going to be referring to the last bullet you fired.

    Also, you should never load your image file in the __init__() of the sprite - this means that every time you create a bullet, you're loading the image off the disk. This will be very slow and wasteful. Instead, load the image once at the beginning (and don't forget convert() - it speeds up drawing):

    bullet_img = pygame.image.load("bullet.png").convert()
    
    class Bullet(pygame.sprite.Sprite):
        def __init__(self,id_num):
            super(Bullet, self).__init__()
            self.image = bullet_img