PiggyTheFirstAstro
PiggyTheFirstAstro

Reputation: 83

AttributeError: 'pygame.Rect' object has no attribute 'rect' error when doing collision

So I'm trying to make collision detection for my game using instances. Here's the code:

class Paddle:
def __init__(self, x, y, width, height, rect):
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.rect = pygame.rect.Rect(x, y, width, height)
class Ball:
    coordinateX = 600
    coordinateY = 300
    velocity = [random.randint(0,1),random.randint(-1,1)]

player = (Paddle(1100, 300, 10, 30, (1100, 300, 10, 30)))
enemy = Paddle(100, 300, 10, 30, (100, 30, 10, 30))
ball = (Ball.coordinateX, Ball.coordinateY, 15)

And later on:

ballRect = pygame.rect.Rect(Ball.coordinateX, Ball.coordinateY, 10, 10)
if pygame.sprite.collide_rect(player, ballRect):
    bounce()

Upvotes: 3

Views: 7214

Answers (3)

underscoreC
underscoreC

Reputation: 749

First of all, when creating the rect attribute for your ball, it should be self.rect = pygame.Rect(x, y, width, height) (assuming you import Pygame with import pygame). That should handle your AttributeError. Same goes for your ballRect, ballRect = pygame.Rect(Ball.coordinateX, Ball.coordinateY, 10, 10).

Next, you're using the wrong rect collision detection function. pygame.sprite refers to something completely different in Pygame (its Sprite objects), and neither your Ball nor Paddle class are Pygame Sprites, from the code you wrote. Thus, calling pygame.sprite.collide_rect() makes no sense here.

Instead, you should simply use rect.colliderect, like so:

if rect.colliderect(other_rect):
    # Colliding!
    print("Stop touching me!")

or in your case:

if player.rect.colliderect(ballRect):
    bounce()

Furthermore, you don't need to pass a rect as an argument to your Paddle initialization, because it's never used. The object's rect in completely generated from your other arguments.

Finally, your Ball class and instantiation code seems a little bit off. You should generate and initialize it like you do for Paddle.

EDIT One last thing. In pygame, when you create an object with a rect attribute, you no longer need to assign x and y values to the object, because whenever you'll need them, say, in a blit, you can just pass the rect directly (or rect.x and rect.y in some edge cases) as the position argument, and pygame will nicely handle the rest.

Here's what your code should look like (with a few other things fixed):

class Paddle():
    def __init__(self, x, y, width, height):
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x, y, width, height)

class Ball():
    def __init__(self, x, y, width, height):
        self.rect = pygame.Rect(x, y, width, height)
        self.velocity = [random.randint(0,1),random.randint(-1,1)]

player = Paddle(1100, 300, 10, 30)
enemy = Paddle(100, 300, 10, 30)
ball = Ball(600, 300, 10, 10)

# Other stuff

# Collision checking
if player.rect.colliderect(ball.rect):
    bounce()

Upvotes: 3

sloth
sloth

Reputation: 101042

As the module name 'sprite' hints, the function pygame.sprite.collide_rect and all other collision detection functions expect Sprite instances as arguments.

Look at the documentation:

pygame.sprite.collide_rect()
Collision detection between two sprites, using rects.
collide_rect(left, right) -> bool

Tests for collision between two sprites. Uses the pygame rect colliderect function to calculate the collision. Intended to be passed as a collided callback function to the *collide functions. Sprites must have a "rect" attributes.

(Also, usually you don't use this function directly, but together with a Group).

So either start using the Sprite class (which is what you should do) or use the functions that the Rect class provides, like colliderect:

colliderect()
test if two rectangles overlap
colliderect(Rect) -> bool

Returns true if any portion of either rectangle overlap (except the top+bottom or left+right edges).

Upvotes: 3

Seysen
Seysen

Reputation: 134

According to documentation, the pygame.sprite.collide_rect() is used to detect collision between two sprites, however you are passing a pygame.rect.Rect() object, and a Paddle object.

So, what you need to do is have two objects created using pygame.sprite.Sprite and then detect collision between them, if you want to use pygame.sprite.collide_rect()

Upvotes: 1

Related Questions