Why Is My Collision Test Always Returning 'True' and Why Is the Position of the Rectangle of the Image Always Wrong (0, 0)

Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.

The Surface is placed at a position on the display with the blit function.

You've to set the location of the rectangle, either by a keyword argument, e.g:

self.rect = self.image.get_rect(topleft = (self.x, self.y))

or an assignment to a virtual attribute (see pygame.Rect), e.g:

self.rect = self.image.get_rect()
self.rect.topleft = (self.x, self.y)

It is absolutely unnecessary to add some extra attributes self.x and self.y. Use the location of the rectangle instead. e.g:

class Ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect(topleft = (280, 475))
self.col = False
def update(self):
gameDisplay.blit(self.image, self.rect)
def test_collisions(self,sprite):
self.col = pygame.sprite.collide_rect(self,sprite)

class Obstacle(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect(topleft = (1000, 483))
def change_x(self):
self.time = pygame.time.get_ticks()
self.rect.x = -(self.time/5) + 800
def update(self):
gameDisplay.blit(self.image, self.rect)

Further note, that you can get rid of the methods Ball.update() respectively Obstacle.update() (you can delete them), if you use a pygame.sprite.Group and call .draw(), which uses the .image and .rect properties of the contained sprites, to draw them. e.g.:

obstacle = Obstacle()
ball = Ball()
all_sprites = pygame.sprite.Group([obstacle, ball])

while not crashed:

# [...]

gameDisplay.fill((255,255,255))

all_sprites.draw(gameDisplay)

pygame.display.flip()
clock.tick(1000)

Why is my Pygame Collision always colliding?

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.

The Surface is placed at a position when it is blit to the display.

You've to set the location of the rectangle, by a keyword argument. In the following (player_x, player_y) are the coordinates of the player and (hole_x, hole_y) ar eth coordinates of the hole:

player_collison_box = player.get_rect(topleft = (player_x, player_y))
hole_collision_box = hole.get_rect(topleft = (hole_x, hole_y))
if player_collison_box.colliderect(hole_collision_box):
print('collision')

Button's rectangle is in the wrong place

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. The Surface is placed at a position when it is blit to the display. The position of the rectangle can be specified by a keyword argument. For example, the top ledt of the rectangle can be specified with the keyword argument topleft. These keyword argument are applied to the attributes of the pygame.Rect before it is returned (see pygame.Rect for a full list of the keyword arguments).

You only need to change 2 lines of your code:

clickimage = pygame.image.load('block.png')
button = pygame.image.load('button.png')
boxclip = clickimage.get_rect(topleft = (50, 50)) # <---
buttonclip = button.get_rect(topleft = (500, 50)) # <---

# [...]
running = True
while running:
# [...]

screen.blit(clickimage, boxclip)
screen.blit(button, buttonclip)

# [...]

image and rect of a image are not on top of each other, they are shifted. what is wrong

Just return new_rect from blitRotateCenter and use it to draw the rectangle:

def blitRotateCenter(image, left, top, angle):
rotated_image = pygame.transform.rotate(image, angle)
new_rect = rotated_image.get_rect(center = image.get_rect(center = (left, top)).center)
screen.blit(rotated_image, new_rect)
return new_rect
new_auto_rect = blitRotateCenter(auto.image, auto.rect.x, auto.rect.y, auto.wagen_winkel)
draw.rect(screen,red, new_auto_rect)

However, if you want to draw a rotated rectangle, see Getting rotated rect of rotated image in Pygame.

AttributeError: 'pygame.Surface' object has no attribute 'get_rect'

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the top left of the rectangle can be specified with the keyword argument topleft:

if bcard.get_rect().collidepoint(mx, my):

if bcard.get_rect(topleft = (30, 200)).collidepoint(mx, my):
print('clicked on image')


Related Topics



Leave a reply



Submit