Nathan Holmes-King
Nathan Holmes-King

Reputation: 45

How to make pygame update in real time?

I am trying to make a baseball-themed game in Python 3.6.5 using Pygame 1.9.4. I can get the welcome screen to show, but I can't get the runGame() function (which uses a while True: loop) to show the field and scoreboard unless I exit the program. The game is far from complete, but I have decided to fix this problem before implementing game mechanics.

I have placed pygame.display.update() everywhere I can think of. In older infinite-loop games written in Python 2 that I have made, I have gotten pygame to update in real time.

import pygame, sys
from pygame.locals import *

FPS=15

#Main function
def main():
    global FPSCLOCK,DISPLAYSURF,BASICFONT
    pygame.init()
    FPSCLOCK=pygame.time.Clock()
    DISPLAYSURF=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
    BASICFONT=pygame.font.Font('freesansbold.ttf',18)
    pygame.display.set_caption('Baseball')
    showStartScreen()
    while True:
        runGame()
        showGameOverScreen()

#Shows welcome menu
def showStartScreen():
    titleFont=pygame.font.Font('freesansbold.ttf',100)
    titleSurf=titleFont.render('BASEBALL',True,WHITE,GREEN)
    titleRect=titleSurf.get_rect()
    titleRect.center=(WINDOWWIDTH/2,WINDOWHEIGHT/2)
    DISPLAYSURF.fill(BROWN)
    DISPLAYSURF.blit(titleSurf, titleRect)
    pygame.display.update()
    while True:
        if checkForKeyPress():
            pygame.event.get()
            return

#Main loop for game
def runGame():
    balls=0
    strikes=0
    outs=0
    drawField()
    pygame.display.flip()
    while True:
        drawScoreboard(balls, strikes, outs)
        pygame.display.update()

if __name__=='__main__':
    main()

When I press a key to begin the game, pygame only shows the welcome screen. When I force-quit the program, pygame automatically updates to show the field and scoreboard.

Upvotes: 3

Views: 2157

Answers (1)

Kingsley
Kingsley

Reputation: 14916

It's pretty close to working.

However some of the loop conditions are not calling things properly. I had to invent checkForKeyPress() and other functions since you didn't include them - maybe these had an issue? The code needs special handling of every pygame.QUIT event for when the user wants to close the window. A user doesn't want to wait when it's time to close the program!

Sometimes the quit was not being handled, I think this is the reason you are seeing the reported display updating behaviour.

The runGame() needs to handle user-input too, especially this exit.

import pygame, sys, time
from pygame.locals import *

WINDOWWIDTH,WINDOWHEIGHT = 800,800
WHITE=(255,255,255)
GREEN=(0,200,0)
BROWN=(164,113,24)

FPS=15

def checkForKeyPress():
    while ( True ):
        for event in pygame.event.get():
            if ( event.type == pygame.QUIT ):
                pygame.event.post( event ) # re-post the quit event to handle later
                return False
            # Any keyboard press, or mouse-click
            elif ( event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN ):
                return True

def drawField():
    global FPSCLOCK,DISPLAYSURF,BASICFONT
    DISPLAYSURF.fill(GREEN)

def drawScoreboard(balls, strikes, outs):
    pass

def showGameOverScreen():
    pass

#Main function
def main():
    global FPSCLOCK,DISPLAYSURF,BASICFONT
    pygame.init()
    FPSCLOCK=pygame.time.Clock()
    DISPLAYSURF=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
    BASICFONT=pygame.font.Font('freesansbold.ttf',18)
    pygame.display.set_caption('Baseball')
    showStartScreen()
    while True:
        if ( runGame() == False ):
            break
        showGameOverScreen()
    pygame.quit()

#Shows welcome menu
def showStartScreen():
    titleFont=pygame.font.Font('freesansbold.ttf',100)
    titleSurf=titleFont.render('BASEBALL',True,WHITE,GREEN)
    titleRect=titleSurf.get_rect()
    titleRect.center=(WINDOWWIDTH/2,WINDOWHEIGHT/2)
    DISPLAYSURF.fill(BROWN)
    DISPLAYSURF.blit(titleSurf, titleRect)
    pygame.display.update()
    checkForKeyPress()
    print("showStartScreen() returns")

#Main loop for game
def runGame():
    global FPSCLOCK,DISPLAYSURF,BASICFONT
    balls=0
    strikes=0
    outs=0
    print("runGame() starts")
    while True:
        drawField()
        drawScoreboard(balls, strikes, outs)

        # Handle user-input
        for event in pygame.event.get():
            if ( event.type == pygame.QUIT ):
                return False # user wants to exit the program

        # Movement keys
        keys = pygame.key.get_pressed()
        if ( keys[pygame.K_UP] ):
            print("up")
        elif ( keys[pygame.K_DOWN] ):
            print("down")
        # elif ( ...

        pygame.display.flip()
        pygame.display.update()

        # Clamp FPS
        FPSCLOCK.tick_busy_loop(60)

    return True  # Game Over, but not exiting program



if __name__=='__main__':
    main()

Upvotes: 1

Related Questions