Pygame 带圆角的按钮,border_radius 参数不起作用

Pygame Button with rounded Corners, border_radius argument does not work

我目前正在学习pygame。编程圆角矩形时遇到问题

pygame.draw.rect() draw a rectangle rect(surface, color, rect) -> Rect rect(surface, color, rect, width=0, border_radius=0, border_radius=-1, border_top_left_radius=-1, border_top_right_radius=-1, border_bottom_left_radius=-1) -> Rect Draws a rectangle on the given surface.

border_radius (int) -- (optional) used for drawing rectangle with rounded corners. The supported range is [0, min(height, width) / 2], with 0 representing a rectangle without rounded corners.

这是官方pygame文档的描述。

username_rect = pg.rect.Rect(screenwidth/2 - 1/8*screenwidth, screenheight*1/5, 1/4*screenwidth, username_title_render.get_height() + 10)
pg.draw.rect(screen, (0,0,0), username_rect,border_radius = 15)

这里是主要部分。但随后我收到此错误消息:

TypeError: 'border_radius' is an invalid keyword argument for this function

我已经尝试添加一个 "width=2" 参数,但它说参数太多。不幸的是,采用其他数字也无济于事。 我目前正在使用 pygame 版本 2.0.0.dev6(SDL 2.0.10,python 3.8.1)

如果你能帮助我,我将非常高兴,在此先感谢!

该文档适用于 2.0.0.dev7,并根据 this PR, border_radius was added after 2.0.0.dev6, GitHub reference 发布。因此,您正在尝试使用尚未问世的东西。您可以尝试从源代码构建并使用关键字(尽管稳定性不是一个承诺)。或者你可以尝试使用矩形和圆形的组合来达到效果。

我 运行 喜欢这个并且必须自己做,我不妨分享一下。

试试这些,一个绘制带圆角的矩形,另一个绘制带边框的圆角矩形。他们使用消除锯齿的圆圈来绘制角,否则它们看起来会很锯齿:

import pygame.gfxdraw

def draw_rounded_rect(surface, rect, color, corner_radius):
    ''' Draw a rectangle with rounded corners.
    Would prefer this: 
        pygame.draw.rect(surface, color, rect, border_radius=corner_radius)
    but this option is not yet supported in my version of pygame so do it ourselves.

    We use anti-aliased circles to make the corners smoother
    '''
    if rect.width < 2 * corner_radius or rect.height < 2 * corner_radius:
        raise ValueError(f"Both height (rect.height) and width (rect.width) must be > 2 * corner radius ({corner_radius})")

    # need to use anti aliasing circle drawing routines to smooth the corners
    pygame.gfxdraw.aacircle(surface, rect.left+corner_radius, rect.top+corner_radius, corner_radius, color)
    pygame.gfxdraw.aacircle(surface, rect.right-corner_radius-1, rect.top+corner_radius, corner_radius, color)
    pygame.gfxdraw.aacircle(surface, rect.left+corner_radius, rect.bottom-corner_radius-1, corner_radius, color)
    pygame.gfxdraw.aacircle(surface, rect.right-corner_radius-1, rect.bottom-corner_radius-1, corner_radius, color)

    pygame.gfxdraw.filled_circle(surface, rect.left+corner_radius, rect.top+corner_radius, corner_radius, color)
    pygame.gfxdraw.filled_circle(surface, rect.right-corner_radius-1, rect.top+corner_radius, corner_radius, color)
    pygame.gfxdraw.filled_circle(surface, rect.left+corner_radius, rect.bottom-corner_radius-1, corner_radius, color)
    pygame.gfxdraw.filled_circle(surface, rect.right-corner_radius-1, rect.bottom-corner_radius-1, corner_radius, color)

    rect_tmp = pygame.Rect(rect)

    rect_tmp.width -= 2 * corner_radius
    rect_tmp.center = rect.center
    pygame.draw.rect(surface, color, rect_tmp)

    rect_tmp.width = rect.width
    rect_tmp.height -= 2 * corner_radius
    rect_tmp.center = rect.center
    pygame.draw.rect(surface, color, rect_tmp)


def draw_bordered_rounded_rect(surface, rect, color, border_color, corner_radius, border_thickness):
    if corner_radius < 0:
        raise ValueError(f"border radius ({corner_radius}) must be >= 0")

    rect_tmp = pygame.Rect(rect)
    center = rect_tmp.center

    if border_thickness:
        if corner_radius <= 0:
            pygame.draw.rect(surface, border_color, rect_tmp)
        else:
            draw_rounded_rect(surface, rect_tmp, border_color, corner_radius)

        rect_tmp.inflate_ip(-2*border_thickness, -2*border_thickness)
        inner_radius = corner_radius - border_thickness + 1
    else:
        inner_radius = corner_radius

    if inner_radius <= 0:
        pygame.draw.rect(surface, color, rect_tmp)
    else:
        draw_rounded_rect(surface, rect_tmp, color, inner_radius)