如何在鼠标悬停在精灵上时为其添加边框,并在鼠标悬停后将其删除?

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

我有一个 sprite,我希望它是这样的,当鼠标悬停在它上面时,它会在 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()

如果需要,我可以添加更多代码。 谢谢!

复制图像并在其周围画一个矩形:

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)

检查鼠标是否在 pygame.Rect.collidepoint 和 select 图像上:

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

这一切都在问题 Pygame mouse clicking detection 的答案中进行了解释。

还要注意 pygame.Surface.get_rect.get_rect() returns 一个矩形,其大小与 Surface 对象相同,但它 returns 是一个始终从头开始的矩形在 (0, 0) 因为 Surface 对象没有位置。
Surface 被放置在具有 blit 功能的显示器上的某个位置。

您必须通过关键字参数设置矩形的位置,例如:

self.rect = self.surf.get_rect(topleft = (x, y))

将鼠标位置存储在对象的属性中。 kill 当鼠标悬停在 Sprite 上时 Sprite 并且鼠标位置不会因 som 帧而改变(例如 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

最小示例

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