Search code examples
pythonpygamerefreshdelay

How can I display both circles without flashing caused by double refresh


The code should display 1 or 2 circles depending on what you ask, and the program asks the user for the frequency of both circles. I'm pretty sure the code works right, but the problem is that when the circles are displayed, 1 of the circles keeps flashing, but I don't know how to adjust it.

I have tried by playing around with it, by moving the update after or before, by updating it 2 times, after or before, anyway i'm stuck and I don't know how I should do it

import pygame
import math
import time
clock = pygame.time.Clock()


pygame.init()
pygame.display.set_caption("circles")
screen = pygame.display.set_mode([1000,700])

width_2 = int(screen.get_width() / 2)
width_3 = int(screen.get_width() / 3)
height_center = int(screen.get_height() / 2 )


black = (0,0,0)
keep_going = True
onecircle = False
twocircles = False
white = (255,255,255)
blue = (0,0,255)
red = (255,0,0)
freq = 0
circle1spot = (0,0)
circle2spot = (0,0)
freq2 = 0
pointradius = 3
num_circles = 0
num_circles2 = 0
radius = 0
radius2 = 0
centerradius = 20
howmanycircles = int(input("How many circles?  \n"))
if howmanycircles == 1:
    onecircle = True
elif howmanycircles == 2:
    twocircles = True
else:
    print("Answer not correct, 1 circle selected by default")
    onecircle = True

if howmanycircles == 1:

    freqinput = int(input("Frequency 1 circle, MIN [1], MAX [148]: \n"))
    freq = 150 - freqinput

elif howmanycircles == 2:

    freqinput = int(input("Frequency 1 circle, MIN [1], MAX [148]: \n"))
    freq = 150 - freqinput

    freqinput2 = int(input("Frequency 2 circle, MIN [1], MAX [148]: \n"))
    freq2 = 150 - freqinput2

def circle1(radius, centerradius):
        radius = radius + 1
        num_circles = math.ceil(radius / freq)
        #screen.fill(white)

        radiusMax = num_circles * freq

        pace = freq / radiusMax


        for y in range(num_circles, 1, -1):

            radiusY = int(((pace * (num_circles - y)) + pace) * radiusMax) + (radius % freq)


            pygame.draw.circle(screen, black, circle1spot, centerradius, 1 )
            pygame.draw.circle(screen, black, circle1spot, radiusY, 1)



        #pygame.display.update() 
        return radius

def circle2(raggio2, centerradius):
        radius2 = radius2 + 1
        num_circles2 = math.ceil(radius2 / freq2)
        #screen.fill(white)

        radiusMax = num_circles2 * freq2

        pace = freq2 / radiusMax


        for y in range(num_circles2, 1, -1):

            radiusY = int(((pace * (num_circles2 - y)) + pace) * radiusMax) + (radius2 % freq2)





            pygame.draw.circle(screen, red, circle2spot, centerradius, 1 )
            pygame.draw.circle(screen, red, circle2spot, radiusY, 1)

        #pygame.display.update() 
        return radius2


while keep_going:

    for event in pygame.event.get():

        if event.type == pygame.QUIT:

            keep_going = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            if pygame.mouse.get_pressed()[0]:
                #mousedownleft = True
                circle1spot = pygame.mouse.get_pos()
                print(circle1spot)


            if pygame.mouse.get_pressed()[2]:
                #mousedownright = True
                circle2spot = pygame.mouse.get_pos()





    pygame.draw.circle(screen, blue, (width_3,height_center), pointradius, 3 )
    pygame.draw.circle(screen, blue, ((width_3*2),height_center), pointradius, 3 )  
    pygame.draw.circle(screen, blue, ((width_2),height_center), pointradius, 3 )    



    if onecircle == True:
        radius = circle1(radius,centerradius)
        pygame.display.update()



    elif twocircles == True:

        radius = circle1(radius,centerradius)   #this is the critical zone
        pygame.display.update()             #this is the critical zone

        radius2 = circle2(radius2, centerradius)    #this is the critical zone
        pygame.display.update()     #this is the critical zone
        screen.fill(white)      #this is the critical zone





pygame.quit()

I'm looking for a possible solution to make it work correctly and to get it refreshed correctly


Solution

  • It is sufficient to do one single pygame.display.update() at the end of the main loop.

    1. clear the display
    2. do all the drawing
    3. update the display
    while keep_going:
    
        # [...]
    
        # 1. clear the display
    
        screen.fill(white) 
    
    
        # 2. do all the drawing
    
        pygame.draw.circle(screen, blue, (width_3,height_center), pointradius, 3 )
        pygame.draw.circle(screen, blue, ((width_3*2),height_center), pointradius, 3 )  
        pygame.draw.circle(screen, blue, ((width_2),height_center), pointradius, 3 )    
    
        if onecircle == True:
            radius = circle1(radius,centerradius)
        elif twocircles == True:
            radius = circle1(radius,centerradius)
            radius2 = circle2(radius2, centerradius) 
    
    
        # 3. update the display
    
        pygame.display.update()