コード例 #1
0
ファイル: match.py プロジェクト: gasnew/fjspace
class Match:
    # -- NECESSARY CONSTANTS --
    ENCOURAGEMENTS = [
        "Nice!", "Better than I expected...", "[REDACTED]", "Congratulations!",
        "Have a slice of 3.1415926535897932384626.", "[VICTORY MESSAGE]",
        "Wow!", "Great, kid! Don't get cocky.", "Gnarly!", "I love you."
    ]
    CONSOLATIONS = [
        "The other guy's cheating!", "You've got red on you!",
        "'Tis but a scratch!", "Help, I'm trapped in a universe factory.",
        "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness",
        "I know.", "Not like this...", "Huh?", "Not my tempo.",
        "Don't grumble; give a whistle!", "At least you're just practicing."
    ]

    def __init__(self, AGREE_TIME, WIN_TIME, COOLDOWN_TIME, STALE_TIME,
                 TOTAL_TIME, FAILURE_TIME, NUM_WINS, keys, p_list_rect,
                 scoreboard_rect, top_rect, top_rect_left, top_rect_right,
                 game_rect, bottom_rect, shadow_dist, sys_font):
        # -- IMPORTS --
        self.keys = keys
        self.top_rect_left = top_rect_left
        self.top_rect_right = top_rect_right
        self.bottom_rect = bottom_rect
        self.AGREE_TIME = AGREE_TIME
        self.NUM_WINS = NUM_WINS
        self.shadow_dist = shadow_dist

        # -- MATCH INFO --
        self.match_num = 0
        self.big_f_agree = self.big_j_agree = 0
        self.f_wins = self.j_wins = 0
        self.score_streak = 0

        # -- NECESSARY CLASSES --
        self.p_list = PlayerList(p_list_rect, shadow_dist, sys_font)
        self.game = Game(WIN_TIME, COOLDOWN_TIME, STALE_TIME, TOTAL_TIME,
                         FAILURE_TIME, self.keys, game_rect, shadow_dist,
                         sys_font)
        self.wheel = Wheel(game_rect, shadow_dist, sys_font)
        self.hud = Hud(top_rect, bottom_rect, shadow_dist, sys_font)
        self.scoreboard = Scoreboard(scoreboard_rect, shadow_dist, sys_font,
                                     self.p_list)
        self.menu = Menu(p_list_rect, self.keys, shadow_dist, sys_font)
        self.match_state = MatchState(MatchState.PLAYER_LIST,
                                      self.state_response)

        # -- MENU ACTIONS --
        self.menu.add_item(
            "[2]", "PRACTICE MODE", 0.5,
            lambda: self.match_state.set_state(MatchState.PRACTICE_MODE))
        self.menu.add_item(
            "[3]", "RESET MATCHUP", 0.5,
            lambda: self.match_state.set_state(MatchState.NEW_OPPONENT,
                                               same_match=True))
        self.menu.add_item(
            "[4]", "NEXT OPPONENT", 0.5,
            lambda: self.match_state.set_state(MatchState.NEW_OPPONENT,
                                               next=True))
        self.menu.add_item(
            "[5]", "CHANGE PLAYERS", 0.5,
            lambda: self.match_state.set_state(MatchState.PLAYER_LIST))

        # -- RENDERING --
        # bottom bar
        self.f_name_text = TextRenderer(
            sys_font, 2, (top_rect_left.centerx, bottom_rect.centery),
            shadow_dist)
        self.j_name_text = TextRenderer(
            sys_font, 2, (top_rect_right.centerx, bottom_rect.centery),
            shadow_dist)
        self.streak_text = TextRenderer(
            sys_font, 1, (bottom_rect.width * 0.08,
                          bottom_rect.centery + bottom_rect.height * 0.25),
            shadow_dist)

        self.practice_mode_text = TextRenderer(sys_font, 2, bottom_rect.center,
                                               0)
        self.practice_inst_rect = Rect(
            (game_rect.left + game_rect.height * 0.05,
             game_rect.top + game_rect.height * 0.05),
            (game_rect.width, game_rect.height * 0.25))
        self.practice_inst_0 = ShadowedPressable.make_pressable_key(
            "1. Hold your key to build your bar.", sys_font, 1,
            GameColor.Pink)[0].convert_alpha()
        self.practice_inst_1 = ShadowedPressable.make_pressable_key(
            "2. Press [SPACE] to reset moving bars.", sys_font, 1,
            GameColor.Cyan)[0].convert_alpha()
        self.practice_inst_2 = ShadowedPressable.make_pressable_key(
            "3. Build the biggest bar to win!", sys_font, 1,
            GameColor.Yellow)[0].convert_alpha()

        # vs
        self.new_match_text = TextRenderer(
            sys_font, 4,
            (game_rect.centerx, game_rect.top + game_rect.height / 6),
            shadow_dist, GameColor.White)

        self.vs_left_bar = Rect((0, game_rect.y + game_rect.height / 3),
                                (top_rect_left.width, game_rect.height / 5))
        self.vs_right_bar = Rect(
            (game_rect.centerx, self.vs_left_bar.bottom),
            (self.vs_left_bar.width, self.vs_left_bar.height))
        vs_par_width = game_rect.height / 7
        self.vs_parallelogram = ((game_rect.centerx, self.vs_left_bar.top),
                                 (game_rect.centerx - vs_par_width,
                                  self.vs_right_bar.bottom),
                                 (game_rect.centerx, self.vs_right_bar.bottom),
                                 (game_rect.centerx + vs_par_width,
                                  self.vs_left_bar.top))
        self.f_name_big_text = TextRenderer(
            sys_font, 4, (top_rect_left.centerx + shadow_dist,
                          self.vs_left_bar.centery + shadow_dist), shadow_dist,
            GameColor.F.Dark)
        self.j_name_big_text = TextRenderer(
            sys_font, 4, (top_rect_right.centerx + shadow_dist,
                          self.vs_right_bar.centery + shadow_dist),
            shadow_dist, GameColor.J.Dark)
        self.vs_text = TextRenderer(sys_font, 2,
                                    (game_rect.centerx + shadow_dist,
                                     self.vs_left_bar.bottom + shadow_dist),
                                    shadow_dist)
        self.vs_left_bar.move_ip((top_rect_left.width, 0))

        big_f, big_f_shadow = ShadowedPressable.make_pressable_key(
            "[F]", sys_font, 4)
        self.big_f = ShadowedPressable(
            big_f.convert_alpha(), big_f_shadow,
            (top_rect_left.centerx, game_rect.top + game_rect.height * 0.85),
            shadow_dist)
        big_j, big_j_shadow = ShadowedPressable.make_pressable_key(
            "[J]", sys_font, 4)
        self.big_j = ShadowedPressable(
            big_j.convert_alpha(), big_j_shadow,
            (top_rect_right.centerx, game_rect.top + game_rect.height * 0.85),
            shadow_dist)

        # counter
        self.counter = TextRenderer(sys_font, 4, game_rect.center, shadow_dist)
        self.ready_text = TextRenderer(
            sys_font, 2,
            (game_rect.centerx, game_rect.top + game_rect.height * 0.35),
            shadow_dist)

        # win rects
        win_rect_size = top_rect.height * 0.15
        self.win_rect = Rect(top_rect.centerx - win_rect_size / 2,
                             win_rect_size, win_rect_size, win_rect_size)
        self.win_rect_shadows = [
            self.win_rect.move(self.win_rect.width * 2 * idx, 0)
            for idx in [-3, -2, -1, 1, 2, 3]
        ]
        self.f_win_rects = []
        self.j_win_rects = []

        # win text
        self.f_win_loss_text = TextRenderer(
            sys_font, 4,
            (top_rect_left.centerx, game_rect.top + game_rect.height * 0.35),
            shadow_dist)
        self.j_win_loss_text = TextRenderer(
            sys_font, 4,
            (top_rect_right.centerx, game_rect.top + game_rect.height * 0.35),
            shadow_dist)
        self.f_plus_minus_text = TextRenderer(
            sys_font, 4,
            (top_rect_left.centerx, game_rect.top + game_rect.height * 0.65),
            shadow_dist)
        self.j_plus_minus_text = TextRenderer(
            sys_font, 4,
            (top_rect_right.centerx, game_rect.top + game_rect.height * 0.65),
            shadow_dist)
        self.f_enc_cons_text = TextRenderer(
            sys_font, 1,
            (top_rect_left.centerx, game_rect.top + game_rect.height * 0.5),
            shadow_dist / 8)
        self.j_enc_cons_text = TextRenderer(
            sys_font, 1,
            (top_rect_right.centerx, game_rect.top + game_rect.height * 0.5),
            shadow_dist / 8)

        # tweens
        self.vs_bar_w = Tweener(
            {
                "retracted": 0,
                "extended": top_rect_left.width
            }, "retracted")
        self.f_name_big_x = Tweener(
            {
                "out": 0,
                "in": self.f_name_big_text.center[0]
            }, "out")
        self.j_name_big_x = Tweener(
            {
                "out": game_rect.right,
                "in": self.j_name_big_text.center[0]
            }, "out")

        # -- SOUND --
        self.vs_sound = pygame.mixer.Sound("SFX/VS.wav")
        self.timer_sound = pygame.mixer.Sound("SFX/beep.wav")
        self.begin_sound = pygame.mixer.Sound("SFX/begin_game.wav")
        self.climax_sound = pygame.mixer.Sound("SFX/climax.wav")
        self.victory_sounds = [
            pygame.mixer.Sound("SFX/vic{0}.wav".format(i)) for i in range(3)
        ]
        self.win_sound = pygame.mixer.Sound("SFX/win.wav")

        self.reset()

    def reset(self):
        self.match_num = 0
        self.big_f_agree = self.big_j_agree = 0
        self.f_wins = self.j_wins = 0
        self.score_streak = 0

        self.winner = ""
        self.hold_wheel_render = False

        self.p_list.focus()
        self.match_state.set_state(MatchState.PLAYER_LIST)

        self.encouragement = ""
        self.consolation = ""

    def state_response(self, state, **kwargs):
        self.p_list.defocus()
        if state not in {MatchState.VICTORY_0, MatchState.VICTORY_1}:
            self.hold_wheel_render = False

        if state == MatchState.PLAYER_LIST:
            self.p_list.focus()
        elif state == MatchState.COUNTDOWN:
            if self.NUM_WINS in {self.f_wins, self.j_wins}:
                self.match_state.set_state(MatchState.WINNER)
                self.f_win_loss_text.color = GameColor.Green if self.winner == "f" else GameColor.Red
                self.j_win_loss_text.color = GameColor.Green if self.winner == "j" else GameColor.Red
                self.f_plus_minus_text.color = GameColor.Green if self.winner == "f" else GameColor.Red
                self.j_plus_minus_text.color = GameColor.Green if self.winner == "j" else GameColor.Red

                if self.winner == "f":
                    self.score_streak += 1
                    self.p_list.pf.score += self.score_streak
                else:
                    self.score_streak = 1
                    self.p_list.pj.score += self.score_streak

                self.win_sound.play()
            else:
                self.game.reset()
                self.begin_sound.play()
                self.timer_sound.play(loops=2)
        elif state == MatchState.NEW_OPPONENT:
            if self.j_wins == self.NUM_WINS:
                self.p_list.swap_players()

            if kwargs.get("next"):
                self.p_list.new_opponent()
            elif kwargs.get("shuffle"):
                self.p_list.shuffle()

            self.p_list.defocus()

            if not kwargs.get("same_match"): self.match_num += 1
            self.big_f_agree = self.big_j_agree = 1
            self.f_wins = self.j_wins = 0
            self.f_win_rects = []
            self.j_win_rects = []

            self.game.reset()

            self.vs_bar_w.set_to("retracted").tween_to("extended", schmaltz=70)
            self.f_name_big_x.set_to("out").tween_to("in", schmaltz=300)
            self.j_name_big_x.set_to("out").tween_to("in", schmaltz=300)

            self.vs_sound.play()
        elif state == MatchState.WHEEL:
            self.wheel.start(self.match_state.state_timer, self.game.perc_f,
                             self.game.perc_j)
            self.hold_wheel_render = True
        elif state == MatchState.VICTORY_0:
            self.climax_sound.play()
        elif state == MatchState.VICTORY_1:
            if self.winner == "f":
                self.f_wins += 1
                self.p_list.pf.wins += 1
                self.p_list.pj.losses += 1

                self.f_win_rects.append(
                    self.win_rect.move(
                        -(self.win_rect.width * 2) * self.f_wins -
                        self.shadow_dist, -self.shadow_dist))
            else:
                self.j_wins += 1
                self.p_list.pj.wins += 1
                self.p_list.pf.losses += 1
                self.j_win_rects.append(
                    self.win_rect.move(
                        (self.win_rect.width * 2) * self.j_wins -
                        self.shadow_dist, -self.shadow_dist))

            random.choice(self.victory_sounds).play()
        elif state == MatchState.PRACTICE_MODE:
            self.game.reset(practice=True)
            self.begin_sound.play()
        elif state == MatchState.PRACTICE_VICTORY:
            self.climax_sound.play()

            self.f_enc_cons_text.color = GameColor.Green if self.winner == "f" else GameColor.Red
            self.j_enc_cons_text.color = GameColor.Green if self.winner == "j" else GameColor.Red
            self.encouragement = random.choice(Match.ENCOURAGEMENTS)
            self.consolation = random.choice(Match.CONSOLATIONS)

    def match_stuff(self, delta_t):
        # player list stuff
        self.p_list.p_list_stuff(self.keys.plus, self.keys.minus)

        # game stuff
        game_over = False
        perc_f = perc_j = 0
        if self.match_state.state in {
                MatchState.RUNNING, MatchState.PRACTICE_MODE
        }:
            game_over, self.winner, perc_f, perc_j = self.game.game_stuff(
                delta_t)

        # wheel stuff
        if self.match_state.state == MatchState.WHEEL or self.hold_wheel_render:
            game_over, self.winner = self.wheel.wheel_stuff(delta_t)

        # hud stuff
        self.hud.hud_stuff()

        # non-hud weird stuff
        if self.match_state.state == MatchState.NEW_OPPONENT:
            if self.keys.f:
                self.big_f_agree = self.big_f_agree - (
                    delta_t /
                    (self.AGREE_TIME * 1000)) if self.big_f_agree > 0 else 0
            else:
                self.big_f_agree = 1

            if self.keys.j:
                self.big_j_agree = self.big_j_agree - (
                    delta_t /
                    (self.AGREE_TIME * 1000)) if self.big_j_agree > 0 else 0
            else:
                self.big_j_agree = 1

        # state stuff
        self.match_state.update(delta_t)
        if self.match_state.state == MatchState.PLAYER_LIST and self.keys.enter:
            self.match_state.set_state(MatchState.NEW_OPPONENT,
                                       shuffle=self.match_num == 0,
                                       same_match=self.match_num != 0)
        elif self.match_state.state == MatchState.NEW_OPPONENT and self.keys.f and self.keys.j and self.big_f_agree == self.big_j_agree == 0:
            self.match_state.set_state(MatchState.COUNTDOWN)
        elif game_over and self.match_state.state in {
                MatchState.RUNNING, MatchState.WHEEL, MatchState.PRACTICE_MODE
        }:
            if self.winner == "stale":
                self.match_state.set_state(MatchState.WHEEL)
            elif self.match_state.state == MatchState.PRACTICE_MODE:
                self.match_state.set_state(MatchState.PRACTICE_VICTORY)
            else:
                self.match_state.set_state(MatchState.VICTORY_0)

        # menu stuff
        if self.keys.nums[49]:
            if not self.menu.in_focus and self.menu.can_focus:
                self.menu.focus()
            self.menu.can_focus = False
        else:
            self.menu.defocus()
            self.menu.can_focus = True

        self.menu.menu_stuff(delta_t)

        # tween stuff
        self.vs_bar_w.tween_stuff(delta_t)
        self.f_name_big_x.tween_stuff(delta_t)
        self.j_name_big_x.tween_stuff(delta_t)

    def render_stuff(self, screen):
        self.game.render_stuff(
            screen,
            render_space=self.match_state.state
            in {MatchState.RUNNING, MatchState.PRACTICE_MODE},
            render_keys=self.match_state.state != MatchState.NEW_OPPONENT,
            disable_keys=self.match_state.state == MatchState.PLAYER_LIST)

        if self.match_state.state == MatchState.COUNTDOWN and self.match_state.state_timer >= 0:
            self.counter.render(screen, str(self.match_state.state_timer)[:4])
            self.ready_text.render(screen, "READY?!?")
        if self.match_state.state == MatchState.WHEEL or self.hold_wheel_render:
            self.wheel.render(screen)

        pygame.draw.rect(screen, GameColor.F.Med, self.top_rect_left)
        pygame.draw.rect(screen, GameColor.J.Med, self.top_rect_right)
        pygame.draw.rect(screen, GameColor.Shadow, self.bottom_rect)

        if self.match_state.state not in {
                MatchState.PRACTICE_MODE, MatchState.PRACTICE_VICTORY
        }:
            self.f_name_text.render(screen, self.p_list.pf.name,
                                    GameColor.lighten(self.p_list.pf.color))
            self.j_name_text.render(screen, self.p_list.pj.name,
                                    GameColor.lighten(self.p_list.pj.color))
            self.streak_text.render(screen,
                                    "STREAK:{0}".format(self.score_streak))
        else:
            self.practice_mode_text.render(screen, "PRACTICE MODE",
                                           GameColor.Gold)

            diff = (self.practice_inst_rect.height -
                    self.practice_inst_0.get_height()) / (3 - 1)
            screen.blit(self.practice_inst_0,
                        self.practice_inst_rect.topleft,
                        special_flags=BLEND_RGB_SUB)
            screen.blit(self.practice_inst_1,
                        (self.practice_inst_rect.left,
                         self.practice_inst_rect.top + diff),
                        special_flags=BLEND_RGB_SUB)
            screen.blit(self.practice_inst_2,
                        (self.practice_inst_rect.left,
                         self.practice_inst_rect.top + 2 * diff),
                        special_flags=BLEND_RGB_SUB)

        if self.match_state.state == MatchState.NEW_OPPONENT:
            self.new_match_text.render(screen,
                                       "MATCH {0}!".format(self.match_num))

            self.vs_left_bar.width = -self.vs_bar_w.tweened_val
            self.vs_right_bar.width = self.vs_bar_w.tweened_val
            pygame.draw.rect(screen, GameColor.White, self.vs_left_bar)
            pygame.draw.rect(screen, GameColor.White, self.vs_right_bar)
            pygame.draw.polygon(screen, GameColor.Shadow,
                                self.vs_parallelogram)

            self.f_name_big_text.center = (self.f_name_big_x.tweened_val,
                                           self.f_name_big_text.center[1])
            self.f_name_big_text.render(screen, self.p_list.pf.name,
                                        self.p_list.pf.color)
            self.j_name_big_text.center = (self.j_name_big_x.tweened_val,
                                           self.j_name_big_text.center[1])
            self.j_name_big_text.render(screen, self.p_list.pj.name,
                                        self.p_list.pj.color)
            self.vs_text.render(screen, "VS")

            self.big_f.down = self.keys.f
            self.big_j.down = self.keys.j
            self.big_f.render(screen, self.big_f_agree)
            self.big_j.render(screen, self.big_j_agree)

        if self.match_state.state == MatchState.WINNER:
            self.f_win_loss_text.render(
                screen, "WIN" if self.winner == "f" else "LOSE")
            self.j_win_loss_text.render(
                screen, "WIN" if self.winner == "j" else "LOSE")

            self.f_plus_minus_text.render(
                screen,
                "+{0}".format(self.score_streak) if self.winner == "f" else "")
            self.j_plus_minus_text.render(screen,
                                          "+1" if self.winner == "j" else "")

        if self.match_state.state not in {
                MatchState.PRACTICE_MODE, MatchState.PRACTICE_VICTORY
        }:
            for rect in self.win_rect_shadows:
                pygame.draw.rect(screen, GameColor.Shadow, rect)
            for rect in self.f_win_rects:
                pygame.draw.rect(screen, GameColor.F.Light, rect)
            for rect in self.j_win_rects:
                pygame.draw.rect(screen, GameColor.J.Light, rect)

        self.hud.render_stuff(screen,
                              self.game.timer,
                              self.game.perc_f,
                              self.game.perc_j,
                              self.keys.nums[49],
                              render_percs=self.match_state.state in {
                                  MatchState.RUNNING, MatchState.PRACTICE_MODE
                              })

        if self.match_state.state == MatchState.PRACTICE_VICTORY:
            self.f_enc_cons_text.render(
                screen,
                self.encouragement if self.winner == "f" else self.consolation)
            self.j_enc_cons_text.render(
                screen,
                self.encouragement if self.winner == "j" else self.consolation)

        if self.match_state.state == MatchState.PLAYER_LIST:
            self.p_list.render_stuff(screen)

        if self.keys.tab:
            self.scoreboard.render_stuff(screen)

        if self.menu.in_focus:
            self.menu.render_stuff(screen)