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