Search code examples
pythonpygame2d-gamespygame-clock

Unable to properly refresh display in Pong game


import pygame, sys

pygame.init()

display_width = 800
display_height = 500

white = (255, 255, 255)

display = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Pong')
clock = pygame.time.Clock()

platform_y = display_height * 0.38

def platform(color, x, y):
    global platform_y

    pygame.draw.rect(display, color, (x, y, 25, 100))

    pygame.display.update()
    clock.tick(80)

def ball():
    pygame.draw.circle(display, white, (400, 250), 12)
    pygame.display.update()

def game():
    global platform_y
    y_change = 0
    while True:
        platform(white, 100, platform_y)
        platform(white, 675, platform_y)
        ball()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                sys.exit(0)

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    y_change -= 2
                if event.key == pygame.K_DOWN:
                    y_change += 2

            if event.type == pygame.KEYUP:
                    if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                        y_change = 0

        platform_y += y_change
        pygame.display.update()
        clock.tick(80)

if __name__ == '__main__':
    game()

I guess it's not the best code but I've been messing around with pygame and got to the point when I have to create Pong, although I'm not sure why the rectangles (platforms) are just getting higher instead of going up and down (I know that both platforms will rise together, will fix that, this is just for test)


Solution

  • You had couple of issues with your code:

    1. You have to call pygame.display.update only once, not after every pygame.draw,
    2. clock.tick is set in main game loop, not in other places,
    3. You have to clear the screen before drawing.

    Here is what will probably work as you expect:

    import pygame, sys
    
    pygame.init()
    
    display_width = 800
    display_height = 500
    
    white = (255, 255, 255)
    
    display = pygame.display.set_mode((display_width, display_height))
    pygame.display.set_caption('Pong')
    clock = pygame.time.Clock()
    
    platform_y = display_height * 0.38
    
    
    def platform(color, x, y):
        global platform_y
    
        pygame.draw.rect(display, color, (x, y, 25, 100))
    
    
    def ball():
        pygame.draw.circle(display, white, (400, 250), 12)
    
    
    def game():
        global platform_y
        y_change = 0
    
        while True:
            platform(white, 100, platform_y)
            platform(white, 675, platform_y)
            ball()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit(0)
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                    sys.exit(0)
    
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        y_change -= 2
                    if event.key == pygame.K_DOWN:
                        y_change += 2
    
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                        y_change = 0
    
            platform_y += y_change
    
            pygame.display.update()
            clock.tick(80)
            display.fill((0, 0, 0))
    
    
    if __name__ == '__main__':
        game()
    

    Couple of advices:

    1. Don't use global! It's smells on bad code. There are certainly better ways to achieve what you wanted without using it.
    2. Try to avoid a lot of conditions nesting. It's very hard to read, and will require much mental energy to read after day or two.

    Happy coding!