我怎样才能限制pygame.draw.circle?

时间:2015-04-06 15:11:58

标签: python pygame

我有一个我想绘制的绘图区域和我不想画的边框。目前,如果鼠标位置(m_x& m_y)在边界的圆半径内,我有程序绘制圆,然后重绘矩形,切掉交叉的圆的一部分。必须有一种更智能,更有效的方法来仅绘制边界内的圆形部分。

if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and mouse_pressed[0] == 1:
        if m_x < draw_areax-brush_size and m_y < draw_areay-brush_size:
            circle = pygame.draw.circle(screen,brush_colour,(m_x,m_y),brush_size)
        else:
            circle = pygame.draw.circle(screen,brush_colour,(m_x,m_y),brush_size)
            reloadareas()

2 个答案:

答案 0 :(得分:5)

pygame.draw的文档说:

  

所有绘图功能都与Surface的剪辑区域相关,并且将被约束到该区域。

因此,如果您只想绘制某个矩形区域内的圆的部分,请通过调用pygame.Surface.set_clip设置剪辑区域,绘制圆圈,然后删除剪辑区域。假设您通常没有在屏幕上生效的剪辑区域,那么您可以这样编程:

clip_area = pygame.Rect(0, 0, draw_areax, draw_areay)
screen.set_clip(clip_area)
pygame.draw.circle(...)
screen.set_clip(None) # clear the clip area

以下是一个例子:

from pygame import *
init()
screen = display.set_mode((640, 480))

# Yellow circle drawn without clipping
draw.circle(screen, Color('yellow'), (150, 120), 60)

# Orange circle drawn with clipping
clip = Rect((100, 100, 200, 100))
screen.set_clip(clip)
draw.circle(screen, Color('orange'), (150, 120), 60)
screen.set_clip(None)

# Outline the clip rectangle in black
draw.rect(screen, Color('black'), clip, 1)
display.flip()

如果您使用剪辑矩形进行大量绘制,那么您可能希望使用context manager封装剪裁矩形的设置和取消设置contextlib.contextmanager,也许是这样,使用{{3}}:

from contextlib import contextmanager

@contextmanager
def clipped(surface, clip_rect):
    old_clip_rect = surface.get_clip()
    surface.set_clip(clip_rect)
    try:
        yield
    finally:
        surface.set_clip(old_clip_rect)

然后我的例子就像这样写:

# Orange circle drawn with clipping
clip = Rect((100, 100, 200, 100))
with clipped(screen, clip):
    draw.circle(screen, Color('orange'), (150, 120), 60)

答案 1 :(得分:1)

这里有一些重复的代码。我会将circle =语句移出if / else块,反转if条件,并将reloadareas()放入其中:

if event.type == pygame.MOUSEBUTTONDOWN or pygame.MOUSEMOTION and mouse_pressed[0] == 1:
    circle = pygame.draw.circle(screen,brush_colour,(m_x,m_y),brush_size)

    if m_x > draw_areax-brush_size or m_y > draw_areay-brush_size:
        reloadareas()