5

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

0

1 Answer 1

4

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) 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.