关于 pygame.mask 函数的问题

问题描述

所以我阅读了pygame的文档,但我无法清楚地理解它。我最近问了一个关于位图字体的问题,我得到了一些代码作为我的答案;这是代码

import pygame

pygame.init()
win = pygame.display.set_mode((800,600))
font = pygame.font.Font("freesansbold.ttf",32)
i = 0
text = "hello how are you?"
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    letter = text[i]
    text_1 = font.render(letter,True,(255,255,255))

    bw,bh = font.size(letter)
    glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects()
    # print(glyph_rect)
    if glyph_rect:
        gh = glyph_rect[0].height
        print(f'letter {letter}  bitmap height: {bh}  glyph height: {gh}')

    win.fill((0,0))
    win.blit(text_1,(0,0))
    pygame.display.update()

    i += 1
    run = i < len(text)

pygame.quit()

所以,我的问题是在线glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects()

  1. pygame.mask.from_surface() 函数有什么作用?
  2. glyph_rect = pygame.mask.from_surface(text_1).get_bounding_rects() 有什么作用?
  3. 变量 glyph_rect 返回哪些参数,这些参数的含义是什么?

解决方法

pygame.mask.from_surfacepygame.mask.Mask 创建一个 pygame.Surface 对象。
Surface 是位图。 Mask 是一个具有 Boolean 值的二维数组。创建的 Mask 是 _Surface 的大小。如果表面中的相应像素不透明,则字段为 True,如果为透明,则字段为 False

pygame.mask.Mask.get_bounding_rects 创建一个 pygame.Rect 对象列表。每个矩形描述了一个连接像素的边界区域。 如果 Surface 恰好包含 1 个连接的图像,则您将在图像周围获得 1 个矩形。


参见示例。黑色矩形是Surface矩形,红色矩形是连通分量的边界矩形:

repl.it/@Rabbid76/ImageHitbox

import pygame

def getMaskRect(surf,top = 0,left = 0):
    surf_mask = pygame.mask.from_surface(surf)
    rect_list = surf_mask.get_bounding_rects()
    surf_mask_rect = rect_list[0].unionall(rect_list)
    surf_mask_rect.move_ip(top,left)
    return surf_mask_rect

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

try:
    my_image = pygame.image.load('Bomb-256.png')
except:
    my_image = pygame.Surface((200,200),pygame.SRCALPHA)
    pygame.draw.circle(my_image,(0,128,0),(60,60),40)
    pygame.draw.circle(my_image,128),(100,150),40)

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

    pos = window.get_rect().center
    my_image_rect = my_image.get_rect(center = pos)
    my_image_mask_rect = getMaskRect(my_image,*my_image_rect.topleft)

    window.fill((255,255,255))
    window.blit(my_image,my_image_rect)
    pygame.draw.rect(window,my_image_rect,3)
    pygame.draw.rect(window,(255,my_image_mask_rect,3)
    pygame.display.flip()

pygame.quit()
exit()