Reputation: 83
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
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
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
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