0

I've encountered an issue in my program where, upon the game entering a new while loop, it freezes (or at least appears to freeze).

When I click outside the window the games stops responding, which leads me to believe that it's most likely the game freezing/crashing over simply not detecting an input.

When playing my game, the user has four options to select (only two of them somewhat work at the moment), one of them allowing them to access their inventory. when the variable "inv" == True, the game is meant to enter a loop similar to the game's main loop where procedures limited to the inventory screen will occur.

Here's the code relevant to the "inv == True" while loop:

def textChange(end, inv, spin, fight, run): #code for changing text
    integ = random.randint(0,4) # for choosing a random escape quote from the runWords variable
    if end == True:
        display_box.draw(screen) # draws the main box to the screen.
        textDisplay("", 487, 312, fBold)
        textDisplayMessage(run[integ],12,297)
        time.sleep(2)
        pygame.quit() #quit game
        sys.exit()
        gameRun = False #break the loop.
    elif inv == True: #if the inventory has been selected
        while inv == True: #if user in the inventory menu:
            key = pygame.key.get_pressed()
            inv_window = pygame.transform.scale(pygame.image.load("bigbox.png"), (449, 289)) #loads display box
            screen.fill(bg_colour) #fills screen
            screen.blit(inv_window, (75,0)) #blits the display box
            display_box.drawsmall(screen) #draws smaller box
            pygame.display.update() #updates display
            if key[pygame.K_ESCAPE]: #if down
                inv = False
                print("howdy")
    else:
        display_box.draw(screen) #display larger message box
        display_box.drawsmall(screen) #display smaller selection box
        textDisplay("fight", 487, 312, fBold) #display fight option
        textDisplay("items", 561, 312, iBold) #item option
        textDisplay("spin",487,376, sBold)    #spin option
        textDisplay("run",561,376, rBold)     #run
        textDisplayMessage(message, 12, 297)

and here's the full code for context:

#inventory
#display items in 2 x 4 at right of box
#next page option if more items needed
#items type listed down left side
#select item: use option and back option appear in lower right box
#back option will be present in lower right box otherwise.


import time, random, sys
import pygame
pygame.init()
(width, height) = (600, 400) #specify width, height
bg_colour = (100, 20, 156) #specify bgcolour

#pre-defining some variables so they can be changed later.
fBold = False
iBold = False
sBold = False
rBold = False
down = False
right = False

endFight = False
inven = False
fighty = False
spinner = False

runWords = ["gotta dash.","better skidaddle.","I left the tap running.","nice seein' you.","later."] #for when the player escapes battle

##class inventory(): #inventory items stored in class????
##    def __init__(self):
##        print("hi")
playerInv = ["1","2","3","4","5","6","7","8","9"]


fps = 60

class infoBox(object):
    def __init__(self, surface):
        self.box = pygame.image.load("bigbox.png") # loads text/info boxes
        self.sbox = pygame.image.load("smallbox.png")

    def draw(self, surface):
        surface.blit(self.box, (0, 289)) #for blitting the big and small boxes to the screen
    def drawsmall(self, surface):
        surface.blit(self.sbox, (449, 289))

def textDisplay(text, x, y, bold): #function for displaying text
    if bold == True:
        font = "courbd.ttf" #code for bold text, red and bold font
        colour = (225, 0, 0)
    elif bold == False:
        font = "cour.ttf" #otherwise the font is normal and white
        colour = (255,255,255)
    textSize = pygame.font.Font(font,14) #font size and font is specified
    textSurf = textSize.render(text, True, colour) # code for rendering text
    textRect = textSurf.get_rect()
    textRect.center = (x, y) #coords of text
    screen.blit(textSurf, textRect) #blits text for battle options to screen

def textDisplayMessage(msg, x, y): #function for displaying textbox message
    font2 = "cour.ttf" # separate font variable for option descriptions
    colour2 = (255,255,255) 
    textSize2 = pygame.font.Font(font2,14)
    textSurf2 = textSize2.render(msg, True, colour2)
    textRect2 = textSurf2.get_rect()
    textRect2.topleft = (x, y) #specifies x and y from top left instead ofcenter
    screen.blit(textSurf2, textRect2)
    pygame.display.update() # updates display

