将形状列表转换为蒙版。

huangapple go评论65阅读模式
英文:

Pygame convert list of shapes to mask

问题

目标是在同一时刻,当一个形状或几个形状经过屏幕时,显示背景中的图像。我的方法是创建一个形状列表(矩形或圆形),然后将所有形状转换为蒙版,然后在每次循环中将屏幕填充为全黑,只显示蒙版。

有没有办法用形状列表创建一个蒙版?我查看了pygame.mask(https://www.pygame.org/docs/ref/mask.html?highlight=mask#module-pygame.mask),但看不到将形状列表转换为蒙版的方法。有什么建议吗?

英文:

The goal is to reveal an image in the background at the same time that a shape or a couple of shapes go through the screen. My approach is to create a list of shapes (rects or circles), then converting al that to a mask and then fill the screen all black but the masks every loop.

Is there a way to make a mask with a list of shapes? I checked pygame.mask (https://www.pygame.org/docs/ref/mask.html?highlight=mask#module-pygame.mask) but cant see a way to convert list of shapes to mask. Any advice?

答案1

得分: 1

你可以做的是为每个形状创建一个"Mask",并创建一个用于填充(覆盖)整个屏幕的"Mask"。

然后,针对以这种方式创建的每个形状遮罩,使用"Mask.draw" 更新屏幕遮罩,类似于这样:

for rect, mask in surfaces:
    screen_mask.draw(mask, rect.topleft)

其中,"surfaces" 是一个包含"Rect" / "Mask" 元组的列表。

然后,您可以使用屏幕遮罩来覆盖屏幕,例如使用"Mask.to_surface",如下所示:

new_background = screen_mask.to_surface(background.copy(), setsurface=background)
screen.blit(new_background, (0, 0))

其中,"background" 是您的原始背景图像,"screen_mask" 是应该覆盖屏幕的遮罩,"new_background" 是您要绘制而不是"background" 的表面。

这里是我拼凑的一个示例,你可以了解一下:

import pygame, math

def main():
    d = 0
    pygame.init()
    screen = pygame.display.set_mode((640, 960))
    img = pygame.image.load('pexels-stijn-dijkstra-16745023.jpg').convert()
    
    triangle = pygame.Surface((32, 32))
    triangle.set_colorkey((0,0,0))
    pygame.draw.lines(triangle, 'red', True, ((0, 0), (32, 0), (16, 32)), 8)
    triangle_rect = triangle.get_frect(center=(400, 100))
    triangle_mask = pygame.mask.from_surface(triangle)

    circle = pygame.Surface((32, 32))
    circle.set_colorkey((0,0,0))
    pygame.draw.circle(circle, 'yellow', (16, 16), 16)
    pygame.draw.circle(circle, 'black', (16, 16), 12)
    circle_rect = circle.get_frect(center=(200, 400))
    circle_mask = pygame.mask.from_surface(circle)
    
    surfaces = (
        (triangle, triangle_rect, triangle_rect, triangle_mask), 
        (circle, circle_rect, circle_rect, circle_mask)
    )

    cloack = pygame.mask.Mask((640, 960))
    clock = pygame.time.Clock()
    while True:
        for e in pygame.event.get():
            if e.type == pygame.QUIT or e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                return

        for surface, rect, base, mask in surfaces:
            cloack.draw(mask, rect.topleft)
            rect.x = base.x + math.sin(0.01 * pygame.time.get_ticks()) * 10
            rect.y += 0.5
            
        back = cloack.to_surface(img.copy(), setsurface=img)
        screen.blit(back, (0, 0))

        for surface, rect, base, mask in surfaces:
            screen.blit(surface, rect)

        pygame.display.flip()
        d = clock.tick(60)
        
main()

希望这能帮助你了解如何使用"Mask"来覆盖屏幕。

英文:

What you can do is to create a Mask for each shape and one Mask to fill (cover) the entire screen.

Then, for each shape mask created this way, update the screen mask with Mask.draw, something like this:

    for rect, mask in surfaces:
screen_mask.draw(mask, rect.topleft)

where surfaces is a list of Rect/Mask tuples.

Then you can use the screen mask to cover the screen, e.g. with Mask.to_surface like this:

new_background = screen_mask.to_surface(background.copy(), setsurface=background)
screen.blit(new_background, (0, 0))

where background is your original background image, screen_mask the mask that should cover the screen and new_background is the surface you draw instead of background.


Here's an example I hacked together; you'll get the idea:

import pygame, math
def main():
d = 0
pygame.init()
screen = pygame.display.set_mode((640, 960))
img = pygame.image.load('pexels-stijn-dijkstra-16745023.jpg').convert()
triangle = pygame.Surface((32, 32))
triangle.set_colorkey((0,0,0))
pygame.draw.lines(triangle, 'red', True, ((0, 0), (32, 0), (16, 32)), 8)
triangle_rect = triangle.get_frect(center=(400, 100))
triangle_mask = pygame.mask.from_surface(triangle)
circle = pygame.Surface((32, 32))
circle.set_colorkey((0,0,0))
pygame.draw.circle(circle, 'yellow', (16, 16), 16)
pygame.draw.circle(circle, 'black', (16, 16), 12)
circle_rect = circle.get_frect(center=(200, 400))
circle_mask = pygame.mask.from_surface(circle)
surfaces = (
(triangle, triangle_rect, triangle_rect, triangle_mask), 
(circle, circle_rect, circle_rect, circle_mask)
)
cloack = pygame.mask.Mask((640, 960))
clock = pygame.time.Clock()
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT or e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
return
for surface, rect, base, mask in surfaces:
cloack.draw(mask, rect.topleft)
rect.x = base.x + math.sin(0.01 * pygame.time.get_ticks()) * 10
rect.y += 0.5
back = cloack.to_surface(img.copy(), setsurface=img)
screen.blit(back, (0, 0))
for surface, rect, base, mask in surfaces:
screen.blit(surface, rect)
pygame.display.flip()
d = clock.tick(60)
main()

将形状列表转换为蒙版。

huangapple
  • 本文由 发表于 2023年6月29日 17:33:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定