python - 将一个表面位 block 传输到另一个表面上而不合并 alpha

标签 python python-3.x pygame alpha blit

在我正在开发的一个 pygame 项目中,角色和物体的 Sprite 将阴影转换到地形上。阴影和地形都是普通的 pygame 表面,因此,为了显示它们,阴影被传输到地形上。当没有其他阴影(只有一个阴影和地形)时,一切都正常,但是当角色走进阴影区域并转换自己的阴影时,两个阴影都会结合它们的 Alpha 值,从而更加模糊地形。 我想要的是避免这种行为,保持 alpha 值稳定。有什么办法可以做到吗?

编辑:这是我在 Photoshop 中制作的图像,用于显示问题 enter image description here

编辑2:@sloth的回答是好的,但我忽略了评论我的项目比这更复杂。阴影不是完整的正方形,而是更类似于"template"。与真实阴影一样,它们是转换对象的轮廓,因此它们需要与 colorkey 和整个 alpha 值不兼容的每像素 alpha。

这是一个YouTube video这更清楚地表明了问题。

最佳答案

解决这个问题的一个简单方法是首先将阴影传输到另一个具有 Alpha 值但没有每个像素 Alpha 的 Surface 上。然后将该 Surface 传输到您的屏幕。

这是一个显示结果的简单示例:

from pygame import *
import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# we create two "shadow" surfaces, a.k.a. black with alpha channel set to something
# we use these to illustrate the problem
shadow = pygame.Surface((128, 128), pygame.SRCALPHA)
shadow.fill((0, 0, 0, 100))
shadow2 = shadow.copy()

# a helper surface we use later for the fixed shadows
shadow_surf = pygame.Surface((800, 600))
# we set a colorkey to easily make this surface transparent
colorkey_color = (2,3,4)
shadow_surf.set_colorkey(colorkey_color)
# the alpha value of our shadow
shadow_surf.set_alpha(100)

# just something to see the shadow effect
test_surface = pygame.Surface((800, 100))
test_surface.fill(pygame.Color('cyan'))

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False

    screen.fill(pygame.Color('white'))

    screen.blit(test_surface, (0, 150))

    # first we blit the alpha channel shadows directly to the screen 
    screen.blit(shadow, (100, 100))
    screen.blit(shadow2, (164, 164))

    # here we draw the shadows to the helper surface first
    # since the helper surface has no per-pixel alpha, the shadows
    # will be fully black, but the alpha value for the full Surface image
    # is set to 100, so we still have transparent shadows
    shadow_surf.fill(colorkey_color)
    shadow_surf.blit(shadow, (100, 100))
    shadow_surf.blit(shadow2, (164, 164))

    screen.blit(shadow_surf, (400, 0))

    pygame.display.update()

enter image description here

关于python - 将一个表面位 block 传输到另一个表面上而不合并 alpha,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52910848/

相关文章:

python - 将 numpy 数组存储在 pandas 数据框的多个单元格中(Python)

Python:如何获取字典中可能的键组合

python - python中大数的浮点除法

android - 在对 Python 的 Android 后端调用中验证 Id token

python - 遇到 "NameError"问题

python - numpy 中的::(双冒号) 是什么,例如 myarray[0::3]?

Python:搜索一对关键字之前和之后的单词

python - 在 Python 中,当 yield cost 超过返回列表时?

python - `time.sleep()` 和 `pygame.time.wait()` 有哪些替代方案?

python - 有没有办法将 pygame.display.update 添加到缩进循环中