def textChange(end, inv, spin, fight, run): #code for changing text
    integ = random.randint(0,4) # for choosing a random escape quote from the runWords variable
    if end == True:
        display_box.draw(screen) # draws the main box to the screen.
        textDisplay("", 487, 312, fBold)
        textDisplayMessage(run[integ],12,297)
        time.sleep(2)
        pygame.quit() #quit game
        sys.exit()
        gameRun = False #break the loop.
    elif inv == True: #if the inventory has been selected
        while inv == True: #if user in the inventory menu:
            key = pygame.key.get_pressed()
            inv_window = pygame.transform.scale(pygame.image.load("bigbox.png"), (449, 289)) #loads display box
            screen.fill(bg_colour) #fills screen
            screen.blit(inv_window, (75,0)) #blits the display box
            display_box.drawsmall(screen) #draws smaller box
            pygame.display.update() #updates display
            if key[pygame.K_ESCAPE]: #if down
                inv = False
                print("howdy")
    else:
        display_box.draw(screen) #display larger message box
        display_box.drawsmall(screen) #display smaller selection box
        textDisplay("fight", 487, 312, fBold) #display fight option
        textDisplay("items", 561, 312, iBold) #item option
        textDisplay("spin",487,376, sBold)    #spin option
        textDisplay("run",561,376, rBold)     #run
        textDisplayMessage(message, 12, 297)

screen = pygame.display.set_mode((width, height)) #specify screen size
pygame.display.set_caption("battle EduGame") #window name

clock = pygame.time.Clock()

pygame.display.flip()

gameRun = True

display_box = infoBox(screen)


while gameRun:


    screen.fill(bg_colour) #fill screen


    event = pygame.event.poll()
    if event.type == pygame.QUIT: #if the "x" is pressed
       pygame.quit() #quit game
       sys.exit()
       gameRun = False #break the loop.
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_RIGHT and right == False: #only allows right arrow to be pressed if the variable for the right arrow hasn't been triggered:
            right = True
        elif event.key == pygame.K_LEFT and right == True: #if the right arrow variable has been triggered, then the left button can be pressed to turn it off again.
            right = False
        elif event.key == pygame.K_UP and down == True: #same, but for down and up.
            down = False
        elif event.key == pygame.K_DOWN and down == False:
            down = True
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN: #if press return...
        if fBold == True:
            print("yo!")
            fighty = True #trigger fight option 
        elif sBold == True:
            print("howdy")
            spinner = True #trigger spinner
        elif iBold == True:
            print("hello")
            inven = True #trigger inventory
        elif rBold == True:
            print("good evening")
            endFight = True #trigger run/end the fight
            textChange(endFight, inven, spinner, fighty, runWords) #change the text.



    if inven == True:
        print("nice one") #placeholder
    else:
        if down == False and right == False: #if pointer in the top left:
            fBold = True
            sBold = False
            iBold = False
            rBold = False
            message = "strike the opponent!" #change the message
        if down == True and right == False: #if in bottom left
            sBold = True
            fBold = False
            iBold = False
            rBold = False
            message = "spin the question wheel!" #change
        if down == False and right == True: #if in top right
            iBold = True
            sBold = False
            fBold = False
            rBold = False
            message = "access your inventory!"
        if down == True and right == True: #if bottom right
            rBold = True
            sBold = False
            iBold = False
            fBold = False
            message = "run like a coward!"

    #print (fBold,sBold,iBold,rBold)
    textChange(endFight, inven, spinner, fighty, runWords) #update text



    pygame.display.update() #update screen


    clock.tick(fps)
Polybrow
  • 65
  • 1
  • 6
  • You need to call one of these [`pygame.event` functions](https://stackoverflow.com/a/42719689) regularly or the window will freeze. In your case you can just call `pygame.event.pump()` in the `while inv == True:` loop. – skrx Dec 05 '18 at 10:18

1 Answers1

2

My guess here is that you break the game loop when you check if the inventory should be open. While the program is in the 'inventory while loop', it cannot retrieve event anymore.

pygame.event.poll() #Is defined only at the beginning of the game loop

you should define your inventory in a function that will display it if it met a certain condition ,without breaking the initial game loop, like

if inv == True:

Also, i think you should use the event mechanism to check if a key is pressed like

if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:

instead of

key = pygame.key.get_pressed()
Momo
  • 108
  • 5