Esempio n. 1
0
    def message_box(self, title, text, on_close=None, font_size=22):
        def modal_done(on_close):
            if self.modal and on_close:
                on_close(self.modal)
            self.modal = None

        if not self.modal:
            self.modal = MessageBox(title,
                                    text,
                                    on_close=lambda *_: modal_done(on_close),
                                    font_size=font_size)
Esempio n. 2
0
def MainScreen(mainGame, screen, clock):
    mainGame.prop_thumbs = pygame.transform.smoothscale(
        CreateThumbs(mainGame.board, mainGame.cur_player), [385, 170])

    roll_dice_button = pygame.Rect(
        180, 610, 150, 70)  #Create rectangle for roll dice/end turn button
    buy_prop_button = pygame.Rect(
        675, 690, 250, 70
    )  #Create rectangle for property buying button (also used for mortgaging and unmortgaging
    buy_upgrade_button = pygame.Rect(350, 700, 150, 50)
    sell_upgrade_button = pygame.Rect(520, 700, 150, 50)
    in_jail_button = pygame.Rect(350, 610, 150, 70)

    TB_img = pygame.transform.smoothscale(
        pygame.image.load("img/Tower Block.png"), [75, 75])
    CH_img = pygame.transform.smoothscale(
        pygame.image.load("img/Council House.png"), [75, 75])

    font_40 = pygame.font.SysFont('Arial',
                                  40)  #Font object for button captions
    font_28 = pygame.font.SysFont(
        'Arial',
        28)  #font object for displaying whose turn it is (among other things)
    font_20 = pygame.font.SysFont('Arial', 20)  #Font for the upgrade buttons

    main_buts = [
        Button(10, 690, 150, 70, "Leaderboards", font_28),
        Button(10, 610, 150, 70, "Pause", font_40),
        Button(900, 160, 100, 50, "Details", font_28)
    ]

    dice_but_click = False  #Booleans tracking whether the roll dice, end turn and but property buttons have been clicked yet this turn
    turn_but_click = False
    buy_but_click = False
    mort_but_click = False
    buy_upgrade_but_click = False
    sell_upgrade_but_click = False
    leave_bogside_but_click = False
    use_card_but_click = False

    msgBox = None
    exitOnBoxClose = False
    advanceOnBoxClose = False
    fps = 10  #Used to determine the waiting between updating the game display

    main_screen_running = True
    while main_screen_running:
        for event in pygame.event.get():
            for but in main_buts:
                but.handle_input_event(event)

            if msgBox != None:
                msgBox.handle_input_event(event)
                if exitOnBoxClose and msgBox.should_exit:
                    main_screen_running = False
                    gotoScreen = -1
                if advanceOnBoxClose and msgBox.should_exit:
                    mainGame.advancePlayer()
                    mainGame.prop_thumbs = pygame.transform.smoothscale(
                        CreateThumbs(mainGame.board,
                                     mainGame.cur_player), [385, 170]
                    )  #Generate thumbnails for new player (here so it is only done when the player changes, not every frame change)
                    advanceOnBoxClose = False
                if msgBox.should_exit == False:
                    break
            if event.type == pygame.QUIT:
                main_screen_running = False
                gotoScreen = -1
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:  #Escape key exits the game
                    main_screen_running = False
                    gotoScreen = -1
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  #Left mouse button
                    mouse_pos = event.pos  #Position of the cursor when nouse was clicked
                    if buy_prop_button.collidepoint(mouse_pos):
                        if mainGame.getCurProp(
                        ).prop_owner == -1:  #Property is unowned
                            buy_but_click = True
                        elif mainGame.getCurProp(
                        ).prop_owner == mainGame.cur_player:  #If owned by current player, it may be mortgaged
                            mort_but_click = True
                    if roll_dice_button.collidepoint(mouse_pos):
                        if mainGame.controller.card_used == False:
                            use_card_but_click = True  #Roll dice button was clicked
                        elif mainGame.controller.player_rolled == False:
                            dice_but_click = True  #End turn button was clicked
                        else:
                            turn_but_click = True  #Button to apply card effects was clicked
                    if in_jail_button.collidepoint(
                            mouse_pos
                    ):  #Button to pay £50 to get out of bogside was clicked
                        leave_bogside_but_click = True
                    if buy_upgrade_button.collidepoint(mouse_pos):
                        buy_upgrade_but_click = True
                    if sell_upgrade_button.collidepoint(mouse_pos):
                        sell_upgrade_but_click = True

        #Clear screen and display main board
        displayScreenAndBoard(screen, mainGame.board.board_img)

        if dice_but_click:  #If Roll Dice button was clicked
            #Roll dice, move the piece accordingly, and display the dice rolls
            mainGame.getDie(0).roll()
            mainGame.getDie(1).roll()

            dice_total = mainGame.getDiceTotal()

            if mainGame.getCurPlayer().player_inJail == False:
                mainGame.getCurPlayer().movePlayer(dice_total, mainGame.board)
            elif mainGame.getDie(0).cur_score == mainGame.getDie(
                    1
            ).cur_score:  #Doubles rolled, so player gets out of bogside
                mainGame.getCurPlayer().leaveJail()
                mainGame.getCurPlayer().movePlayer(dice_total, mainGame.board)
            #Player does not move otherwise, as they must be lost in bogside

            #Generate the dice images
            mainGame.controller.roll_img1 = pygame.transform.smoothscale(
                mainGame.getDie(0).getImg(), [70, 70])
            mainGame.controller.roll_img2 = pygame.transform.smoothscale(
                mainGame.getDie(1).getImg(), [70, 70])

            if mainGame.getDie(0).cur_score != mainGame.getDie(
                    1
            ).cur_score:  #If a double has not been rolled (rolling a double gives the player another turn)
                mainGame.controller.player_rolled = True  #So player only gets another turn if they rolled doubles
            mainGame.controller.may_buy = True

            if mainGame.getDie(0).cur_score == mainGame.getDie(1).cur_score:
                mainGame.controller.cur_doubles += 1

            if mainGame.controller.cur_doubles >= 3:  #If player rolls 3 consecutive doubles, they go to Bogside
                mainGame.sendCurPlayerToBog()
                mainGame.controller.player_rolled = True  #Will not get to roll again

            #Determine rent if applicable
            mainGame.controller.turn_rent = mainGame.determineRent()

            if mainGame.controller.turn_rent != 0:
                mainGame.getCurPlayer().spendMoney(
                    mainGame.controller.turn_rent
                )  #Decrease the player's money and credit the owner of the property that amount
                if mainGame.getCurProp().prop_type != Prop_Type.PAYMENT:
                    mainGame.getPlayer(
                        mainGame.getCurProp().prop_owner).addMoney(
                            mainGame.controller.turn_rent)

            #If the current space returns a card
            if mainGame.getCurProp().prop_type == Prop_Type.POT_LUCK:
                mainGame.controller.cur_card = mainGame.board.PL_Deck.getNextCard(
                )
            elif mainGame.getCurProp().prop_type == Prop_Type.COUNCIL_CHEST:
                mainGame.controller.cur_card = mainGame.board.CC_Deck.getNextCard(
                )

            #If card will have just been returned, render the text that will show its effects
            if mainGame.getCurProp(
            ).prop_type == Prop_Type.POT_LUCK or mainGame.getCurProp(
            ).prop_type == Prop_Type.COUNCIL_CHEST:  #Card will have been returned
                mainGame.controller.card_effs, mainGame.controller.card_texts = renderCardTexts(
                    font_28, mainGame.controller.cur_card)
                mainGame.controller.card_used = False

            #If the player lands on the 'Go To Bogside' space
            if mainGame.getCurProp().prop_type == Prop_Type.GO_TO_BOGSIDE:
                mainGame.sendCurPlayerToBog()

        #Display whose turn it is, how much money this player has, and show their property overview
        displayWhoseTurn(screen, font_28, mainGame.getCurPlayer())
        displayPlayerMoney(screen, font_28,
                           mainGame.getCurPlayer().player_money)
        displayPlayerToken(screen, mainGame.getCurPlayer())
        displayPropThumbs(screen, mainGame.prop_thumbs, 610, 50)
        displayDiceScore(screen, mainGame.controller.roll_img1,
                         mainGame.controller.roll_img2)

        #Show each of the player's pieces at its requisite position on the board
        displayPieces(screen, mainGame)

        #Show the Roll Dice/End Turn button, and the appropriate caption
        if mainGame.controller.card_used == False:
            displayButtonRect(screen, roll_dice_button, (100, 100, 100),
                              font_40, 'Use Card', (0, 0, 0))
        elif mainGame.controller.player_rolled == False:
            displayButtonRect(screen, roll_dice_button, (100, 100, 100),
                              font_40, 'Roll Dice', (0, 0, 0))
        else:
            displayButtonRect(screen, roll_dice_button, (100, 100, 100),
                              font_40, 'End Turn', (0, 0, 0))

        if mainGame.getCurPlayer().player_inJail and mainGame.getCurPlayer(
        ).player_hasBogMap:  #If player is lost in bogside, but they have the equivelant of a "Get out of Jail Free" card
            displayButtonRect(screen, in_jail_button, (100, 100, 100), font_28,
                              'Use Map', (0, 0, 0))
        elif mainGame.getCurPlayer().player_inJail:  #Don't have card
            displayButtonRect(screen, in_jail_button, (100, 100, 100), font_28,
                              'Buy Map (£50)', (0, 0, 0))

        #Display title deed for property currently on
        if mainGame.getCurProp(
        ).prop_type == Prop_Type.NORMAL or mainGame.getCurProp(
        ).prop_type == Prop_Type.SCHOOL or mainGame.getCurProp(
        ).prop_type == Prop_Type.STATION:  #If property actually will have a title deed to display
            title_deed = pygame.transform.smoothscale(
                mainGame.getCurProp().getTitleDeed(), [270, 400])
            screen.blit(title_deed, [665, 230])

            if mainGame.getCurProp().prop_type == Prop_Type.NORMAL:
                #Normal properties are the only ones that can have Council Houses and Tower Blocks on them
                displayUpgrades(screen, CH_img, TB_img, mainGame.getCurProp(),
                                font_40)

                if mainGame.getCurProp().prop_owner == mainGame.cur_player:
                    if mainGame.board.wholeGroupOwned(
                            mainGame.cur_player,
                            mainGame.getCurPlayer().player_pos
                    ):  #May only be bought if the property is owned by the current player and the entire colour group is owned

                        if mainGame.getCurProp().C_Houses < 4:
                            displayButtonRect(screen, buy_upgrade_button,
                                              (100, 100, 100), font_20,
                                              'Buy Council House', (0, 0, 0))
                        elif mainGame.getCurProp().T_Blocks == 0:
                            displayButtonRect(screen, buy_upgrade_button,
                                              (100, 100, 100), font_20,
                                              'Buy Tower Block', (0, 0, 0))

                        if mainGame.getCurProp().T_Blocks > 0:
                            displayButtonRect(screen, sell_upgrade_button,
                                              (100, 100, 100), font_20,
                                              'Sell Tower Block', (0, 0, 0))
                        elif mainGame.getCurProp().C_Houses > 0:
                            displayButtonRect(screen, sell_upgrade_button,
                                              (100, 100, 100), font_20,
                                              'Sell Council House', (0, 0, 0))

            if mainGame.getCurProp(
            ).prop_type == Prop_Type.NORMAL or mainGame.getCurProp(
            ).prop_type == Prop_Type.SCHOOL or mainGame.getCurProp(
            ).prop_type == Prop_Type.STATION:
                if mainGame.getCurProp().prop_owner == mainGame.cur_player:
                    #Display relevant button for mortgaging or unmortgaging a property
                    if mainGame.getCurProp(
                    ).mortgage_status:  #Property is mortgaged
                        displayButtonRect(screen, buy_prop_button,
                                          (100, 100, 100), font_28,
                                          'Unmortgage Property', (0, 0, 0))
                    else:
                        displayButtonRect(screen, buy_prop_button,
                                          (100, 100, 100), font_28,
                                          'Mortgage Property', (0, 0, 0))

            if mainGame.getCurProp(
            ).prop_owner == -1 and mainGame.controller.may_buy:
                #Give player the opportunity to buy property (since it is available and they have began their turn by rolling the dice)
                displayButtonRect(screen, buy_prop_button, (100, 100, 100),
                                  font_40, 'Buy Property', (0, 0, 0))
            elif mainGame.getCurProp().prop_owner != -1:
                #Property is owned by a player so display information pertaining to the owning of said property by this aforementioned player
                displayOwner(
                    screen, font_28,
                    mainGame.getPlayer(mainGame.getCurProp().prop_owner))
        else:
            if mainGame.getCurProp(
            ).prop_type != Prop_Type.LOST_IN_BOGSIDE:  #Will work perfectly normally for all properties but the Lost In Bogside square
                tit_str = mainGame.getCurProp().prop_title
            elif mainGame.getCurPlayer(
            ).player_inJail:  #If Player is actually 'in jail'
                tit_str = "Lost In Bogside"
            else:
                tit_str = "On The Paths"  #In the same space but can move freely (i.e. 'not in jail')

            tit_text = font_40.render(
                tit_str, True, (0, 0, 0)
            )  #Render the property name as it does not have a title deed that can do so
            t_width, t_height = font_40.size(tit_str)
            screen.blit(tit_text, [(400 - t_width) / 2 + 600, 220])

        if mainGame.getCurProp(
        ).prop_type == Prop_Type.NORMAL or mainGame.getCurProp(
        ).prop_type == Prop_Type.SCHOOL or mainGame.getCurProp(
        ).prop_type == Prop_Type.STATION or mainGame.getCurProp(
        ).prop_type == Prop_Type.PAYMENT:  #If incurs a charge
            try:
                if mainGame.controller.turn_rent != 0:  #If rent has actually been charged then the player is told they themselves have paid whatever amount
                    displayPaidRent(screen, font_28,
                                    mainGame.controller.turn_rent)
                elif mainGame.getCurProp(
                ).prop_owner == mainGame.cur_player and mainGame.getCurProp(
                ).prop_type == Prop_Type.NORMAL:  #If property is owned by the current player and NORMAL (since other properties depend on those owned and dice rolls
                    if mainGame.board.wholeGroupOwned(
                            mainGame.getCurProp().prop_owner,
                            mainGame.getCurPlayer().player_pos
                    ) and mainGame.getCurProp().C_Houses == 0:
                        displayRent(screen, font_28,
                                    mainGame.getCurProp().getRent() * 2)
                    else:
                        displayRent(screen, font_28,
                                    mainGame.getCurProp().getRent())
            except AttributeError:  #Prevents errors as PAYMENT property has no owner but changes variable turn_rent
                pass

        if mainGame.getCurProp(
        ).prop_type == Prop_Type.POT_LUCK or mainGame.getCurProp(
        ).prop_type == Prop_Type.COUNCIL_CHEST:
            if mainGame.controller.cur_card != None:  #If player was already on one of these places when their turn begins, cur_card and card_texts will be None object; this condition prevents an error when the following code thinks that it is
                displayCard(screen, mainGame.controller.cur_card)
                t_count = 0
                for cur_text in mainGame.controller.card_texts:
                    w, h = cur_text.get_size()
                    screen.blit(cur_text,
                                [(400 - w) / 2 + 600, 480 + t_count * 25])
                    t_count += 1

        if turn_but_click:  #End Turn button
            #If player could sell some things to avoid going bankrupt
            cont = True
            if mainGame.getCurPlayer().player_money < 0 and (
                    getObtainMon(mainGame.board, mainGame.cur_player) +
                    mainGame.getCurPlayer().player_money) >= 0:
                msgBox = MessageBox(
                    screen,
                    'You need to ensure your money is 0 or above before you can finish your turn. Please sell or mortgage some assets to continue.',
                    'Not Enough Money')
                cont = False
            elif (
                    getObtainMon(mainGame.board, mainGame.cur_player) +
                    mainGame.getCurPlayer().player_money
            ) < 0:  #If it is impossible for a player to not end up in debt, they go bankrupt
                mainGame.getCurPlayer().deactivate(
                )  #Remove player from the game
                cont = False
                for counter in range(mainGame.board.max_pos):
                    if mainGame.board.getProp(
                            counter).prop_type == Prop_Type.NORMAL:
                        if mainGame.board.getProp(
                                counter).prop_owner == mainGame.cur_player:
                            mainGame.board.getProp(counter).p_owner = -1
                            mainGame.board.getProp(
                                counter).mortgage_status = False
                            mainGame.board.getProp(counter).C_Houses = 0
                            mainGame.board.getProp(counter).T_Blocks = 0
                    if mainGame.board.getProp(
                            counter
                    ).prop_type == Prop_Type.SCHOOL or mainGame.board.getProp(
                            counter).prop_type == Prop_Type.STATION:
                        if mainGame.board.getProp(
                                counter).prop_owner == mainGame.cur_player:
                            mainGame.board.getProp(counter).p_owner = -1
                            mainGame.board.getProp(
                                counter).mortgage_status = False

                msgBox = MessageBox(
                    screen,
                    'Unfortunately, this utopian capitalist world has ceased to be utopian for you: you have gone bankrupt and are no longer in the game.',
                    'Game Over')
                advanceOnBoxClose = True

            #Next player's turn now (if the previous player has no more to do
            if cont:
                mainGame.advancePlayer()
                mainGame.prop_thumbs = pygame.transform.smoothscale(
                    CreateThumbs(mainGame.board,
                                 mainGame.cur_player), [385, 170]
                )  #Generate thumbnails for new player (here so it is only done when the player changes, not every frame change)

            if mainGame.countActivePlayers() < 2:
                mainGame.advancePlayer()
                msgBox = MessageBox(
                    screen,
                    mainGame.getCurPlayer().player_name + ' has won the game.',
                    'Game Over')
                exitOnBoxClose = True

        #Button for buying a property has been clicked
        if buy_but_click and (
                mainGame.getCurProp().prop_type == Prop_Type.NORMAL
                or mainGame.getCurProp().prop_type == Prop_Type.SCHOOL
                or mainGame.getCurProp().prop_type == Prop_Type.STATION
        ):  #Final check that the property can actually be owned
            #Player wished to buy property
            if mainGame.getCurProp(
            ).prop_owner == -1:  #Property is unowned, hence can actually be bought
                if mainGame.getCurPlayer().player_money >= mainGame.getCurProp(
                ).cost:
                    #Player has enough money
                    mainGame.getCurPlayer().spendMoney(mainGame.getCurProp(
                    ).cost)  #Decrease the player's bank balance accordingly
                    mainGame.getCurProp().buyProperty(
                        mainGame.cur_player
                    )  #Change the property's status to track the new ownership
                    mainGame.prop_thumbs = pygame.transform.smoothscale(
                        CreateThumbs(mainGame.board,
                                     mainGame.cur_player), [385, 170]
                    )  #Update title deed thumbnails to reflect newly purchased properties

        #Button to apply the effects of a Pot Luck or Council Chest card
        if use_card_but_click and mainGame.controller.cur_card != None:  #Check there is a card to work with
            mainGame.controller.card_used = True
            mainGame.applyCardEffects()  #Apply card effects

        #All of the following may only be done if the current player owns the property
        #Button for mortgaging or unmortgaging a property
        if mort_but_click and (
                mainGame.getCurProp().prop_type == Prop_Type.NORMAL
                or mainGame.getCurProp().prop_type == Prop_Type.SCHOOL
                or mainGame.getCurProp().prop_type == Prop_Type.STATION
        ):  #Final check that the property is one that may be mortgaged
            if mainGame.getCurProp(
            ).prop_owner == mainGame.cur_player and mainGame.getCurProp(
            ).mortgage_status == False:  #Property must be owned by the current player and not already mortgaged
                mainGame.getCurProp(
                ).mortgage_status = True  #Property is now mortgaged
                mainGame.getCurPlayer().addMoney(
                    int(mainGame.getCurProp().mortgage_val))
            elif mainGame.getCurProp(
            ).prop_owner == mainGame.cur_player and mainGame.getCurProp(
            ).mortgage_status:  #Property must be owned by the current player and is mortgaged
                if mainGame.getCurPlayer().player_money >= mainGame.getCurProp(
                ).mortgage_val * 1.2:  #Player has sufficient money to unmortgage the property (twice the money gotten by mortgaging it)
                    mainGame.getCurProp(
                    ).mortgage_status = False  #Property is no longer in a state of being mortgaged
                    mainGame.getCurPlayer().spendMoney(
                        int(mainGame.getCurProp().mortgage_val * 1.2)
                    )  #Decrease player's money by the cost of unmortgaging the property

        #Button for buying a Council House or Tower Block
        if buy_upgrade_but_click and mainGame.getCurProp(
        ).prop_type == Prop_Type.NORMAL and mainGame.board.wholeGroupOwned(
                mainGame.cur_player,
                mainGame.getCurPlayer().player_pos
        ):  #Player wishes to upgrade the property and said upgrade can actually be purchaed
            if mainGame.getCurProp(
            ).prop_owner == mainGame.cur_player:  #May only be bought if the property is owned by the current player
                if mainGame.getCurProp(
                ).C_Houses < 4:  #Fewer than 4  Council Houses, so these are the next upgrade to be bought
                    if mainGame.getCurPlayer().player_money >= (
                            mainGame.getCurProp().CH_cost *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos)
                    ):  #Player actually has enough money to buy the Council House upgrade
                        mainGame.board.buyCHGroup(
                            mainGame.cur_player,
                            mainGame.getCurPlayer().player_pos
                        )  #Buy the Council Houses for the whole group
                        mainGame.getCurPlayer().spendMoney(
                            mainGame.getCurProp().CH_cost *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos)
                        )  #Decrease the player's money by the cost of a Council House for however many properties are in the group
                elif mainGame.getCurProp(
                ).C_Houses == 4 and mainGame.getCurProp(
                ).T_Blocks == 0:  #4 Council Houses and no Tower Blocks, so Tower Block can be bought
                    if mainGame.getCurPlayer().player_money >= (
                            mainGame.getCurProp().TB_cost *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos)
                    ):  #Player actually has enough money to buy the Tower Block upgrade
                        mainGame.board.buyTBGroup(
                            mainGame.cur_player,
                            mainGame.getCurPlayer().player_pos
                        )  #Buy the Council Houses for the whole group
                        mainGame.getCurPlayer().spendMoney(
                            mainGame.getCurProp().TB_cost *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos)
                        )  #Decrease the player's money by the cost of a Tower Block for however many properties are in the group

        #Button for selling a Council House or Tower Block
        if sell_upgrade_but_click and mainGame.getCurProp(
        ).prop_type == Prop_Type.NORMAL and mainGame.board.wholeGroupOwned(
                mainGame.cur_player,
                mainGame.getCurPlayer().player_pos
        ):  #Player wishes to upgrade the property and said upgrade can actually be purchaed
            if mainGame.getCurProp(
            ).prop_owner == mainGame.cur_player:  #May only be bought if the property is owned by the current player
                if mainGame.getCurProp(
                ).T_Blocks > 0:  #Property has a Tower Block that can be sold
                    mainGame.board.sellTBGroup(
                        mainGame.cur_player,
                        mainGame.getCurPlayer().player_pos
                    )  #Sell the Tower Blocks for the whole group
                    mainGame.getCurPlayer().addMoney(
                        int(mainGame.getCurProp().TB_cost / 2 *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos))
                    )  #Increase the player's money by half of what the upgrades were bought for
                elif mainGame.getCurProp(
                ).C_Houses > 0:  #No Tower Blocks, buy some Council Houses which can instead be sold
                    mainGame.board.sellCHGroup(
                        mainGame.cur_player,
                        mainGame.getCurPlayer().player_pos
                    )  #Sell the Council Houses for the whole group
                    mainGame.getCurPlayer().addMoney(
                        int(mainGame.getCurProp().CH_cost / 2 *
                            mainGame.board.countGroupSize(
                                mainGame.cur_player,
                                mainGame.getCurPlayer().player_pos))
                    )  #Increase the player's money by half of what the upgrades were bought for

        #Button to buy a map out of Bogside for £50
        if leave_bogside_but_click and (
                mainGame.getCurPlayer().player_money >= 50
                or mainGame.getCurPlayer().player_hasBogMap
        ) and mainGame.getCurPlayer().player_inJail:
            mainGame.getCurPlayer().leaveJail()
            if mainGame.getCurPlayer().player_hasBogMap == False:
                mainGame.getCurPlayer().spendMoney(50)
            else:
                mainGame.getCurPlayer().useBogMap()

        if msgBox != None:
            msgBox.update()
            if msgBox.should_exit == False:
                msgBox.draw(screen)

        if main_buts[2].clicked():  #Details
            main_screen_running = False
            gotoScreen = 2
        if main_buts[0].clicked():  #Leaderboards
            main_screen_running = False
            gotoScreen = 3
        if main_buts[1].clicked():  #Pause
            main_screen_running = False
            gotoScreen = 4

        for but in main_buts:
            but.render(screen)

        #Reset button booleans so that effects of clicking buttons do not happen more than once
        dice_but_click = False
        turn_but_click = False
        buy_but_click = False
        mort_but_click = False
        buy_upgrade_but_click = False
        sell_upgrade_but_click = False
        leave_bogside_but_click = False
        use_card_but_click = False
        clock.tick(
            fps
        )  #10 fps currently, but could easily be changed to update more or less often
        pygame.display.flip(
        )  #Refresh display from a pygame perspective, to reflect the screen.blit()s
    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
