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
Installing Pip Is Not Working in Python ≪ 3.6
How to Use Glob() to Find Files Recursively
How to Properly Determine the Current Script Directory
Multiple Assignment and Evaluation Order in Python
Explanation of How Nested List Comprehension Works
Py2Exe - Generate Single Executable File
Checking Whether a Variable Is an Integer or Not
How to Write Json Data to a File
Does Python Have "Private" Variables in Classes
What's the U Prefix in a Python String
Finding the Source Code For Built-In Python Functions
Word Boundary With Words Starting or Ending With Special Characters Gives Unexpected Results
Why Does Substring Slicing With Index Out of Range Work
Finding and Replacing Elements in a List
Django Template How to Look Up a Dictionary Value With a Variable