如何在 pygame 中制作圆形表面
how to make circular surface in pygame
我需要创建一个有边界圆的表面。在该表面上绘制的任何内容都不应在该边界圆之外可见。我试过使用遮罩、次表面、srcalpha 等,但似乎没有任何效果。
我的尝试:
w = ss.get_width ()
h = ss.get_height ()
TRANSPARENT = (255, 255, 255, 0)
OPAQUE = ( 0, 0, 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, *c, r, 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, *bounds, OPAQUE)
pygame.gfxdraw.filled_ellipse (self.cropped_background, *bounds, *bounds, OPAQUE)
The background is a square image. It should be cropped into the shape of a circle and rendered on screen
您可以使用混合模式 BLEND_RGBA_MIN
实现此目的(参见 pygame.Surface.blit
)。
创建一个与 self.background
大小相同的透明 pygame.Surface
。在 Surface 中间画一个白色圆圈,然后使用混合模式 BLEND_RGBA_MIN
在 Surface 上混合背景。最后你可以 blit 它在屏幕上:
size = self.background.get_size()
self.cropped_background = pygame.Surface(size, pygame.SRCALPHA)
pygame.draw.ellipse(self.cropped_background, (255, 255, 255, 255), (0, 0, *size))
self.cropped_background.blit(self.background, (0, 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, 255) if (x+y) % 2 == 0 else (255, 0, 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, (255, 255, 255, 255), (0, 0, *size))
cropped_background.blit(background, (0, 0), 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, 0))
pygame.display.flip()
另见 How to fill only certain circular parts of the window in pygame?
我需要创建一个有边界圆的表面。在该表面上绘制的任何内容都不应在该边界圆之外可见。我试过使用遮罩、次表面、srcalpha 等,但似乎没有任何效果。
我的尝试:
w = ss.get_width ()
h = ss.get_height ()
TRANSPARENT = (255, 255, 255, 0)
OPAQUE = ( 0, 0, 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, *c, r, 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, *bounds, OPAQUE)
pygame.gfxdraw.filled_ellipse (self.cropped_background, *bounds, *bounds, OPAQUE)
The background is a square image. It should be cropped into the shape of a circle and rendered on screen
您可以使用混合模式 BLEND_RGBA_MIN
实现此目的(参见 pygame.Surface.blit
)。
创建一个与 self.background
大小相同的透明 pygame.Surface
。在 Surface 中间画一个白色圆圈,然后使用混合模式 BLEND_RGBA_MIN
在 Surface 上混合背景。最后你可以 blit 它在屏幕上:
size = self.background.get_size()
self.cropped_background = pygame.Surface(size, pygame.SRCALPHA)
pygame.draw.ellipse(self.cropped_background, (255, 255, 255, 255), (0, 0, *size))
self.cropped_background.blit(self.background, (0, 0), special_flags=pygame.BLEND_RGBA_MIN)
self.ss.fill(BLACK)
self.ss.blit(self.cropped_background, ORIGIN)
最小示例:
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, 255) if (x+y) % 2 == 0 else (255, 0, 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, (255, 255, 255, 255), (0, 0, *size))
cropped_background.blit(background, (0, 0), 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, 0))
pygame.display.flip()
另见 How to fill only certain circular parts of the window in pygame?