Milnik
Milnik

Reputation: 55

Moving between game screens

I am quite new to pygame and have a problem with designing a main loop that handles the different game screens. I am writing a checkers game with 3 different screens.

Intro screen: takes in the desired board size N and passes it to the main loop. The main loop then calls game_screen where my game class is called with called with N as a parameter.

Game screen: Calls Game class, so the entire game is run here. It also gets returns such as elapsed time and winner from the game class. The idea is to pass these into the main loop and call game_over_screen with them as parameters.

This causes issues as my return "choice" is sometimes a tuple and sometimes an int. It is an int when I'm closing the window, but a tuple is returned when a game is won.

Game Over: should basically just take winner and elapsed time and print them. Also should return a choice when the button is clicked. This should go back to the intro screen.

What I need help with: The logic in my main loop seems VERY bulky. The idea of sometimes returning an int and sometimes a tuple doesn't seem right to me. I'm grateful for any tips with how these main loops for simple games like this are designed.

# Intro Screen
########################################################################### 
def game_intro_screen():                  
    intro  = True
    while intro:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:     #quit by closing the window
                return 0  
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE:
                    return 2                            
        screen.fill(BLACK)                     # Fill background with black
        pygame.display.set_caption("CHECKERS")
        message_to_screen("CHECKERS", GRAY, y_displace=-350, size="large")    
        message_to_screen("- Rules -", GRAY, y_displace=-170, size="medium")
        message_to_screen("- Peasants( x, o) can only move diagonally forward.", GRAY, y_displace=-120, size="small")
        message_to_screen("- Kings (X, O) can move diagonally both ", GRAY, y_displace= -90, size="small")
        message_to_screen(" forward and backwards. ", GRAY, y_displace= -60, size="small")#
        message_to_screen("- Tokens can only move to a free field.", GRAY, y_displace= -30, size="small")
        message_to_screen("- Eat the opponents pieces by jumping over them.", GRAY, y_displace= 0, size="small")
        message_to_screen("- Win the game by eating the opponent's tokens.", GRAY, y_displace= 30, size="small")

        message_to_screen("- Controls - ", GRAY, y_displace= 100, size="medium")
        message_to_screen("- Click a token to select it. ", GRAY, y_displace= 150, size="small")
        message_to_screen("- Click an empty field to move your selected token", GRAY, y_displace= 180, size="small")

        message_to_screen("- Chose the grid size - ", GRAY, y_displace= 300, size="medium")

        choice=button("8 X 8", 60,800,150,50, GRAY, BLUE, action="play8")
        if choice!=None: 
            return 8
        choice=button("10 X 10", 270,800,150,50, GRAY, BLUE, action="play10")
        if choice!=None: 
            return 10
        choice=button("12 X12", 485,800,150,50, GRAY, BLUE, action="play12")
        if choice!=None: 
            return 12

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

# Game Over Screen
########################################################################### 
def game_over_screen(winner, end_time):                    # pass winner, time here


    second= end_time
    minute=0
    hour=0    
    minute, second=divmod(second, 60)
    hour, minute=divmod(minute, 60)
    time=(hour, minute, second)


    intro  = True
    while intro:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:     #quit by closing the window
                return 0  
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE:
                    return 2             

        screen.fill(BLACK)                     # Fill background with black
        pygame.display.set_caption("CHECKERS")
        message_to_screen("GAME OVER", GRAY, y_displace=-350, size="large")  
        #message_to_screen("%s wins!" % winner, GRAY, y_displace=-100, size="medium")
        message_to_screen("Player %s won!" % winner , GRAY, y_displace=-100, size="medium")  
        #message_to_screen(" Elapsed time: 00:12:43" , GRAY, y_displace=50, size="medium")
        message_to_screen(" Elapsed time: "+str("%d" %time[0] + " : "+"%d" %time[1] + " : "+"%d" %time[2]) , GRAY, y_displace=50, size="medium")
        message_to_screen("-------------------------------" , GRAY, y_displace=120, size="small")
        #message_to_screen(" Current High score: 00:07:11" , GRAY, y_displace=150, size="small")
        #text=smallfont.render("Elapsed time: "+str("%d" %hour + " : "+"%d" %minute + " : "+"%d" %second), True, WHITE) 
        #screen.blit(text, [0+MARGIN,350])  
        choice=button("Play again?", 220,800,250,50, GRAY, BLUE, action="play")
        if choice!=None: 
            return 3

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


# Game Screen
########################################################################### 

def game_screen(N):

    game = Game(N)
    validmove= None

    done= False
    while not done:
        #Keyboard and mouse event handling
        for event in pygame.event.get(): 
            if event.type == pygame.QUIT: 
                return 0

            if event.type == pygame.KEYDOWN:
                entry = str(event.key)

            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                game.evaluate_click(pygame.mouse.get_pos())



        # Game over calls, get winner, get_end time get saved_seconds
        ########################################################## 
        if game.status == 'game over':
            winner= game.winner
            end_time= timer()[0]
            sec=getScore()
            if sec < end_time:
                saveScore(sec)

            print (winner)
            print(end_time)
            return 2, winner, end_time

        # Draw calls
        ############################# 
        screen.fill(BLACK)
        # Draw the game board and tokens:
        game.draw()
        # Display whose turn is it
        message=str(pygame.display.get_caption()[0])
        message_to_screen(message, WHITE, y_displace=310, size="small")
        #print (timer()[0])
        time=timer()[1]
        # Display Game timer
        text=smallfont.render("Elapsed time: "+str(time[0]) + " : " +str(time[1])+ " : " +str(time[2]), True, WHITE) 
        screen.blit(text, [200,800])
        # Display invalid move
        if game.valid_move==False:
            validmove = "Invalid Move"
            text=smallfont.render(validmove, True, WHITE) 
            screen.blit(text, [250,850])

        pygame.display.flip()
        clock.tick(10)


        pygame.display.flip()     
        clock.tick(30)


########################################################################### 



choice= game_intro_screen()
while choice !=0:
    # active_board = 8x8
    if choice==8:
        a= game_screen(choice)
        if isinstance(a, tuple):
            choice=a[0]
        else:
            choice=game_screen(choice)
    # active_board = 10x10
    if choice==10:
        a= game_screen(choice)
        if isinstance(a, tuple):
            choice=a[0]
        else:
            choice=game_screen(choice)
    # active_board = 12x12
    if choice==12:
        a= game_screen(choice)
        if isinstance(a, tuple):
            choice=a[0]
        else:
            choice=game_screen(choice)  
    # Exit to game_over screen
    if choice==2:
        if isinstance(a, tuple):
            W=a[1]
            ET=a[2]
        choice=game_over_screen(W,ET)       # Pass winner into game_over_screen
    # From game_over_screen, Play again, call intro screen
    if choice==3:
        choice=game_intro_screen()



pygame.QUIT
quit()

Upvotes: 0

Views: 98

Answers (1)

Lennart Steinke
Lennart Steinke

Reputation: 614

One way to fix this, would be to return a dict containing the information. Add a "reason" which you can use to store the reason why the game ended (cancelled, game over) and other entries based on the reason, if needed.

This will also allow you to later return additional information while still returning the same data type.

Upvotes: 1

Related Questions