在我正在从事的pygame项目中,角色和对象的精灵将阴影投射到地形上。阴影和地形都是正常的pygame曲面,因此,为了显示它们,阴影被涂抹到了地形上。当没有其他阴影(只有一个阴影和地形)时,一切正常,但是当角色进入阴影区域时,在投射自己的阴影时,两个阴影会组合其alpha值,从而使地形更加模糊。 我想要的是避免这种行为,保持alpha值稳定。有什么办法吗?
EDIT2:@sloth的答案是可以的,但我忽略了评论我的项目比这更复杂。阴影不是整个正方形,而是更类似于“模具”。像真实的阴影一样,它们是从其投射对象的轮廓,因此它们需要每个像素的Alpha,这些Alpha与ColorKey和整个Alpha值不兼容。
这里是YouTube video,可以更清楚地显示问题。
答案 0 :(得分:2)
解决此问题的一种简单方法是先将阴影阴影在另一个具有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()
答案 1 :(得分:0)
您可以创建一个测试阴影碰撞的函数,并相应地调整阴影的混合值。
答案 2 :(得分:0)
您可以通过将每个像素的alpha阴影涂抹到辅助表面上,然后用透明的白色填充此表面并传递pygame.BLEND_RGBA_MIN
标志作为special_flags
参数来组合它们。填充颜色的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。