Search code examples
pythonwhile-looppygame

Game crashes when reaching "while creating:" loop


The Title says it all.

import pygame
import os

pygame.init()

displayWidth = 1280
displayHeight = 720
black = (0,0,0)
white = (255,255,255)

# Defining variables that determine what points the code has reached.
Running = True
intro = True
menu = True
gender = True
charactercreation = True
genderpicked = False
mcgender = "Null"
displaycharactercreation = True # Defining a loop so that the character creation screen doesn't jitter, blitting multiple times.
creating_character = True
creating = True
event = pygame.event.wait()
key = pygame.key.get_pressed()
n = 1

# Defining a textbox maker
def text_objects(text, font, colour):
    textSurface = font.render(text, True, colour)
    return textSurface, textSurface.get_rect()

# Defining a fade function
def fade(direction):
    if direction == "Out":
        black = (0, 0, 0)
        fade_opacity = 0
        fading = True
        while fading:
            fade_opacity += 1
            fadeshape = pygame.Surface((1280, 720))
            fadeshape.set_alpha(fade_opacity)
            fadeshape.fill(black)
            display.blit(fadeshape, (0,0))
            pygame.display.update()
            if fade_opacity == 100:
                fading = False
    elif direction == "In":
        black = (0, 0, 0)
        fade_opacity = 255
        fading = True
        while fading:
            fade_opacity -= 1
            fadeshape = pygame.Surface((1280,720))
            fadeshape.set_alpha(fade_opacity)
            fadeshape.fill(black)
            display.blit(fadeshape, (0,0))
            pygame.display.update()
            if fade_opacity == 0:
                fading = False

# Creating window and defining images
display = pygame.display.set_mode((displayWidth, displayHeight))


pygame.display.set_caption("Blazing Badge")
clock = pygame.time.Clock()

warriorImage = pygame.image.load("warrior.png")
grassImage = pygame.image.load("grass.png")
playButton = pygame.image.load("play button.png")
durandal = pygame.image.load("durandal.png")
mainscreen = pygame.image.load("mainmenu.jpg")
logo = pygame.image.load("logo.png")
arrow = pygame.image.load(os.path.join("graphics", "left_arrow.png"))

pygame.display.set_icon(durandal) # Setting the Window Icon

