如何在图片上使用 Pygame 的 set_alpha() 方法

7

我正在使用pygame和python构建一个项目,为游戏的初始界面创建了一个闪屏。我有一张.png图片要用于闪屏,并决定从黑色渐变到透明来实现。我发现最好的方法是通过设置alpha值来blit图像。我编写了以下代码,但它运行非常缓慢(程序会挂起30秒),并且没有显示出alpha值,只在屏幕上显示了图片。我做错了什么?

screen = pygame.display.set_mode([1066,600])

#Drawable surface
background = pygame.Surface(screen.get_size())

#Used for converting color maps
background = background.convert()

#Splashscreen

#image fades in
for i in range (225):
    background.fill((0,0,0))
    image = pygame.image.load("logo.png")
    image.set_alpha(i)
    logoimage = screen.blit(image,(0,0))
    pygame.display.flip()

pygame.time.delay(2000)

#image fades out

#goes on to display main menu
3个回答

11

除了monkey提到的问题外,您可能会遇到另一个问题,那就是您可能需要使用surface.convert()将图像转换为可以更改alpha的形式。您可以执行以下任一操作。

image = pygame.image.load("logo.png")
image = image.convert()
或者
image = pygame.image.load("logo.png").convert()

我发现,虽然surface.convert_alpha()应该做的差不多,但它通常不起作用。尝试使用以下测试代码进行检查。

import pygame, sys
pygame.init()
window=pygame.display.set_mode((1500, 800))
background=pygame.Surface((window.get_rect().width, window.get_rect().height))
background.fill((0, 0, 0))
image=pygame.image.load('InsertImageHere.png')
image=image.convert()
image2=pygame.image.load('InsertImage2Here.png')
image2=image2.convert_alpha()
rect=image.get_rect()
rect2=image2.get_rect()
rect2.left=rect.width+1
i=1
while True:
    for event in pygame.event.get():
        if event.type==12:
            pygame.quit()
            sys.exit()
    image.set_alpha(i)
    image2.set_alpha(i)
    window.fill((255, 255, 255))
    window.blit(background, background.get_rect())
    window.blit(image, rect)
    window.blit(image2, rect2)
    pygame.time.delay(20)
    i+=1
    if i==255:
        i=1
    pygame.display.update()
在我的测试中,图像1可以正常淡入,但是图像2始终很暗。你应该自己尝试一下;你的电脑可能会有所不同。
如果surface.convert_alpha() 对你有用,你应该使用它,否则按照我之前说的做。这应该可以解决你的问题。
你还应该注意,我使用了pygame.time.delay(20)而不是之前的2000。如果你每次增加透明度1,那么2000会太长了。

是的,.convert() 解决了问题,感谢所有的帮助!我还不太理解 .convert() 的作用,所以现在我会去学习一下它的相关知识! - Ben Schwabe
convert_alpha()函数将图像转换为每像素alpha格式,因此set_alpha()方法无法使用。如果要使用set_alpha()方法,则必须使用没有每像素alpha的图像。请改用colorkey(颜色键)代替。 - ndvo

5

[1] 您不希望在每次迭代中都加载图像,因为创建新表面是一个缓慢的操作。[2] 你的循环会绘制225次,然后在最后一次迭代后等待2000毫秒。

你想要:

image = pygame.image.load("logo.png")

for i in range (225):
    background.fill((0,0,0))    
    image.set_alpha(i)
    screen.blit(image,(0,0))
    pygame.display.flip()
    pygame.time.delay(20)

要实现淡入淡出效果,需要在播放器点击/按下按钮之前不断循环。代码如下:

import pygame
from pygame.locals import *

# ...

def title_loop():
    # title screen main loop    
    image = pygame.image.load("logo.png")
    done = False
    alpha = 0
    alpha_vel = 1

    # fade alpha in-out while waiting    
    while not done:        
        # get key input
        for event in pygame.event.get():
            if event.type == QUIT:
                done = true
            if event.type == KEYDOWN:
                if event.key = K_ESCAPE:
                    done = true

        # draw
        if alpha >= 255 or alpha <= 0:
            alpha_vel *= -1
        alpha += alpha_vel

        background.fill((0,0,0))
        image.set_alpha(i)
        screen.blit(image,(0,0))
        pygame.display.flip()

        pygame.time.delay(20)

我尝试了你建议的方法,它可以正常工作,但是由于某种原因,图像仍然完全不透明。如果我在它上面使用 get_alpha(),那么它会告诉我应该有的正确 alpha 值,但是图像并没有以该 alpha 值显示。这可能是一个 bug 吗? - Ben Schwabe
哦,当图像具有每像素透明度时,set_alpha值将被忽略。在 image = pygame.image.load("logo.png") 之后添加 image.set_alpha(None),我认为这将禁用每像素透明度,使其读取您的值。编辑:或尝试 pygameNerd 的帖子以删除每像素透明度。 - ninMonkey

2

PygameNerd您的例子很接近,但实际上并不能正常工作。

image.convert()可以正确地淡化图像,但不支持alpha通道。在非黑色背景下尝试,会出现问题。 image.convert_alpha() 不会淡化,但alpha通道可以正常工作。

我很惊讶pygame没有直接支持这个,但无论如何。以下是一个答案: http://www.nerdparadise.com/tech/python/pygame/blitopacity/

它有点复杂,但可以很好地工作。透明背景和淡入淡出都打包在一起。


非常感谢!我已经找了很久类似这样有用的教程了。 - Ben Schwabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接