Python 在不合并alpha的情况下,将一个曲面拼接到另一个曲面上
在我正在进行的pygame项目中,角色和对象的精灵在地形上投射阴影。阴影和地形都是普通的pygame曲面,因此,为了显示它们,阴影会被闪电式地投射到地形上。当没有其他阴影(只有一个阴影和地形)时,一切正常,但当角色进入阴影区域时,在投射自己的阴影时,两个阴影合并其alpha值,使地形更加模糊。 我想要的是避免这种行为,保持alpha值稳定。有什么办法吗 编辑:这是我在Photoshop中制作的一张图片,用来展示这个问题 EDIT2:@sloth的回答是可以的,但我忽略了评论我的项目比这更复杂。阴影不是整个正方形,而是更类似于“模板”。像真实的阴影一样,它们是从中投射的对象的轮廓,因此它们需要与“颜色关键点”和“整个alpha”值不兼容的每像素alphaPython 在不合并alpha的情况下,将一个曲面拼接到另一个曲面上,python,python-3.x,pygame,alpha,blit,Python,Python 3.x,Pygame,Alpha,Blit,在我正在进行的pygame项目中,角色和对象的精灵在地形上投射阴影。阴影和地形都是普通的pygame曲面,因此,为了显示它们,阴影会被闪电式地投射到地形上。当没有其他阴影(只有一个阴影和地形)时,一切正常,但当角色进入阴影区域时,在投射自己的阴影时,两个阴影合并其alpha值,使地形更加模糊。 我想要的是避免这种行为,保持alpha值稳定。有什么办法吗 编辑:这是我在Photoshop中制作的一张图片,用来展示这个问题 EDIT2:@sloth的回答是可以的,但我忽略了评论我的项目比这更复杂。
下面是一个更清楚地显示问题的函数。您可以创建一个函数来测试阴影碰撞,并相应地调整阴影的混合值。解决此问题的简单方法是首先在另一个具有alpha值但没有每像素alpha的
曲面上blit阴影。然后将表面
改为显示在屏幕上
下面是一个简单的示例,显示了结果:
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()
您可以通过将每个像素的alpha阴影点放到辅助曲面上,然后用透明的白色填充该曲面,并将pygame.BLEND_RGBA_MIN
标志作为特殊标志
参数来组合这些阴影。填充颜色的alpha值应等于或低于阴影的alpha值。传递pygame.BLEND_RGBA_MIN
标志意味着对于每个像素,每个颜色通道的较低值将被采用,因此它会将重叠阴影的增加alpha减少为填充颜色alpha
import pygame as pg
pg.init()
screen = pg.display.set_mode((800, 600))
clock = pg.time.Clock()
shadow = pg.image.load('shadow.png').convert_alpha()
# Shadows will be blitted onto this surface.
shadow_surf = pg.Surface((800, 600), pg.SRCALPHA)
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
screen.fill((130, 130, 130))
screen.blit(shadow, (100, 100))
screen.blit(shadow, (154, 154))
shadow_surf.fill((0, 0, 0, 0)) # Clear the shadow_surf each frame.
shadow_surf.blit(shadow, (100, 100))
shadow_surf.blit(shadow, (154, 154))
# Now adjust the alpha values of each pixel by filling the `shadow_surf` with a
# transparent white and passing the pygame.BLEND_RGBA_MIN flag. This will take
# the lower value of each channel, therefore the alpha should be lower than
# the shadow alphas.
shadow_surf.fill((255, 255, 255, 120), special_flags=pg.BLEND_RGBA_MIN)
# Finally, blit the shadow_surf onto the screen.
screen.blit(shadow_surf, (300, 0))
pg.display.update()
clock.tick(60)
这是shadow.png