Object lagging/teleporting in simple pygame stimulation

Viewed 57

I am trying to create a simple program that stimulates the revolution of stars in a binary system, but when I run the program, one of the 'stars' glitches around, practically teleporting around the given path to different locations. How can I fix this? Here is the code:

import pygame, sys, math, keyboard

run = True
black = (255, 255, 255)
white = (0, 0, 0)
angle = 0
size = width, height = 1550, 800
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
screen.fill(black)

while run:
    msElapsed = clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    def star1():
        global angle
        screen.fill(white)
        x = int(math.cos(angle) * 70) + 775
        y = int(math.sin(angle) * 100) + 400
        pygame.draw.circle(screen, black, (x, y), 10)
        pygame.display.flip()
        angle += 0.05


    def star2():
        global angle
        screen.fill(white)
        x = int(math.cos(angle) * 100) + 775
        y = int(math.sin(angle) * 70) + 400
        pygame.draw.circle(screen, black, (x, y), 10)
        pygame.display.flip()
        angle += 0.05

    star1()
    star2()

    if keyboard.is_pressed('Esc'):
        print("System Terminated ('ESC')")
        sys.exit(0)

pygame.quit()
1 Answers

The problem is caused by screen.fill(white) and the multiple calls to pygame.display.flip(). The fill() function fills the entire Surface with a solid color. Call fill once at the begin of the application loop. An update of the display at the end of the application loop is sufficient. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering.

Remove all calls to pygame.display.flip() from your code, but call it once at the end of the application loop.

You don't need the keboard package at all. Use the pygame.key.get_pressed() instead.

while run:
    msElapsed = clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    def star1():
        global angle
        # screen.fill(white)                           <--- DELTE
        x = int(math.cos(angle) * 70) + 775
        y = int(math.sin(angle) * 100) + 400
        pygame.draw.circle(screen, black, (x, y), 10)
        # pygame.display.flip()                        <--- DELTE
        angle += 0.05

    def star2():
        global angle
        # screen.fill(white)                           <--- DELTE
        x = int(math.cos(angle) * 100) + 775
        y = int(math.sin(angle) * 70) + 400
        pygame.draw.circle(screen, black, (x, y), 10)
        # pygame.display.flip()                        <--- DELTE
        angle += 0.05

    screen.fill(white)                               # <--- ADD
    star1()
    star2()
    pygame.display.flip()                            # <--- ADD

    keys = pygame.key.get_pressed()                  # <--- CHANGE
    if keys[pygame.K_ESCAPE]:
        print("System Terminated ('ESC')")
        sys.exit(0)

Note, you use the same angle for both objects. Hence the angle is incremented twice in each frame.

Related