-1

New to pygame, writing a little code to try and detect collisions. Here is a small test file I wrote up to demonstrate the error. It instantiates two sprites, and tries to detect collision between them

import pygame

class Box(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
class Circle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()

box = Box()
circle = Circle()
group = pygame.sprite.Group()
group.add(circle)
pygame.sprite.spritecollideany(box, group)

However this returns an error:

default_sprite_collide_func = sprite.rect.colliderect
                                  ^^^^^^^^^^^
AttributeError: 'Box' object has no attribute 'rect'

I'm not really sure what I should be doing to remedy the situation. How can I detect collision between two sprites in pygame?

NOTE: edited to include proposed solution from an answer. I'm not making a new question since I'm still getting a similar error.

Math chiller
  • 4,123
  • 6
  • 28
  • 44
  • 1
    Are you certain you're supposed to pass the Classes to ```spritecollideany()```? Should you be instantiating those classes? i.e. ```box = Box()```? – ewokx Aug 08 '23 at 01:20

1 Answers1

1

The spritecolllideany function takes as parameters (sprite, group), i.e. the first parameter is a sprite instance and the second parameter is a sprite group (which contains one or more sprite instances).

In your example code, your are passing classes; it is equivalent to:

pygame.sprite.spritecollideany(Box, Circle) # passing the class objects, oops!

The error message might be a little confusing but it is giving some good clues about what is going on: it's essentially saying that the Box class has no attribute named rect (if an instance had been passed in, instead of the error saying type object 'Box'..., it would instead say 'Box' object...).

You'll probably need something more like:

box = Box() # create an instance
circle = Circle()
group = pygame.sprite.Group() # create a group with a sprite in it
group.add(circle)
hit = pygame.sprite.spritecollideany(box, group)
if hit:
  ... # there was a collision...

Note that your subclasses aren't calling the base Sprite class __init__ method, which you probably want to do. Also, your sprite subclasses don't currently do anything - you'll want to make them draw an image, for example.

I know you mentioned that your sample code is just a trimmed down example, so maybe you're already doing both of these things in your actual code. If not, the chimp example walks you through some of that.

Dave Brueck
  • 156
  • 6
  • 1
    This code still does not work. – Rabbid76 Aug 08 '23 at 05:11
  • I would note that it also produces the exact same error. To be clear, in my actual code I did something like this, I just reproduced a minimal example to demonstrate the issue. Edited question to rule out this answer. – Math chiller Aug 08 '23 at 13:35
  • Please double check that it is producing the *exact* same error - if the problem is that you made the changes I suggested but are getting an AttributeError with a message like "Box object has no attribute rect" (as opposed to the original msg about "type object Box"), then the error is saying exactly what you need: your sprite needs a 'rect' attribute. The docs for spritecollideany (linked above) say that you need to either provide the 'collided' callback or all the sprites involved need a 'rect' attribute. – Dave Brueck Aug 08 '23 at 16:55
  • Ok, I think you're right. – Math chiller Aug 09 '23 at 12:39