My collide_rect function isn’t working properly. It always returns True, when it’s not suppose to. I have tried looking on the internet but nothing is working for me. I think the collide rect somehow did not use the actual coordinates for the two sprites. Can anyone help with this?
import pygame
import pygame.sprite
import sys
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption("test_collision")
clock = pygame.time.Clock()
crashed = False
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()
self.x = 280
self.y = 475
self.col = False
def update(self):
gameDisplay.blit(self.image, (self.x,self.y))
self.rect = self.image.get_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.x = 1000
self.y = 483
self.image = pygame.image.load("obstacle.png")
self.time = pygame.time.get_ticks()
self.rect = self.image.get_rect()
def change_x(self):
self.time = pygame.time.get_ticks()
self.x = -(self.time/5) + 800
def update(self):
self.rect = self.image.get_rect()
gameDisplay.blit(self.image,(self.x,self.y))
obstacle = Obstacle()
ball = Ball()
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
gameDisplay.fill((255,255,255))
ball.update()
obstacle.change_x()
obstacle.update()
ball.test_collisions(obstacle)
if ball.col:
print("colided")
pygame.display.flip()
clock.tick(1000)
pygame.quit()
sys.exit()
P.S This is my first post 🙂
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0