首页 > 解决方案 > 在不合并 alpha 的情况下将 Surface 粘贴到另一个 Surface

问题描述

在我正在处理的一个 pygame 项目中,角色和对象的精灵在地形上投下阴影。阴影和地形都是普通的 pygame 表面,所以为了显示它们,阴影被粘贴到地形上。当没有其他阴影(只有一个阴影和地形)时一切正常,但是当角色走进阴影区域时,在投射自己的阴影时,两个阴影结合了它们的 alpha 值,更加模糊了地形。我想要的是避免这种行为,保持 alpha 值稳定。有什么办法吗?

编辑:这是我在 Photoshop 中制作的图像,用于显示问题 在此处输入图像描述

EDIT2:@sloth 的回答还可以,但我忽略了我的项目比这更复杂的评论。阴影不是整个正方形,而是更类似于“模板”。与真实阴影一样,它们是投射对象的轮廓,因此它们需要与颜色键和整个 alpha 值不兼容的每像素 alpha。

这是一个YouTube 视频,更清楚地显示了这个问题。

标签: pythonpython-3.xpygamealphablit

解决方案


解决这个问题的一个简单方法是在另一个Surface具有 alpha 值但没有每像素 alpha 的第一个上涂抹阴影。然后将其粘贴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()

在此处输入图像描述


推荐阅读