Madison
Madison

Reputation: 747

Why won't pygame draw a circle?

I am a beginner in python, and I'm trying to draw a circle wherever the mouse is(I also have a mouse and background image). Here is my code:

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit

        if event.type == MOUSEBUTTONDOWN:
            color = (100,100,100)
            posx,posy = pygame.mouse.get_pos()
            screen.lock()
            pygame.draw.circle(screen, color, (posx,posy), 50)
            screen.unlock()

    screen.blit(background,(0,0))
    x,y = pygame.mouse.get_pos()
    x -= mousec.get_width()/2
    y -= mousec.get_height()/2

    screen.blit(mousec, (x,y))

    pygame.display.update()

Whenever I click nothing happens. Why doesn't it draw a circle? Thanks for the help!

Upvotes: 2

Views: 7698

Answers (1)

jdi
jdi

Reputation: 92657

I know almost nothing about pygame so I can't be much more help than this... but what I think you are doing is always drawing back over your circle. Try this out:

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

screen.fill((0,0,0))

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        if event.type == MOUSEBUTTONDOWN:
            # draw background first (however)
            screen.fill((0,0,0))

            # draw your other layers (mouse image)

            # draw the circle
            color = (255,255,255)
            posx,posy = pygame.mouse.get_pos()
            pygame.draw.circle(screen, color, (posx,posy), 50)

    pygame.display.update()

Basically what is happening in your example is that when you mouse down event does a draw, you will then draw back over it again with the background. I am not sure what mousec is but that will be drawn over the background every time. So you will never see a circle drawn from your mouse click

My example fills the background once to start, and then when there is a mouse down, it will fill the background again to draw over the previous state, and then draw the circle.

Another approach, using your exact example, is to only record the mouse position when checking the event, and defer the drawing of the circle until after your layers. You would "remember" the last mouse position to constantly redraw that circle on every loop:

last_mouse_pos = None

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit

        if event.type == MOUSEBUTTONDOWN:
            last_mouse_pos = pygame.mouse.get_pos()

        elif event.type == KEYDOWN and event.unicode == 'c':
            # clear the circle when pressing the 'c' key
            last_mouse_pos = None

    screen.blit(background,(0,0))
    x,y = pygame.mouse.get_pos()
    x -= mousec.get_width()/2
    y -= mousec.get_height()/2

    screen.blit(mousec, (x,y))

    if last_mouse_pos:
        color = (100,100,100)
        posx,posy = last_mouse_pos
        pygame.draw.circle(screen, color, (posx,posy), 50)

    pygame.display.update()

The difference in this approach is that you are always drawing everything on each loop as opposed to only in response to changes in events.

Update

In response to your question in the comments... a way to modify that second example to retain all the mouse clicks would be to save them up in a set and draw them back each time.

mouse_clicks = set()

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit

        if event.type == MOUSEBUTTONDOWN:
            mouse_clicks.add(pygame.mouse.get_pos())

        elif event.type == KEYDOWN and event.unicode == 'c':
            # clear the circle when pressing the 'c' key
            mouse_clicks.clear()

    screen.blit(background,(0,0))
    x,y = pygame.mouse.get_pos()
    x -= mousec.get_width()/2
    y -= mousec.get_height()/2

    screen.blit(mousec, (x,y))

    for pos in mouse_clicks:
        color = (100,100,100)
        posx,posy = pos
        pygame.draw.circle(screen, color, (posx,posy), 50)

    pygame.display.update()

Upvotes: 5

Related Questions