Esempio n. 3
0
import pygame
from msgbox import MessageBox

pygame.init()
screen = pygame.display.set_mode((750, 500))
clock = pygame.time.Clock()

message = 'The quick brown fox jumps over the lazy dog, but that does not tell us anything about what the cat did \n This starts a new line'
title = 'This is a title'

messageBox = MessageBox(screen, message, title)

running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        messageBox.handle_input_event(event)
        if messageBox.should_exit == False:  #Prevents any other actions taking place on screen while the messagebox is visible.
            break
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0, 0, 0))
    messageBox.update()
    if messageBox.should_exit == False:
        messageBox.draw(screen)
    pygame.display.flip()

pygame.quit()
Esempio n. 4
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
def Leaderboards(mainGame, screen, clock):
    font_48 = pygame.font.SysFont('Arial', 48) #Font for title and name
    font_40 = pygame.font.SysFont('Arial', 40) #Font for the "?" and Exit buttons
    font_28 = pygame.font.SysFont('Arial', 28) #Font for actual leaderboards and attributes
    font_32b = pygame.font.SysFont('Arial', 32, True) #Font for column headings

    lead_arr = setup2DArray(mainGame)

    #Arrow images to be displayed on the buttons that are used by the player for choosing which column to sort on and whether to sort ascending or descending
    arrow_both = pygame.image.load("img/Arrows/both.png")
    arrow_up = pygame.image.load("img/Arrows/up.png")
    arrow_down = pygame.image.load("img/Arrows/down.png")
    
    #Initialise button array
    sort_buts = [pygame.Rect(360,80,40,40), pygame.Rect(610,80,40,40), pygame.Rect(940,80,40,40)]

    leader_buts = [Button(880, 10, 120, 50, 'Exit', font_40),
                   Button(819, 10, 50, 50, '?', font_40)]

    msgBox = MessageBox(screen, 'Total Money measures simply how much money each player has in the Bank. \n Total Assets counts the values of all owned properties, upgrades, etc. based on how much was paid for them initially. \n Obtainable Money is how much money each player could get if they were to sell off all of their properties and the like.', 'Leaderboards: Explained')
    msgBox.should_exit = True
    
    tit_text = font_48.render('Viewing Leaderboards:', True, (0,0,0)) #Render title at top left of screen
    head_1 = font_32b.render('Player', True, (0,0,0))
    head_2 = font_32b.render('Total Money', True, (0,0,0))
    head_3 = font_32b.render('Total Assets', True, (0,0,0))
    head_4 = font_32b.render('Obtainable Money', True, (0,0,0))
    mon_text = font_48.render(mainGame.getCurPlayer().player_name, True, (0,0,0)) #Render player money on screen
    f_width, f_height = font_48.size(mainGame.getCurPlayer().player_name)

    y_top = 120 #First y co-ordinate for a row of details
    y_space = 40 #Co-ordinate spacing between rows
    
    fps = 10
    sort_column = 1
    sort_asc = False
    sort_but_click = -1
    lead_arr = quickSort(lead_arr, 0, lead_arr.shape[0]-1, sort_column, sort_asc)
    leaderboards_running = True
    while leaderboards_running: #Main loop for this part of the program
        for event in pygame.event.get():
            for but in leader_buts:
                but.handle_input_event(event)

            msgBox.handle_input_event(event)
            if msgBox.should_exit == False:
                break
            if event.type == pygame.QUIT:
                leaderboards_running = False
                gotoScreen = -1
            if event.type == pygame.KEYDOWN: #If any key pressed
                if event.key == pygame.K_ESCAPE: #Escape key exits the game
                    leaderboards_running = False
                    gotoScreen = -1
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1: #Left mouse button
                    mouse_pos = event.pos #Position of the cursor when nouse was clicked
                    for counter in range(3): #Cycle through all the arrays of buttons to see if any have been clicked
                        if sort_buts[counter].collidepoint(mouse_pos):
                            sort_but_click = counter

        screen.fill((255,255,255))
        screen.blit(tit_text, [10, 10])
        screen.blit(mon_text, [(770-f_width), 10])
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(10,70,1000,700), 10) #Draw black rectangle surrounding the property data

        #Display each of the column headings (bold text)
        screen.blit(head_1, [30, 80])
        screen.blit(head_2, [200, 80])
        screen.blit(head_3, [450, 80])
        screen.blit(head_4, [700, 80])

        for counter in range(3):
            displayButtonRect(screen, sort_buts[counter], (100, 100, 100), font_28, '', (0, 0, 0))

            if counter == sort_column-1:
                if sort_asc:
                    screen.blit(arrow_down, [sort_buts[counter].x, sort_buts[counter].y])
                else:
                    screen.blit(arrow_up, [sort_buts[counter].x, sort_buts[counter].y])
            else:
                screen.blit(arrow_both, [sort_buts[counter].x, sort_buts[counter].y])

        y_pos = y_top #Y co-ordinate of the first row of data
        for counter in range(lead_arr.shape[0]):
            text_1 = font_28.render(mainGame.getPlayer(lead_arr[counter][0]).player_name, True, (0,0,0)) #Property name/title
            screen.blit(text_1, [30, y_pos])
            text_2 = font_28.render(str(lead_arr[counter][1]), True, (0,0,0)) 
            screen.blit(text_2, [200, y_pos])
            text_3 = font_28.render(str(lead_arr[counter][2]), True, (0,0,0)) 
            screen.blit(text_3, [450, y_pos])
            text_4 = font_28.render(str(lead_arr[counter][3]), True, (0,0,0))
            screen.blit(text_4, [700, y_pos])

            y_pos += y_space #Increment y co-ordinate variable by the difference in co-ordinates between each row, as already defined

        if sort_but_click != -1:
            if sort_column == sort_but_click+1:
                sort_asc = not sort_asc
            else:
                sort_column = sort_but_click + 1
                sort_asc = False

            lead_arr = quickSort(lead_arr, 0, lead_arr.shape[0]-1, sort_column, sort_asc)

        if leader_buts[0].clicked():
            leaderboards_running = False
            gotoScreen = 1

        if leader_buts[1].clicked():
            msgBox.should_exit = False

        msgBox.update()
        if msgBox.should_exit == False:
            msgBox.draw(screen)

        for but in leader_buts:
            but.render(screen)

        sort_but_click = -1
        clock.tick(fps) #10 fps currently, but could easily be changed to update more or less often
        pygame.display.flip() #Refresh display from a pygame perspective, to reflect the screen.blit()s
    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