【问题标题】:Draw a transparent rectangles and polygons in pygame在pygame中绘制透明的矩形和多边形
【发布时间】:2021-07-29 03:17:29
【问题描述】:

如何绘制一个带有 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 值似乎不起作用。

【问题讨论】:

  • 您需要添加更多代码,因为上面的行看起来不错。要么是窗口初始化有问题,所以它不支持 alpha,要么你实际上是多次绘制矩形而没有清除屏幕,所以矩形看起来不透明。
  • 你也需要pygame.init吗?
  • 嗯,因为你没有明确指定位深度,你可以试试windowSurface = pygame.display.set_mode((1000, 750), pygame.DOUBLEBUF, 32)。只有 32 位表面支持 Alpha 通道。
  • 你需要添加更多代码。你能把你的主循环贴在你画的地方吗?

标签: python pygame


【解决方案1】:

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

大多数参数都接受一个颜色参数,它是一个 RGB 三元组。这些也可以接受 RGBA 四联体。 alpha值如果包含像素alpha会直接写入Surface,但是draw函数不会透明绘制。

您可以做的是创建第二个表面,然后将其传送到屏幕上。 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 docs,尤其是介绍。

【讨论】:

    【解决方案2】:

    很遗憾,没有绘制透明形状的好方法。见pygame.draw模块:

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

    因此你需要做一个解决方法:

    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()
    

    【讨论】:

      【解决方案3】:

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

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

      “1”表示不填写

      【讨论】:

      • 并没有真正回答这个问题,但帮助我画了一个带边框的透明矩形:D
      【解决方案4】:

      一种方法是不用 pygame 绘制一个矩形,而是使用诸如paint.net 或 Fire Alpaca 之类的绘图程序来创建一个透明矩形的图像。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-26
        • 1970-01-01
        • 2016-03-12
        • 1970-01-01
        • 2021-04-10
        • 2016-05-25
        相关资源
        最近更新 更多