コード例 #1
0
def OfflinePauseMenu(mainGame, screen, clock):
    save_file_box = TextBox(
        (340, 300, 560, 50),
        clear_on_enter=False,
        inactive_on_enter=False,
        active=False,
        active_color=pygame.Color(
            "red"))  #Create text box for storing save file path
    save_file_box.buffer = list(
        mainGame.save_path
    )  #list() is used to convert string into array of characters

    music_box = pygame.Rect(100, 200, 40, 40)
    font_48 = pygame.font.SysFont(
        'Arial', 48)  #Fonts used for texts, of various sizings
    font_60 = pygame.font.SysFont('Arial', 60)
    font_40 = pygame.font.SysFont('Arial', 40)
    font_28 = pygame.font.SysFont('Arial', 28)

    enable_txt = "Enable"
    if mainGame.autosave:
        enable_txt = "Disable"

    pause_buts = [
        Button(150, 425, 300, 80, "Save and Exit", font_40),
        Button(600, 425, 300, 80, "Exit Without Saving", font_40),
        Button(75, 620, 400, 80, "Save and Restart", font_40),
        Button(550, 620, 400, 80, "Restart Without Saving", font_40),
        Button(750, 10, 200, 80, "Resume", font_60),
        Button(910, 300, 90, 50, "Change", font_28),
        Button(910, 360, 90, 50, enable_txt, font_28)
    ]

    msgBox = None  #Will become MessageBox object as required

    pause_title = font_60.render("The Game is Paused", True,
                                 (0, 0, 0))  #Generate text for titles
    settings_txt = font_60.render("Settings:", True,
                                  (0, 0, 0))  #Settings sub-heading
    toggle_txt = font_48.render("Toggle Background Music", True,
                                (0, 0, 0))  #Text next to check box
    save_txt = font_60.render("Save Game:", True,
                              (0, 0, 0))  #Save Game sub-heading
    save_file_txt = font_48.render("Save File Path:", True,
                                   (0, 0, 0))  #Title of save path text box
    new_txt = font_60.render("New Game:", True,
                             (0, 0, 0))  #New game sub-heading
    autosave_txt = [
        font_48.render("Autosave is currently off", True, (0, 0, 0)),
        font_48.render("Autosave is currently on", True, (0, 0, 0))
    ]

    music_box_click = False
    pause_menu_running = True
    while pause_menu_running:
        for event in pygame.event.get():
            for but in pause_buts:
                but.handle_input_event(event)
            if msgBox != None:  #If a MessageBox has been created
                msgBox.handle_input_event(event)
                if msgBox.should_exit == False:
                    break  #Exit for loop; do not register any other objects
            if event.type == pygame.QUIT:
                pause_menu_running = False
                gotoScreen = -1
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:  #Escape key exits the game
                    pause_menu_running = False  #This screen will no longer run
                    gotoScreen = -1  #Game will completely exit
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  #Left mouse button
                    if music_box.collidepoint(
                            event.pos
                    ):  #Check box for toggling background music
                        music_box_click = True
            save_file_box.get_event(
                event
            )  #Function that allows each textbox to register key presses and the like

        screen.fill((255, 255, 255))  #Clear the screen
        pygame.draw.rect(screen, (0, 0, 0),
                         pygame.Rect(50, 20, 20,
                                     60))  #Rectangles for pause symbol
        pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(80, 20, 20, 60))
        screen.blit(pause_title, [120, 10])
        screen.blit(settings_txt, [10, 110])

        pygame.draw.rect(screen, (0, 0, 0), music_box,
                         2)  #Display blank check box
        if not mainGame.pause:  #If music is unpaused, check box needs to be checked
            pygame.draw.line(
                screen, (0, 0, 0), [102, 220], [115, 238],
                4)  #Display two lines corresponding to the two parts of a tick
            pygame.draw.line(screen, (0, 0, 0), [115, 238], [145, 195], 4)

        screen.blit(toggle_txt, [150, 190])
        screen.blit(save_txt, [10, 240])
        screen.blit(save_file_txt, [30, 300])
        screen.blit(new_txt, [10, 550])

        save_file_box.update()  #Update the textbox based on events
        save_file_box.draw(screen)  #Draw the text box and contents on screen

        screen.blit(autosave_txt[int(mainGame.autosave)], [30, 360])

        if pause_buts[5].clicked():  #Button for updating save file path
            valid = True  #Whether the file path entered is valid
            if save_file_box.getContents()[-3:].lower(
            ) != "dfo":  #Must have correct file ending, or invalid
                msgBox = MessageBox(
                    screen,
                    'Invalid file. Please ensure the entered file has the correct .dfo file ending.',
                    'File Error')
                valid = False  #Path is not valid as wrong file ending

            if valid:
                try:
                    os.makedirs(os.path.dirname(save_file_box.getContents()),
                                exist_ok=True)
                    f = open(save_file_box.getContents(), 'w+')
                except:  #Any error occurs in creating the directory or file
                    msgBox = MessageBox(
                        screen,
                        'Invalid save file entered. Please ensure the path entered exists and you have permissions to access it (the file does not have to)',
                        'Invalid Save File')
                    valid = False  #Path is not valid as cannot be created without error

            if valid:
                mainGame.save_path = save_file_box.getContents(
                )  #Update save file within the Game object
                mainGame.saveGame()  #Save the game in the newly entered file

        if pause_buts[6].clicked(
        ):  #Button for toggling autosave feature on/off
            mainGame.autosave = not mainGame.autosave  #Toggle the boolean value of autosave
            if mainGame.autosave:
                pause_buts[6].updateCap("Disable")
            else:
                pause_buts[6].updateCap("Enable")

        if pause_buts[0].clicked():  #Save and Exit
            mainGame.saveGame()  #Save game
            pause_menu_running = False  #This screen no longer running
            gotoScreen = -1  #Don't go to any other screen (i.e. exit completely)

        if pause_buts[1].clicked():  #Exit without saving
            pause_menu_running = False  #This screen no longer running
            gotoScreen = -1  #Don't go to any other screen (i.e. exit completely)

        if pause_buts[2].clicked():  #Save and restart
            mainGame.saveGame()  #Save the game
            pause_menu_running = False  #This screen no longer running
            gotoScreen = 0

        if pause_buts[3].clicked():  #Restart without saving
            pause_menu_running = False  #This screen no longer running
            gotoScreen = 0  #Goto new game screen

        if pause_buts[4].clicked():  #Resume
            pause_menu_running = False
            gotoScreen = 1

        if music_box_click:  #Check box for background music
            if mainGame.pause:  #Music is currently paused
                pygame.mixer.music.unpause()  #Unpause music
            else:  #Music is currently unpaused
                pygame.mixer.music.pause()  #Pause music
            mainGame.pause = not mainGame.pause  #Toggle state of pause in Game class

        if msgBox != None:  #If a MessageBox has been created
            msgBox.update()  #Update message box with relevant events
            if msgBox.should_exit == False:  #If message box should be showing
                msgBox.draw(screen)  #Draw message box on screen

        for but in pause_buts:
            but.render(screen)

        music_box_click = False
        clock.tick(10)  #10 fps
        pygame.display.flip()  #Refresh screen

    return mainGame, gotoScreen  #Pass the Game object and the integer storing where the game will go to next back out to the main game loop
