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

PiggyTheFirstAstro :

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()
underscoreC :

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()

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=401793&siteId=1