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