コード例 #2
0
def NewNet(screen, clock):
    font_48 = pygame.font.SysFont('Arial', 48)
    font_40 = pygame.font.SysFont('Arial', 40)
    font_28 = pygame.font.SysFont('Arial', 28)

    pieces_x = 350
    pieces_y = 450

    name_box = TextBox((320, 400, 380, 50),
                       clear_on_enter=False,
                       inactive_on_enter=True,
                       active=True,
                       active_color=pygame.Color("red"))
    name_text = font_48.render("Enter your Name (max 12 characters):", True,
                               (0, 0, 0))
    n_width, n_height = font_48.size("Enter your Name (max 12 characters):")
    name_button = Button(400, 460, 200, 80, "Confirm", font_48)

    ready_up_but = Button(400, 460, 200, 80, "Ready Up", font_48)
    start_game_but = Button(400, 460, 200, 80, "Start Game", font_48)
    ready_up_but.hideBut()
    start_game_but.hideBut()

    piece_rects = [None] * 6
    piece_imgs_lobby = [None] * 6
    for n in range(6):
        piece_rects[n] = pygame.Rect(pieces_x + 110 * (n % 3),
                                     pieces_y + 110 * int(n / 3), 100, 100)
        piece_imgs_lobby[n] = pygame.transform.smoothscale(
            pygame.image.load("img/Pieces/" + str(n + 1) + ".png"), [30, 30])

    choose_text = font_40.render("Choose Your Piece:", True, (0, 0, 0))
    pieces_large = np.array([None] * 6)  #Load 6 available player pieces
    for p_counter in range(6):
        pieces_large[p_counter] = pygame.transform.smoothscale(
            pygame.image.load("img/Pieces/" + str(p_counter + 1) + ".png"),
            [100, 100])  #Load image into pygame and resize

    # Read in host (server) IP and port from file.
    # This means that the server IP and port do not have to be hard-coded.
    f = open("data/Host_Data.txt", "r")
    host_dat = f.readline().split(",")
    # Some setup code that was previously run while the screen was active.
    # Having it here instead streamlines things a bit.
    ip_text = font_48.render(
        "Your IP: " + socket.gethostbyname(socket.gethostname()), True,
        (0, 0, 0))
    lobby = Pyro4.Proxy("PYRO:dfo.game@" + host_dat[0] + ":" + host_dat[1])
    # Okay, this is actually a Game() class object, but the Lobby() part is the only part actually used here,
    # and I wrote everything here with lobby separate first, so why bother changing it?

    ready_up_texts = [
        font_48.render("Waiting for players to ready up.", True, (0, 0, 0)),
        font_48.render("Waiting for players to ready up..", True, (0, 0, 0)),
        font_48.render("Waiting for players to ready up...", True, (0, 0, 0))
    ]

    waiting_texts = [
        font_48.render("Waiting to start.", True, (0, 0, 0)),
        font_48.render("Waiting to start..", True, (0, 0, 0)),
        font_48.render("Waiting to start...", True, (0, 0, 0))
    ]

    newnet_running = True
    piece_choice = -1
    piece_chosen = False
    name_chosen = False
    ready_up = False
    start_game = False
    while newnet_running:
        for event in pygame.event.get():
            if name_box.visible:
                name_box.get_event(event)
                name_button.handle_input_event(event)
            ready_up_but.handle_input_event(event)
            start_game_but.handle_input_event(event)

            if event.type == pygame.QUIT:
                newnet_running = False
                gotoScreen = -1

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:  #Escape key exits the game
                    newnet_running = False  #This screen will no longer run
                    gotoScreen = -1  #Game will completely exit
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  #Left mouse button
                    if not piece_chosen and name_chosen:
                        for n in range(6):
                            if piece_rects[n].collidepoint(event.pos):
                                piece_choice = n

        screen.fill((255, 255, 255))

        if not name_box.visible:  #Player has entered name; show lobby and following game setup
            screen.blit(ip_text, [10, 10])
            screen.blit(host_text, [10, 60])
            renderLobby(screen, lobby, 10, 110, font_40, font_28,
                        piece_imgs_lobby)
            if not piece_chosen:
                renderPieces(screen, pieces_large, lobby, pieces_x, pieces_y,
                             choose_text)
            ready_up_but.render(screen)
            start_game_but.render(screen)

            if ready_up and not start_game and not lobby.allReadyUp():
                screen.blit(
                    ready_up_texts[int(pygame.time.get_ticks() / 500) % 3],
                    [235, 460])

            if start_game and not lobby.allReadyToStart():
                screen.blit(
                    waiting_texts[int(pygame.time.get_ticks() / 500) % 3],
                    [375, 460])

        if name_box.visible:  #Player is entering name
            name_box.update()
            name_box.draw(screen)
            name_button.render(screen)
            screen.blit(name_text, [(1024 - n_width) / 2, 335])

        if name_button.clicked():
            #Determine if the name entered is valid. Will try and do something to prevent duplicate naming...
            if len(name_box.getContents()) <= 12 and len(
                    name_box.getContents()) != 0:  #Name is valid
                #Display your IP and name, and connect to server using Pyro4 module
                host_text = font_48.render(
                    "Your Name: " + name_box.getContents(), True, (0, 0, 0))
                lobby.connect(socket.gethostbyname(socket.gethostname()),
                              name_box.getContents())

                name_box.hide()
                name_chosen = True
                name_button.hideBut()

        if piece_choice != -1 and name_chosen:
            if not (piece_choice + 1 in lobby.getUsedPieces()):
                lobby.setPiece(socket.gethostbyname(socket.gethostname()),
                               piece_choice + 1)
                piece_chosen = True
                ready_up_but.showBut()
            piece_choice = -1

        if ready_up_but.clicked():
            lobby.readyUp(socket.gethostbyname(socket.gethostname()))
            ready_up = True
            ready_up_but.hideBut()

        if start_game_but.clicked():
            lobby.readyToStart(socket.gethostbyname(socket.gethostname()))
            start_game = True
            start_game_but.hideBut()

        if not start_game and name_chosen and not start_game_but.visible and ready_up:
            if lobby.allReadyUp() and dim(
                    lobby.getLobby()
            )[0] >= 2:  #May not proceed until at least two players have joined
                start_game_but.showBut()

        if start_game and name_chosen and ready_up:
            if lobby.allReadyToStart() and dim(lobby.getLobby(
            ))[0] >= 2:  #At least two players required for a game (duh!)
                #Creation of localGame object first
                players = createLocalPlayers(
                    pieces_large,
                    lobby.getLobby())  #Create array of LocalPlayer objects
                prop_arr = createLocalProperties(
                    "data/Property Values.txt"
                )  #Create array of Property objects
                Pot_Luck_Deck = createLocalDeck("Pot Luck", "img/PL/Pot Luck ",
                                                "data/Card_Texts.txt",
                                                "data/PL Master.txt",
                                                16)  #Create Card_Deck object
                Council_Chest_Deck = createLocalDeck(
                    "Council Chest", "img/CC/Council Chest ",
                    "data/Card_Texts.txt", "data/CC Master.txt",
                    16)  #Create Card_Deck object
                game_board = createLocalBoard("data/Board_Data.txt", prop_arr,
                                              Pot_Luck_Deck,
                                              Council_Chest_Deck,
                                              "img/Board.png",
                                              600)  #Create Board object
                this_player_num = findPlayerNum(lobby)

                localGame = createLocalGame(
                    players, game_board, "img/Dice/", this_player_num
                )  #Finally create the single, cohesive Game object that is the sole purpose of this screen/part of the game

                if lobby.getGameSetup() == False:
                    fh = open("data/Property Values.txt", "r")
                    prop_data = fh.read()
                    lobby.setupGame(prop_data)

                newnet_running = False
                gotoScreen = 6

        clock.tick(10)  #10 fps
        pygame.display.flip()  #Refresh screen

    return lobby, localGame, gotoScreen