首页 > 解决方案 > 为什么 Alpha 混合无法正常工作?

问题描述

我正在尝试制作一个简单的 Pygame 应用程序,其中一些颜色与它们下面的颜色混合。这是我的代码:

代码清单1:

import pygame, sys, time
from pygame.locals import *

#define constants
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 600
FPS = 60
    
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), 0, 32)
    
alpha = 0
increasing = True
    
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    #fill screen with red
    screen.fill(pygame.Color(247, 25, 0,255))
    alpha_surface = pygame.Surface((screen.get_rect().width, screen.get_rect().height))
    alpha_surface = alpha_surface.convert_alpha()
    surfaceRect = alpha_surface.get_rect()

    #fill surface with orange
    pygame.draw.rect(alpha_surface, (247, 137, 0, 255), (0, 0, 480, 480))
    #fill surface with translucent yellow
    pygame.draw.rect(alpha_surface, (220, 247, 0, alpha), (120, 120, 360, 360))
    #fill surface with green
    pygame.draw.rect(alpha_surface, (0, 247, 4), (240, 240, 240, 240))
    #fill surface with translucent blue
    pygame.draw.rect(alpha_surface, (0, 78, 247, alpha), (360, 360, 120, 120))
    screen.blit(alpha_surface, (120,120))
    
    pygame.display.update()
    clock.tick(FPS)

    if increasing:
        alpha += 1
        if alpha > 255:
            alpha = 255
            increasing = False
    else:
        alpha -= 1
        if alpha < 0:
            alpha = 0
            increasing = True

该代码应该使黄色矩形与橙色矩形混合,蓝色矩形与绿色矩形混合。相反,我从中得到了一些东西:

图 1:黄色和蓝色不透明度设置为 0% 的原始状态

对此:

图 2:黄色和蓝色不透明度设置为 100% 的最终状态

正如你所看到的,黄色和蓝色矩形不仅与红色矩形(屏幕表面)融合在一起,而且还在橙色和绿色矩形上打了一个洞,这样我们就可以通过它们看到红色矩形。

标签: pythonpygameblending

解决方案


如果要混合不同的图层,则必须创建不同pygame.Surface的 s 或图像。可以通过加载图像 ( pygame.image) 或构造pygame.Surface对象来生成 Surface。

使用每像素 alpha创建一个完全透明的表面。用于pygame.Surface.convert_alpha更改图像的像素格式,包括每个像素的 alpha。用透明颜色填充Surfacepygame.Color(0, 0, 0, 0) (例如):


最小的例子:

import pygame

pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((600, 600), 0, 32)

def transparentSurface(size):
    surface = pygame.Surface(size).convert_alpha()
    surface.fill((0, 0, 0, 0))
    return surface

alpha, increase = 0, 1
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    screen.fill(pygame.Color(247, 25, 0,255))
    
    alpha_surface1 = transparentSurface(screen.get_size())
    pygame.draw.rect(alpha_surface1, (247, 137, 0, 255), (120, 120, 480, 480))

    alpha_surface2 =  transparentSurface(screen.get_size())
    pygame.draw.rect(alpha_surface2, (220, 247, 0, alpha), (240, 240, 360, 360))

    alpha_surface3 =  transparentSurface(screen.get_size())
    pygame.draw.rect(alpha_surface3, (0, 247, 4), (360, 360, 240, 240) )

    alpha_surface4 =  transparentSurface(screen.get_size())
    pygame.draw.rect(alpha_surface4, (0, 78, 247, alpha), (480, 480, 120, 120) )
    
    screen.blit(alpha_surface1, (0,0))
    screen.blit(alpha_surface2, (0,0))
    screen.blit(alpha_surface3, (0,0))
    screen.blit(alpha_surface4, (0,0))

    pygame.display.update()
    
    alpha += increase
    if alpha < 0 or alpha > 255:
        increase *= -1
        alpha = max(0, min(255, alpha))

pygame.quit()

推荐阅读