Search code examples
pythonpython-3.xpygame

Why do circles only display when I click but are still affected by physics as soon as the code loads?


I am trying to spawn circles when I click on the screen but the circles only display when I click even though they are being affected as soon as I run the code and it is only grabbing my initial mouse position. I am using pygame, pygame.locals and sys libraries.

code:

pygame.init()

screen = pygame.display.set_mode((1000, 500))
green = (0, 255, 0)

mx, my = pygame.mouse.get_pos()
circle_pos = [mx, my]

circle = False

clock = pygame.time.Clock()
while True:
    screen.fill((15, 15, 15))

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

    if circle == True:
        pygame.draw.circle(screen, green, circle_pos, 5)

    if event.type == pygame.MOUSEBUTTONDOWN:
        circle = True

    circle_pos[1] += 1

    if circle_pos[1] > 495:
        boundaries = circle_pos[1] - 495
        circle_pos[1] -= boundaries

    pygame.display.update()
    clock.tick(120)
    print(clock.get_fps())

pygame.quit()

Solution

  • If you want to draw objects permanently, you must draw them every frame in the application loop.

    You have to add a list for the circle positions:

    circles = []
    

    Add a new position to the list when the mouse button is clicked:

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
    
            if event.type == pygame.MOUSEBUTTONDOWN:
                circles.append(list(event.pos))
    
        # [...]
    

    Draw all the circles in the list in the application loop:

    while True:
        # [...]
    
        screen.fill((15, 15, 15))
    
        for circle_pos in circles:
            pygame.draw.circle(screen, green, circle_pos, 5)
    
        pygame.draw.circle(screen, green, pygame.mouse.get_pos(), 5)
    
        pygame.display.update()
        clock.tick(120)
    

    Complete example:

    import pygame
    pygame.init()
    
    screen = pygame.display.set_mode((1000, 500))
    clock = pygame.time.Clock()
    green = (0, 255, 0)
    circles = []
    
    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    
            if event.type == pygame.MOUSEBUTTONDOWN:
                circles.append(list(event.pos))
    
        screen.fill((15, 15, 15))
        for circle_pos in circles:
            pygame.draw.circle(screen, green, circle_pos, 5)
        pygame.draw.circle(screen, green, pygame.mouse.get_pos(), 5)
        pygame.display.update()
        clock.tick(120)
    
    pygame.quit()
    sys.exit()
    

    Change the positions contained in the list to move the circles:

    import pygame
    pygame.init()
    
    screen = pygame.display.set_mode((1000, 500))
    clock = pygame.time.Clock()
    green = (0, 255, 0)
    circles = []
    
    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
    
            if event.type == pygame.MOUSEBUTTONDOWN:
                circles.append(list(event.pos))
    
        screen.fill((15, 15, 15))
        mouse_pos = pygame.mouse.get_pos()
        for circle_pos in circles:
            dx = mouse_pos[0] - circle_pos[0] 
            dy = mouse_pos[1] - circle_pos[1]
            if abs(dx) > abs(dy):  
                circle_pos[0] += 1 if dx > 0 else -1
            elif dy != 0:
                circle_pos[1] += 1 if dy > 0 else -1
            pygame.draw.circle(screen, green, circle_pos, 5)
        pygame.draw.circle(screen, green, pygame.mouse.get_pos(), 5)
        pygame.display.update()
        clock.tick(120)
    
    pygame.quit()
    sys.exit()