Draw a transparent rectangle in pygame

前端 未结 5 1474
一向
一向 2020-12-01 01:20

How can I draw a rectangle that has a color with an alpha? I have:

windowSurface = pygame.display.set_mode((1000, 750), pygame.DOUBLEBUF)
pygame.draw.rect(w         


        
相关标签:
5条回答
  • 2020-12-01 01:56

    A way to do this is to instead of drawing a rectangle with pygame, you could create an image of a transparent rectangle by using a drawing program such as paint.net or Fire Alpaca.

    0 讨论(0)
  • 2020-12-01 02:01

    pygame.draw functions will not draw with alpha. The documentation says:

    Most of the arguments accept a color argument that is an RGB triplet. These can also accept an RGBA quadruplet. The alpha value will be written directly into the Surface if it contains pixel alphas, but the draw function will not draw transparently.

    What you can do is create a second surface and then blit it to the screen. Blitting will do alpha blending and color keys. Also, you can specify alpha at the surface level (faster and less memory) or at the pixel level (slower but more precise). You can do either:

    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
    

    or,

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

    Keep in mind in the first case, that anything else you draw to s will get blitted with the alpha value you specify. So if you're using this to draw overlay controls for example, you might be better off using the second alternative.

    Also, consider using pygame.HWSURFACE to create the surface hardware-accelerated.

    Check the Surface docs at the pygame site, especially the intro.

    0 讨论(0)
  • 2020-12-01 02:10

    Unfortunately there is no good way to draw a transparent shape. See pygame.draw module:

    A color's alpha value will be written directly into the surface [...], but the draw function will not draw transparently.

    Hence you need to do a workaround:

    1. Create a pygame.Surface object with a per-pixel alpha format large enough to cover the shape.
    2. Draw the shape on the _Surface.
    3. Blend the Surface with the target Surface. blit() by default blends 2 Surfaces

    For example 3 functions, which can draw transparent rectangles, circles and polygons:

    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)
    

    Minimal example: 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()
    
    0 讨论(0)
  • 2020-12-01 02:14

    the most i can do to help you is to show you how to draw a rectangle that is not filled in. the line for the rectangle is:

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

    the "1" means that it is not filled in

    0 讨论(0)
  • 2020-12-01 02:16

    You can add a fourth value to your color tuple to represent Alpha:

    pygame.draw.rect(windowSurface, (255, 255, 255, 127), pygame.Rect(0, 0, 1000, 750))
    
    0 讨论(0)
提交回复
热议问题