while Running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

        print(event)

    mouse = pygame.mouse.get_pos()
    pressed = pygame.mouse.get_pressed()

    # Main menu follows ----------------
    while menu:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        display.fill(white)
        largeText = pygame.font.Font("The Fighter.otf", 115)
        TextSurf, TextRect = text_objects("Tech Demo", largeText, black)
        TextSurf = pygame.transform.rotate(TextSurf, 15)
        TextRect.center = ((displayWidth*0.68), (displayHeight*0.4))
        playpos = (((displayWidth/2)-100), (displayHeight)*0.7)
        durandalpos = (((displayWidth/2)-280), (displayHeight*0.2))
        display.blit(mainscreen, (0,0))
        display.blit(playButton, playpos)
        durandalresized = pygame.transform.scale(durandal, (561, 333))
        display.blit(durandalresized, durandalpos)
        display.blit(logo, ((displayWidth*0.2), (displayHeight*0.35)))
        display.blit(TextSurf, TextRect)

        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()

        print(click)
        print(mouse)


        if 580 < mouse[0] < 710 and 532 < mouse[1] < 674:
            if click[0] == 1:
                print("Start Game")
                fade(direction="Out")
                menu = False
        pygame.display.update()
        clock.tick(15)

    print("I have broken out of the main menu loop.")

    while charactercreation:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gender_symbols = pygame.image.load(os.path.join("graphics\Character Creation", "Gender Symbols.png"))
        creation_background = pygame.image.load(os.path.join("graphics\Character Creation", "creationbackground.jpg"))
        TextSurf, TextRect = text_objects("Choose your gender", pygame.font.Font("The Fighter.otf", 115), white)

        display.blit(creation_background, (0, 0))
        display.blit(TextSurf, (((1280 / 2) - 500), displayHeight * 0.1))
        display.blit(gender_symbols, (340, (displayHeight * 0.6)))
        pygame.display.update()

        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()

        charactercreation = False

    print("I have broken out of the character creation loop.")

    while genderpicked == False:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            print(event)

        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()

        if 365 < mouse[0] < 602 and 457 < mouse[1] < 702 and click[0] == 1:
            mcgender = "Female"
            genderpicked = True
            print(mcgender)
        elif 457 < mouse[1] < 702 and 677 < mouse[0] < 916 and click[0] == 1:
            mcgender = "Male"
            genderpicked = True
            print(mcgender)

    print("I have broken out of the gender picking loop.")



    while displaycharactercreation:

        display.blit(creation_background, (0, 0))
        pygame.display.update()
        print(mcgender)
        if mcgender == "Male":
            gendercolour = (0, 128, 255)
        elif mcgender == "Female":
            gendercolour = (255, 0, 127)
        else:
            gendercolour = white
        # Creating the prompts for the creation screen.
        LetterQ1, LetterQ2 = text_objects("<- Q", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterQ1, (100, 50))
        LetterE1, LetterE2 = text_objects("E->", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterE1, (1080, 50))
        LetterA1, LetterA2 = text_objects("<- A", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterA1,(100, 310))
        LetterD1, LetterD2 = text_objects("D ->", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterD1, (1080, 310))
        LetterZ1, LetterZ2 = text_objects("<- Z", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterZ1, (100, 570))
        LetterC1, LetterC2 = text_objects("C ->", pygame.font.Font("The Fighter.otf", 115), gendercolour)
        display.blit(LetterC1, (1080, 570))
        pygame.display.update() # Applying all of the prompts
        displaycharactercreation = False

    print("I have stopped displaying the prompts for character creation")

    while creating_character:
        if mcgender == "Male":
            print("I have reached male")
            while creating:
                print("I have reached creation loop male")
                key = pygame.key.get_pressed()
                if key[pygame.K_q]:
                    if n == 1:
                        n = 8
                    else:
                        n -= 1
                    print(n)
                if key[pygame.K_e]:
                    if n == 8:
                        n = 1
                    else:
                        n += 1
                    print(n)

This is the code so far, running python and pygame. Sorry if the code is just a bit all over the place, it's how I'm used to coding,

When reaching this point:

while creating_character:
    if mcgender == "Male":
        print("I have reached male")
        while creating:
            print("I have reached creation loop male")
            key = pygame.key.get_pressed()
            if key[pygame.K_q]:
                if n == 1:
                    n = 8
                else:
                    n -= 1
                print(n)
            if key[pygame.K_e]:
                if n == 8:
                    n = 1
                else:
                    n += 1
                print(n)
            if key[pygame.K_RETURN]:
                creating = False
                creating_character = False

The code crashes and the window begins not responding past the point of while creating: I still get the interpreter returning "I have reached creation loop male", over and over again.


Solution

  • The code does not crash, but it is not responding, because the event handling is missing.

    The array of key states, which is returned by pygame.key.get_pressed(), is evaluated when the events are handled by either pygame.event.pump() or pygame.event.get(). When a keyboard event occurse, then the internal states of the key is updated and pygame.key.get_pressed() can return the new states.

    Call pygame.event.pump() in the inner loop:

    while creating:
    
        # handle events
        pygame.event.pump()
    
        print("I have reached creation loop male")
    
        # get the current key states
        key = pygame.key.get_pressed()
    
        if key[pygame.K_q]:
            if n == 1:
                n = 8
            else:
                n -= 1
            print(n)
        if key[pygame.K_e]:
            if n == 8:
                n = 1
            else:
                n += 1
            print(n)
        if key[pygame.K_RETURN]:
            creating = False
            creating_character = False