Skip to content
Advertisement

How do I add a border to a sprite when the mouse hovers over it, and delete it after the mouse stops?

I have a sprite, and I want it to be so that when the mouse hovers over it, it places a small border around the sprite, and when it leaves, delete that border. How would I go about doing this?

Sprite Class:

class textureblock(pygame.sprite.Sprite):
  def __init__(self, imagefile):
    super(textureblock, self).__init__()
    self.surf = pygame.image.load(imagefile).convert_alpha()
    self.surf = pygame.transform.scale(self.surf, (48,48))
    self.rect = self.surf.get_rect()
  def die(self):
    self.kill()

I can add more code if required. Thank you!

Advertisement

Answer

Copy the image and draw a rectangle around it:

self.surf = pygame.transform.scale(self.surf, (48,48))
self.hover_surf = self.surf.copy()
pygame.draw.rect(self.hover_surf, (255, 255, 0), self.hover_surf.get_rect(), 6)

Check if the mouse is on the image with pygame.Rect.collidepoint and select the image:

self.hover = self.rect.collidepoint(pygame.mouse.get_pos())
self.image = self.hover_surf if self.hover else self.surf

This all is explained in the answers to the question Pygame mouse clicking detection.

Also note that 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.surf.get_rect(topleft = (x, y))

Store the mouse position in an attribute of the object. kill the Sprite when the mouse hovers over the Sprite and the mouse position does not change for som frames (e.g. 10):

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, filename):
        # [...]

        self.hover = False
        self.mouse_pos = None
self.count = 0

    def update(self):
        # [...]

        mouse_pos = pygame.mouse.get_pos()
        if self.hover and mouse_pos == self.mouse_pos:
            self.count += 1
            if self.count > 10:
              self.kill()
        else:
            self.count = 0
        self.mouse_pos = mouse_pos

Minimal example

import pygame

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, filename):
        super().__init__() 
        self.original_image = pygame.image.load(filename).convert_alpha()
        self.hover_image = self.original_image.copy()
        pygame.draw.rect(self.hover_image, (255, 255, 0), self.hover_image.get_rect(), 6)
        self.image = self.original_image 
        self.rect = self.image.get_rect(center = (x, y))
        self.hover = False
        self.mouse_pos = None
        self.count = 0

    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        self.hover = self.rect.collidepoint(mouse_pos)
        self.image = self.hover_image if self.hover else self.original_image
        if self.hover and mouse_pos == self.mouse_pos:
            self.count += 1
            if self.count > 10:
              self.kill()
        else:
            self.count = 0
        self.mouse_pos = mouse_pos

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

group = pygame.sprite.Group([
    SpriteObject(window.get_width() // 3, window.get_height() // 3, 'Apple.png'),
    SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, 'Banana.png'),
    SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, 'Pear.png'),
    SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, 'Plums.png'),
])

run = True
while run:
    clock.tick(60)
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False 

    group.update()

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement