在pygame中绘制透明矩形和多边形

问题描述 投票:0回答:4

如何绘制一个带有 alpha 颜色的矩形?
我有:

windowSurface = pygame.display.set_mode((1000, 750), pygame.DOUBLEBUF)
pygame.draw.rect(windowSurface, pygame.Color(255, 255, 255, 128), pygame.Rect(0, 0, 1000, 750))

但我希望白色矩形的透明度为 50%,但 alpha 值似乎不起作用。

python pygame
4个回答
93
投票

pygame.draw
函数不会使用 alpha 进行绘制。文档说:

大多数参数接受 RGB 三元组的颜色参数。它们还可以接受 RGBA 四元组。如果 Surface 包含像素 alpha,则 alpha 值将直接写入 Surface,但绘制函数不会透明绘制。

您可以做的是创建第二个表面,然后将其传输到屏幕。 Blitting 将进行 Alpha 混合和颜色键。此外,您还可以在表面级别(更快且占用更少的内存)或像素级别(更慢但更精确)指定 alpha。您可以执行以下任一操作:

s = pygame.Surface((1000,750))  # the size of your rect
s.set_alpha(128)                # alpha level
s.fill((255,255,255))           # this fills the entire surface
windowSurface.blit(s, (0,0))    # (0,0) are the top-left coordinates

或者,

s = pygame.Surface((1000,750), pygame.SRCALPHA)   # per-pixel alpha
s.fill((255,255,255,128))                         # notice the alpha value in the color
windowSurface.blit(s, (0,0))

请记住,在第一种情况下,您绘制到

s
的任何其他内容都将使用您指定的 alpha 值进行位块传输。因此,如果您使用它来绘制覆盖控件,那么您最好使用第二种选择。

另外,考虑使用 pygame.HWSURFACE 创建硬件加速的表面。

查看 pygame 站点上的 Surface 文档,尤其是简介。


21
投票

不幸的是没有好的方法来绘制透明形状。请参阅 pygame.draw 模块:

颜色的 alpha 值将直接写入表面 [...],但绘制函数不会透明绘制。

所以你不能直接使用“pygame.draw”模块绘制透明形状。 “pygame.draw”模块不会将形状与目标表面混合。您必须在表面上绘制形状(使用 RGBA 格式)。然后你可以

blit
(从而混合)这个表面。请参阅在 pygame 中绘制透明矩形和多边形。因此,您需要采取解决方法:

  1. 创建一个
    pygame.Surface
    对象,其每像素 Alpha 格式足够大以覆盖形状。
  2. 在_Surface 上绘制形状。
  3. Surface与目标Surface混合。
    blit()
    默认混合 2 曲面

例如3个函数,可以绘制透明的矩形、圆形和多边形:

def draw_rect_alpha(surface, color, rect):
    shape_surf = pygame.Surface(pygame.Rect(rect).size, pygame.SRCALPHA)
    pygame.draw.rect(shape_surf, color, shape_surf.get_rect())
    surface.blit(shape_surf, rect)
def draw_circle_alpha(surface, color, center, radius):
    target_rect = pygame.Rect(center, (0, 0)).inflate((radius * 2, radius * 2))
    shape_surf = pygame.Surface(target_rect.size, pygame.SRCALPHA)
    pygame.draw.circle(shape_surf, color, (radius, radius), radius)
    surface.blit(shape_surf, target_rect)
def draw_polygon_alpha(surface, color, points):
    lx, ly = zip(*points)
    min_x, min_y, max_x, max_y = min(lx), min(ly), max(lx), max(ly)
    target_rect = pygame.Rect(min_x, min_y, max_x - min_x, max_y - min_y)
    shape_surf = pygame.Surface(target_rect.size, pygame.SRCALPHA)
    pygame.draw.polygon(shape_surf, color, [(x - min_x, y - min_y) for x, y in points])
    surface.blit(shape_surf, target_rect)

最小示例: repl.it/@Rabbid76/PyGame-TransparentShapes

import pygame

def draw_rect_alpha(surface, color, rect):
    shape_surf = pygame.Surface(pygame.Rect(rect).size, pygame.SRCALPHA)
    pygame.draw.rect(shape_surf, color, shape_surf.get_rect())
    surface.blit(shape_surf, rect)

def draw_circle_alpha(surface, color, center, radius):
    target_rect = pygame.Rect(center, (0, 0)).inflate((radius * 2, radius * 2))
    shape_surf = pygame.Surface(target_rect.size, pygame.SRCALPHA)
    pygame.draw.circle(shape_surf, color, (radius, radius), radius)
    surface.blit(shape_surf, target_rect)

def draw_polygon_alpha(surface, color, points):
    lx, ly = zip(*points)
    min_x, min_y, max_x, max_y = min(lx), min(ly), max(lx), max(ly)
    target_rect = pygame.Rect(min_x, min_y, max_x - min_x, max_y - min_y)
    shape_surf = pygame.Surface(target_rect.size, pygame.SRCALPHA)
    pygame.draw.polygon(shape_surf, color, [(x - min_x, y - min_y) for x, y in points])
    surface.blit(shape_surf, target_rect)

pygame.init()
window = pygame.display.set_mode((250, 250))
clock = pygame.time.Clock()

background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *window.get_size(), (160, 160, 160), (192, 192, 192)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect, color in tiles:
    pygame.draw.rect(background, color, rect)

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

    window.blit(background, (0, 0))

    draw_rect_alpha(window, (0, 0, 255, 127), (55, 90, 140, 140))
    draw_circle_alpha(window, (255, 0, 0, 127), (150, 100), 80)
    draw_polygon_alpha(window, (255, 255, 0, 127), 
        [(100, 10), (100 + 0.8660 * 90, 145), (100 - 0.8660 * 90, 145)])

    pygame.display.flip()

pygame.quit()
exit()

2
投票

我能做的最多就是向你展示如何绘制一个未填充的矩形。 矩形的线是:

pygame.draw.rect(surface, [255, 0, 0], [50, 50, 90, 180], 1)

“1”表示未填写


0
投票

实现此目的的一种方法是,您可以使用 Paint.net 或 Fire Alpaca 等绘图程序创建透明矩形的图像,而不是使用 pygame 绘制矩形。

© www.soinside.com 2019 - 2024. All rights reserved.