0

Here is the error I get:

Traceback (most recent call last):
  File "C:\Users\Mendel Hornbacher\My programs\Spaceblaster\SpaceBlaster0.0.2b.py", line 95, in <module>
    animate()
  File "C:\Users\Mendel Hornbacher\My programs\Spaceblaster\SpaceBlaster0.0.2b.py", line 53, in animate
    ship.hit(astroid_list)
  File "C:\Users\Mendel Hornbacher\My programs\Spaceblaster\SpaceBlaster0.0.2b.py", line 34, in hit
    if pygame.sprite.spritecollide(self, item, False):
  File "C:\Python33\lib\site-packages\pygame\sprite.py", line 1515, in spritecollide
    return [s for s in group if spritecollide(s.rect)]
TypeError: 'Astroid' object is not iterable

and these are the classes involved:

  1. animate:

    def animate():
        ship.hit(astroid_list)
        ship.move()
        screen.fill([0,0,0])
        astroid_list.draw(screen)
        screen.blit(ship.image, ship.rect)
        pygame.display.flip()
    
  2. self.hit (in 'Ship' class)

    def hit(self, group):
            for item in group:
                group.remove(item)
                if pygame.sprite.spritecollide(self, item, False):
                    self.die()
                group.add(item)
    
  3. astroid_list

    astroid_list = pygame.sprite.Group()
    

If it means anything I'm running windows 8 pro. If the above code is not enough I'll post the whole code in a comment.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Menachem Hornbacher
  • 2,080
  • 2
  • 24
  • 36

2 Answers2

2

You are passing a single sprite to spritecollide when it expects to get a list of sprites. This is causing the exception to be thrown because your Astroid is not a iterable class.

def hit(self, group):
    if pygame.sprite.spritecollide(self, group, False):
        self.die()

Spritecollide documentation

Nice little tip from the documentation is that pygame.sprite.spritecollideany is slightly faster then the regular spritecollide and would be probably a better choice since you do not care what you collided with it appears, so you do not need to return what you have collided with.

sean
  • 3,955
  • 21
  • 28
0

The spritecollide function expects you to pass a Group, not individual sprites.

Just test with your whole group in one go:

def hit(self, group):
    if pygame.sprite.spritecollide(self, group, False):
        self.die()

Now you also avoid removing and adding items to a list while looping over it.

If you want to remove the sprites self collides with from the group, do so after calling spritecollide():

def hit(self, group):
    collided = pygame.sprite.spritecollide(self, group, False)
    for item in collided:
        group.remove(item)
    if collided:
        self.die()

Instead of manually removing each item though, you could just set the dokill flag to True, and they will be removed from the group for you:

def hit(self, group):
    if pygame.sprite.spritecollide(self, group, True):
        self.die()

If you do not need to know what items collided and do not want to remove items from the group, use spritecollideany() instead; it returns just True or False and is faster:

def hit(self, group):
    if pygame.sprite.spritecollideany(self, group):
        self.die()
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343