如何在Pygame中制作圆形表面

问题描述

我需要创建一个具有边界圆的曲面。在该表面上绘制的任何内容在该边界圆之外都不应该可见。我已经尝试过使用遮罩,地下,srcalpha等,但似乎无济于事。

我的尝试:

w = ss.get_width  ()
h = ss.get_height ()    
    
TRANSPARENT = (255,255,0)
OPAQUE      = (  0,225)
    
crop = pygame.Surface ((w,h),pygame.SRCALPHA,ss)
crop.fill (TRANSPARENT)
    
c = round (w / 2),round (h / 2)
r = 1
pygame.gfxdraw.     aacircle (crop,*c,r,OPAQUE)
pygame.gfxdraw.filled_circle (crop,OPAQUE)
    
ss = crop.subsurface (crop.get_rect ())
App.set_subsurface (self,ss)

稍后...

self.ss.fill (BLACK)
self.ss.blit (self.background,ORIGIN)

背景是正方形图像。应该将其裁剪为圆形并在屏幕上呈现

基于Rabbid76的注释的解决方案:

def draw_scene (self,temp=None):
        if temp is None: temp = self.ss
        # 1. Draw everything on a surface with the same size as the window (background and scene).
        size = temp.get_size ()
        temp = pygame.Surface (size)
        self.draw_cropped_scene (temp)

        # 2. create the surface with the white circle.      
        self.cropped_background = pygame.Surface (size,pygame.SRCALPHA)
        self.crop ()

        # 3. blit the former surface on the white circle.
        self.cropped_background.blit (temp,ORIGIN,special_flags=pygame.BLEND_RGBA_MIN)
    
        # 4. blit the whole thing on the window.
        self.ss.blit (self.cropped_background,ORIGIN)

    def draw_cropped_scene (self,temp): App.draw_scene (self,temp)    

crop()的示例实现为:

def crop (self):
        o,bounds = self.bounds
        bounds = tr (bounds) # round elements of tuple
        pygame.gfxdraw.     aaellipse (self.cropped_background,*bounds,OPAQUE)
        pygame.gfxdraw.filled_ellipse (self.cropped_background,OPAQUE)

解决方法

背景是正方形图像。应该将其裁剪为圆形并在屏幕上呈现

您可以通过使用混合模式BLEND_RGBA_MIN(请参见pygame.Surface.blit)来实现此目的。

创建一个透明的pygame.Surface,其大小与self.background相同。在表面的中间绘制一个白色圆圈,并使用混合模式BLEND_RGBA_MIN在此表面上混合背景。最后,您可以在屏幕上 blit

size = self.background.get_size()
self.cropped_background = pygame.Surface(size,pygame.SRCALPHA)
pygame.draw.ellipse(self.cropped_background,(255,255,255),(0,*size))
self.cropped_background.blit(self.background,0),special_flags=pygame.BLEND_RGBA_MIN)
self.ss.fill(BLACK)
self.ss.blit(self.cropped_background,ORIGIN)

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

import pygame
pygame.init()
window = pygame.display.set_mode((250,250))

background = pygame.Surface(window.get_size())
for x in range(5):
    for y in range(5):
        color = (255,255) if (x+y) % 2 == 0 else (255,0)
        pygame.draw.rect(background,color,(x*50,y*50,50,50))

size = background.get_size()
cropped_background = pygame.Surface(size,pygame.SRCALPHA)
pygame.draw.ellipse(cropped_background,*size))
cropped_background.blit(background,special_flags=pygame.BLEND_RGBA_MIN)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        
    window.fill(0)
    window.blit(cropped_background,0))
    pygame.display.flip()

另请参见How to fill only certain circular parts of the window in pygame?