当前位置: 首页 > 知识库问答 >
问题:

Pygame-有没有办法只在掩码中进行blit或更新

邵博艺
2023-03-14

在pygame中,是否有任何方法可以在面具内将某些东西blit到屏幕上。例如:如果你有一个遮罩,除了左上角和全黑图像外,所有的位都被设置为1,而不改变图像,你能保持左上角(和遮罩一样)清晰吗?只有更新一个掩码(而不是一个rect)才有助于提高效率。

共有2个答案

微生宝
2023-03-14

所以如果我理解正确的话,问题是——能否使用位掩码进行闪电扫描。答案是“是”和“否”。AFAIK,pygame中不支持1位掩码,这意味着您必须对源曲面使用32 bpp RGBA(SRCALPHA标志)以使用透明度进行blit,在这种情况下,您使用8位掩码=每像素256级的透明度,这在前面的答案中进行了描述。另一个选项是使用“colorkey”闪烁。在这种情况下,它更类似于1位掩码,用于标准24 bpp RGB曲面。您只需设置源曲面中不希望写入目标的颜色。见“表面”。在文档中设置“颜色键”。然而,colorkey方法的问题是,您可能会意外地在源中有一些像素,它们的颜色与colorkey相同,但您仍然希望绘制它们。所以你必须小心。我个人使用RGBA表面进行掩蔽,它更强大,但几乎总是我不需要8位,1位掩蔽就足够了。所以,在我看来,有点奇怪的是,没有对每比特掩码的支持。缓冲区翻转也是如此-您可以仅使用矩形列表来描述屏幕缓冲区中要更新的区域。更灵活、更直接的方法是使用位掩码,但这也是不可能的。也许可以将一个位掩码转换为一个矩形列表,但我没有尝试。第三种选择是不使用pygame的曲面,对数据使用Numpy,然后使用数组blitting:

pygame.surfarray.blit_array(Destination_surface, my_array)

然后你可以自由地用你的数据做任何你想做的事情,但那是另一回事了。

阎鹏
2023-03-14

好的,如果我正确理解了你的问题,诀窍是BLEND\u RGBA\u MULT标志。

我决定亲自测试一下,因为我很好奇。我从这个图像开始:

我用白色做了一个图像,我想让图像显示的地方是白色,我想把它遮住的地方是透明的。我甚至给它不同程度的透明度,看看我是否可以得到模糊掩蔽。

^^^你可能看不到图像,因为它是透明的白色,但它在那里。您只需右键单击并下载即可。

我加载了两个图像,确保使用convert_alpha()

background = pygame.image.load("leaves.png").convert_alpha()
mask = pygame.image.load("mask-fuzzy.png").convert_alpha()

然后为了掩盖图像,我复制了被掩盖的图像,

masked = background.copy()

...我使用BLEND\u RGBA\u MULT将遮罩点到这个副本上,

masked.blit(mask, (0, 0), None, pygame.BLEND_RGBA_MULT)

...我把它画在屏幕上。

display.blit(masked, (0, 0))

果然,它奏效了:

这是我使用的完整代码

import pygame
from pygame.locals import *

pygame.init()
display = pygame.display.set_mode((320, 240))

background = pygame.image.load("leaves.png").convert_alpha()
mask = pygame.image.load("mask-fuzzy.png").convert_alpha()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    # draw
    display.fill(Color(255, 0, 255))
    masked = background.copy()
    masked.blit(mask, (0, 0), None, pygame.BLEND_RGBA_MULT)
    display.blit(masked, (0, 0))
    pygame.display.flip()

如果你想要一个可变的掩码,你可以尝试手动编辑一个Surface并使用它作为你的掩码。

编辑:以下是通过编辑Surface生成掩码的示例:

mask = pygame.Surface((320, 240), pygame.SRCALPHA)
for y in range(0, 240):
    for x in range(0, 320):
        if (x/16 + y/16) % 2 == 0:
            mask.set_at((x, y), Color("white"))

它产生这样的结果:

现在我想在游戏中使用它!

 类似资料:
  • 问题内容: 有没有办法用TypeScript语言进行方法重载? 我想实现以下目标: 这是我不想做的一个例子(我真的很讨厌JS中重载hack的那一部分): 问题答案: 根据规范,TypeScript确实支持方法重载,但是它很笨拙,并且包含许多手动检查参数类型的工作。我认为这主要是因为在纯JavaScript中最接近方法重载的地方还包括检查,并且TypeScript尝试不修改实际的方法主体,以避免任何

  • 我正在将应用程序设置为在play store上上载,但play console显示错误,您需要为APK或Android应用程序包使用不同的版本代码,因为您已经有一个版本代码为1的应用程序包。我试着在Android系统中更改版本代码

  • 我正在为一家酒店开发一个应用程序,使酒店管理层能够报告和查看关注和问题。我正在使用Android和Firebase为这个应用程序。 为了最小化数据下载并优化速度,我正在数据库中添加“活动”和“已解析”节点,如下所示: 现在,酒店希望我添加一个函数来创建一个Excel报告,报告过去一个月内关闭/解决的问题。为此,我将在“resolved”节点上附加一个单值事件侦听器,获取已解决关注点的键,然后为每个

  • 问题内容: 我想根据一个简单的标准更新一组行,并获取已更改的PK列表。我以为我可以做这样的事情,但担心可能出现的并发问题: 如果将其包装在事务中,是否会发生任何并发问题?还是有更好的方法来做到这一点? 问题答案: 考虑查看OUTPUT子句:

  • 我目前正在pygame中开发一款AI v AI游戏,我刚刚完成它,但其中一个功能没有按预期工作。它是这样的(在pygame.event.get()循环中): compute_data函数可能需要0.5秒,但在大约30次pygame窗口停止响应后,在20秒后返回事件循环时,它会显示最终结果。

  • 我已经看到,这在其他类型的对话框窗口中是可能的,如“ShowConfirmDialog”,其中可以指定按钮的数量和它们的名称;但是在使用“ShowInputDialog”时是否可以实现相同的功能?我似乎在API中找不到这种类型的东西。也许我只是错过了,但任何帮助都很感激。