【问题标题】:Setting a pygame surface to have rounded corners将 pygame 表面设置为圆角
【发布时间】:2020-09-02 06:55:51
【问题描述】:

这个 Rectangle 类从 pygame.sprite 扩展而来。我想使用set_rounded 来修改矩形角的圆度。例如https://imgur.com/2N5NHlg

class Rectangle(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.original_image = pg.Surface((10, 10))
        self.image = self.original_image
        self.rect = self.image.get_rect()


    def set_rounded(self, roundness):
        pass

roundness 参数将确定圆角矩形的半径。

【问题讨论】:

  • 问题解决了吗?
  • 我请求编辑,因为矩形的宽度使用了错误的索引。另一个问题是圆角矩形的背景是黑色的,不透明。这可以通过改变背景的颜色来看到。
  • @Rabbid76 似乎仍然存在 self.rect_image 表面的问题,由于某种原因仍在 rect 后面显示。将窗口背景更改为 window.fill((0, 150, 0))。我一直无法找到解决方案。我尝试设置 alpha,更改其可见性,但它仍然存在。
  • 你是对的,我的答案有一个错误(初学者错误)。我已经更正了答案:self.image = self.original_image.copy().convert_alpha()

标签: python pygame sprite blending


【解决方案1】:

你可以通过设置函数pygame.draw.rect的关键字参数border_radius来达到你想要的效果。

创建一个与图像大小相同且具有每个像素 alpha (SRCALPHA) 的矩形,并绘制一个带有圆角的完全白色、不透明的图像:

size = self.original_image.get_size()
self.rect_image = pg.Surface(size, pg.SRCALPHA)
pg.draw.rect(self.rect_image, (255, 255, 255), (0, 0, *size), border_radius=roundness)

复制原图并使用BLEND_RGBA_MIN混合模式将矩形与图像混合(见pygame.Surface.blit):

self.image = self.original_image.copy().convert_alpha()
self.image.blit(self.rect_image, (0, 0), None, pg.BLEND_RGBA_MIN) 

注意,关键字属性border_radius 是一个新特性。您必须使用最新的 pygame 版本 (2.0.0.dev10)。

如果您不能使用 2.0.0.dev10 版本,则需要自己将圆角矩形粘贴在一起:

class Rectangle(pg.sprite.Sprite):
    # [...]

    def set_rounded(self, roundness):
        size = self.original_image.get_size()
        self.rect_image = pg.Surface(size, pg.SRCALPHA)
        
        #pg.draw.rect(self.rect_image, (255, 255, 255), (0, 0, *size), border_radius=roundness)

        r, c = roundness, (255, 255, 255)
        pg.draw.rect(self.rect_image, c, (r, 0, size[0]-2*r, size[1]))
        pg.draw.rect(self.rect_image, c, (0, r, size[0], size[1]-2*r))
        for cpt in [(r, r), (size[0]-r, r), (r, size[1]-r), (size[0]-r, size[1]-r)]:  
            pg.draw.circle(self.rect_image, c, cpt, r)

        self.image = self.original_image.copy().convert_alpha()
        self.image.blit(self.rect_image, (0, 0), None, pg.BLEND_RGBA_MIN) 

看例子:

import pygame as pg

class Rectangle(pg.sprite.Sprite):
    def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.original_image = pg.Surface((100, 100))
        self.original_image.fill((255, 0, 0))
        self.image = self.original_image
        self.rect = self.image.get_rect()

    def set_rounded(self, roundness):
        size = self.original_image.get_size()
        self.rect_image = pg.Surface(size, pg.SRCALPHA)
        pg.draw.rect(self.rect_image, (255, 255, 255), (0, 0, *size), border_radius=roundness)

        self.image = self.original_image.copy().convert_alpha()
        self.image.blit(self.rect_image, (0, 0), None, pg.BLEND_RGBA_MIN) 

pg.init()
window = pg.display.set_mode((200, 200))

rect_object = Rectangle()
rect_object.set_rounded(30)
rect_object.rect.center = window.get_rect().center
group = pg.sprite.Group(rect_object)

run = True
while run:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            run = False

    window.fill((128, 128, 128))
    group.draw(window)
    pg.display.flip()

【讨论】:

  • 这个项目必须兼容pygame 1.9.6+。有没有办法在不使用border_radius的情况下实现这一点?
  • @Hydra 我已经扩展了答案。
猜你喜欢
  • 1970-01-01
  • 2011-11-17
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 2020-11-29
相关资源
最近更新 更多