Search code examples
pythonpygamecollision-detection

collision error self.rect.colliderect(sprite.rect)


This code starts printing "collision" before it hits the sprite.

This defines the "bullet"

class Magic(pygame.sprite.Sprite):

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.image = pygame.image.load("Magic.png")
        self.rect = self.image.get_rect()
        pygame.sprite.Sprite.__init__(self, spritegroup)

    def is_collided_with(self, sprite):
        return self.rect.colliderect(sprite.rect)

This is the collision detection code

            if magic.is_collided_with(enemy1):
                print("collision")
                enemy1.kill()

This defines the enemy

class Enemy(pygame.sprite.Sprite):

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.image = pygame.image.load("Enemy1.png")
        self.rect = self.image.get_rect()
        pygame.sprite.Sprite.__init__(self, spritegroup)


    def render(self):
        screen.blit(self.image, (self.x, self.y))

enemy1 is the enemy defined below enemy1 = Enemy(1400, 50)


Solution

  • 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, by an assignment to a virtual attribute (see pygame.Rect), e.g:

    class Magic(pygame.sprite.Sprite):
        # [...]
    
        def is_collided_with(self, sprite):
            sprite.rec.topleft = sprite.x, sprite.y
            self.rect.topleft = self.x, self.y
            return self.rect.colliderect(sprite.rect)
    

    However, I recommend removing the x and y attributes. Use rect.x and rect.y instead. Set the location of the rectangle, either by a keyword argument:

    class Magic(pygame.sprite.Sprite):
    
        def __init__(self, x, y):
            self.image = pygame.image.load("Magic.png")
            self.rect = self.image.get_rect(topleft = (x, y))
            pygame.sprite.Sprite.__init__(self, spritegroup)
    
        def is_collided_with(self, sprite):
            return self.rect.colliderect(sprite.rect)
    
    class Enemy(pygame.sprite.Sprite):
    
        def __init__(self, x, y):
            self.image = pygame.image.load("Enemy1.png")
            self.rect = self.image.get_rect(topleft = (x, y))
            pygame.sprite.Sprite.__init__(self, spritegroup)
    
        def render(self):
            screen.blit(self.image, self.rect)