鼠标运动在不在主表面上的矩形上发生碰撞

Mouse motion collide on a Rect that's not on the main Surface

我正在尝试制作一个库存系统,您可以在其中单击库存中的项目。库存本身是一个单独的表面,当用户单击 'Inven' 按钮时创建和绘制。

我现在库存中有一件样品。我希望当用户将鼠标悬停在项目上时呈现和绘制文本。

我正在通过检查 mousemotion 事件来解决这个问题,然后查看事件位置是否与库存项目 rect 发生碰撞。

这行得通...但是生成的文本是在矩形的位置绘制的,如果它在主表面上,而不是较小的库存特定表面上。我发现当将坐标传递给我只想在库存表面上绘制的项目时,坐标必须相对于它们正在使用的表面。

例如:在库存表面 (0,0) 处的 Bliting 库存项目将其放置在库存表面的左上角,而不是主表面。所以我没有传递项目相对于整个游戏的实际坐标。

但是当我检查与鼠标的碰撞时,它确实使用了库存项目相对于整个游戏的坐标。不只是主表面。

我想我必须找到物品相对于整个游戏的实际坐标,但考虑到 Pygame 能够理解物品相对于绘制表面的坐标,这似乎很奇怪.

有没有办法在代码中获取未绘制在主表面上的项目相对于主表面的坐标?或者有没有一种方法可以检查仅相对于特定表面的鼠标运动碰撞?

相关代码如下。

class Game:
    """Game settings and options"""
    def __init__(self, gameTitle):
        self.width = 800
        self.height = 600
        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode((self.width, self.height)) # main surface
        self.fps = 60
        pygame.display.set_caption(gameTitle)
        self.statusTextTimer = -1
        self.textBlurbShowing = False # the 'blurb' is the text to be shown on hover
        self.textBlurbTimer = -1
        self.textBlurb = None
# creates text on hover
def hoverText(text, pos):
    gameMaster.textBlurbShowing = True
    gameMaster.textBlurbTimer = 0
    gameMaster.textBlurb = gameMaster.Text(12, gameMaster)
    gameMaster.textBlurb.create(text, 'Black', pos[0], pos[1])
        if event.type == MOUSEMOTION and gameMaster.textBlurbShowing == False and inventoryClicked:
            
            for item in player.inventory.contents:
                if item.rect.collidepoint((event.pos)):
                    print('Collided') # was making sure event was registering
                    hoverText(item.desc, (event.pos[0], event.pos[1]))
class Inventory:
    def __init__(self, posx, posy, size):
        self.posx = posx
        self.posy = posy
        self.size = size
        self.surf = pygame.Surface((size,size), pygame.SRCALPHA)
        self.rect = self.surf.get_rect(x=posx, y=posy)
        self.textSurf = pygame.font.SysFont('Lucidia Console', 22).render('Inventory', True, 'White')
        self.textRect = self.textSurf.get_rect()
        self.textRect.x = self.textRect.x + 10
        self.textRect.y = self.textRect.y + 10
        self.slotCoords = {
            1:(0,100), 2:(100,100), 3:(200,100), 4:(300,100),
            5:(0,200), 6:(100,200), 7:(200,200), 8:(300,200),
            9:(0,300), 10:(100,300), 11:(200,300), 12:(300,300),} # inv slot : (x,y) all slots must be 100x100 
# ^^^ these are the coordinates each inventory slot uses, they're passed to an item in the slot for drawing.
# Checking collisions uses these coordinates relative to the main surface, but when drawing, it works with the inventory surface.
        self.contents = []

感谢任何帮助。

Is there a way in code to get the coordinates of an item relative to the main surface, that is not being drawn on the main surface?

你必须知道物品的目的地表面的位置。

让我们假设,在 pygame.Surface dest_surf:

上的位置 (item_x, item_y) 绘制一个 item_image
item_rect = item_image.get_rect(topleft = (item_x, item_y))
dest_surf.blit(item_image, item_rect)

稍后你 blitscreen 上的 dest_surf at (dest_x, dest_y):

screen.blit(dest_surf, (dest_x, dest_y))

item_image在屏幕上的边界矩形可以通过将(dest_x, dest_y)添加到item_rect的位置来计算:

screen_item_rect = item_rect.copy()
screen_item_rect.x += dest_x
screen_item_rect.y += dest_y

这可以通过使用gyame.Rect.move来简化:

screen_item_rect = item_rect.move(dest_x, dest_y)