示例#1
0
文件: hud.py 项目: timl235/stealth
    def update(self):

        # Update its value and text
        self.value -= 1
        self.update_text(str(self.value))
        saves.save_data["time_left"] = self.value
        saves.save()
示例#2
0
 def save_click(self):
     saves.save()
def reg_round(player_party, player_name, round_number):
    boss_round = False
    print("###########################")
    if (round_number + 1) % 5 == 0:
        boss_round = True
        print("A boss has appeared!")
    else:
        print("An enemy party has appeared!")
    enemy_party = get_enemy_party(round_number, boss_round)

    print(enemy_party.get_random_greeting(), end="\n\n")

    while enemy_party.get_party_health() > 0:
        print("----------------------------")
        print(player_turn(enemy_party, player_party, player_name))
        print("----------------------------", end="\n\n")
        killed_enemies = enemy_party.get_dead_party_members()
        if killed_enemies:
            for enemy in killed_enemies:
                print(f"The {enemy.name} was defeated!\n")
                items = drop_items(enemy.item_drops, enemy.max_drops)
                player_party.add_items(items)
        else:
            print("----------------------------")
            print(enemy_turn(enemy_party, player_party))
            print("----------------------------", end="\n\n")
            killed_players = player_party.get_dead_party_members()
            if killed_players:
                for player in killed_players:
                    print(f"{player.name} was defeated!\n")

        if not player_party.get_party_health() > 0:
            print(f"{player_name}'s party was defeated by the enemy party\n")
            return round_number

    print(f"Congradulations {player_name} you defeated the enemy party!")
    round_number += 1
    print("###########################")

    if chance_to_get_new_player(round_number, len(player_party.party)):
        new_player = get_random_player()
        player_party.add_party_member(new_player)
        print(
            f"\nCongradulations, {new_player.name} has decided to join your party!"
        )

    if boss_round:
        while True:
            choice = input(
                "Would you like to save, quit, save and quit or continue? (enter 's' to save, 'q' to quit, 'sq' to save and quit or anything else to continue): "
            )
            if choice.lower() == 's':
                print(save(player_name, player_party, round_number))
                return round_number
            elif choice.lower() == 'q':
                print("Thank you for playing, hope to see you again!")
                exit()
            elif choice.lower() == 'sq':
                print(save(player_name, player_party, round_number))
                print("Thank you for playing, hope to see you again!")
                exit()
            else:
                return round_number
    print("")
    player_party.equip_items()
    return round_number
示例#4
0
    def run(self, from_start=False):
        # Game loop

        # Load the players progress,
        # if they clicked continue.
        # Otherwise then start from the start
        if not from_start:
            self.current_level_no = saves.load("current_level")
        else:
            self.current_level_no = 0
        # Save the current level
        saves.save_data["current_level"] = self.current_level_no
        saves.save()

        # If the player is about to start level 1,
        # then play the intro
        played_intro = True
        if self.current_level_no == 0 and from_start:
            self.play_intro(self.intro, self.intro_thresholds, [("part 1:", 75, 214, 200),
                                                                ("infiltration", 125, 603, 296)])
        elif isinstance(self.current_level, level.Level08) and from_start:
            self.play_intro(self.part2_scene, self.part2_scene_thresholds, [("part 2:", 75, 222, 200),
                                                                            ("escape", 125, 349, 296)])
        else:
            played_intro = False

        # Load the current level
        self.current_level = self.level_list[self.current_level_no]
        self.player.level = self.current_level
        self.current_level.player = self.player

        # A performance enhancement
        # The more dots the longer it takes
        player = self.player

        # Load the music
        # Then mix the volumes
        music2_playing = False
        if isinstance(self.current_level, (level.Level08, level.Level09, level.Level10)):
            pygame.mixer.music.load("resources/music2.mp3")
            pygame.mixer.music.set_volume(0.25)
            music2_playing = True
            self.sound_engine.que_sound([self.sound_engine.siren_sound, -1])

            self.timer.can_update = True
            self.timer.reset()

            self.timer.set(saves.load("time_left"))
        else:

            self.timer.can_update = False
            self.timer.reset()
            saves.save_data["time_left"] = self.timer.value
            saves.save()

            pygame.mixer.music.load("resources/music.mp3")
            pygame.mixer.music.set_volume(0.25)

        # Hide mouse pointer
        pygame.mouse.set_visible(False)

        # Reset level by undo-ing all scrolling
        # Then scroll back to the start position
        # Finally reset any changes made to sprites in the level
        self.current_level.reset_objects()
        self.current_level.reset_world()
        self.current_level.set_scrolling()

        # Set the players position
        player.rect.x = 48
        player.rect.y = 384

        # Variables to control the player
        run = 0
        jump = False
        crouch = False

        # A variety of variables that are controlling whats going on

        if played_intro:
            pause = 32
            fade_in = True
        else:
            pause = 0
            fade_in = False
        reset = False
        progress = False
        do_reset = False
        show_caught = False
        time_up = False
        play_outro = False

        # Always play the light sound
        # But make it a non-zero volume if there are guards
        self.sound_engine.que_sound([self.sound_engine.light_sound, -1])

        # Play the music
        pygame.mixer.music.play(-1)

        # Loop until the window is closed
        game_exit = False

        # And here begins out game loop
        while not game_exit:

            # A generic style events loop
            for event in pygame.event.get():

                # If player closes window
                if event.type == QUIT:

                    # Show the mouse before quitting
                    pygame.mouse.set_visible(True)

                    # Exit pygame then quit the program
                    pygame.quit()
                    sys.exit(0)

                # If a key was pressed...
                elif event.type == KEYDOWN:

                    # Escape returns to menu by breaking the game loop
                    if event.key == K_ESCAPE:
                        game_exit = True

                    # Player controls

                    # Running left/right
                    if event.key == self.controls["WALK_LEFT"]:
                        run = -1
                    if event.key == self.controls["WALK_RIGHT"]:
                        run = 1

                    # Jumping
                    if event.key == self.controls["JUMP"]:
                        jump = True

                    # Use keypads
                    if event.key == self.controls["ACTION"]:
                        player.use_keypad()

                    # Crouching
                    if event.key == self.controls["CROUCH"]:
                        crouch = True

                    if event.key == self.controls["RESTART"]:
                        player.health = -1

                # If a key was released...
                elif event.type == KEYUP:

                    # Stopping the player from running left
                    if event.key == self.controls["WALK_LEFT"] and not run == 1:
                        run = 0

                    # Stopping the player from running right
                    if event.key == self.controls["WALK_RIGHT"] and not run == -1:
                        run = 0

                    # Stops the player from jumping and climbing
                    if event.key == self.controls["JUMP"]:
                        jump = False
                        player.climbing = False

                    # And then stopping the playing from crouching
                    if event.key == self.controls["CROUCH"]:
                        crouch = False

                elif event.type == self.update_timer_event:
                    if self.timer.can_update:
                        self.timer.update()
                        self.sound_engine.que_sound([self.sound_engine.keypress_sound, 0])

            # Pause is a counter variable that stops the game
            # The higher pause is set to the longer the game will pause
            # Pause is often used when transitions are being made
            if pause > 0:
                pause -= 1

            # Level progression
            # If the player has reached the right side of the screen
            # Then pause the game, and say the game should progress onto the next level
            if player.rect.centerx - player.rect.width/4 >= constants.SCREEN_WIDTH and not progress:

                # Don't let the player walk any further
                player.rect.centerx = constants.SCREEN_WIDTH + player.rect.width/4
                player.xv = 0

                # If there are bombs in the level
                # make sure the player has activated them in all
                if len(self.current_level.bombs.sprites()) or \
                   len([bomb for bomb in self.current_level.non_draw if isinstance(bomb, entities.Bomb)]):
                    if not len([bomb for bomb in self.current_level.non_draw if isinstance(bomb, entities.Bomb)]):
                        activated = len(self.current_level.bombs.sprites())
                        if activated == len([bomb for bomb in self.current_level.bombs.sprites()
                                             if bomb.progress >= 10]):
                            pause = 60
                            progress = True
                else:
                    pause = 60
                    progress = True

            if progress and pause == 30:

                # Reset the player and level
                self.current_level.reset_objects()
                self.current_level.reset_world()
                self.current_level.set_scrolling()
                player.reset()

                # Save the progress to the save file
                # and set the new level, if the player hasn't finished the game
                # Otherwise return to the menu
                self.current_level_no += 1
                if self.current_level_no >= len(self.level_list):
                    self.current_level_no = 0
                    saves.save_data["current_level"] = 0
                    saves.save()

                    play_outro = True

                    break
                else:
                    self.current_level = self.level_list[self.current_level_no]
                saves.save_data["current_level"] = self.current_level_no
                saves.save()

                # Assign references between objects
                player.level = self.current_level
                self.current_level.player = player

                if isinstance(self.current_level, (level.Level08, level.Level09, level.Level10)):
                    if not music2_playing:
                        pygame.mixer.music.load("resources/music2.mp3")
                        pygame.mixer.music.set_volume(0.75)
                        pygame.mixer.music.play(-1)
                        self.sound_engine.que_sound([self.sound_engine.siren_sound, -1])
                        music2_playing = True
                    if isinstance(self.current_level, level.Level08):
                        self.play_intro(self.part2_scene, self.part2_scene_thresholds, [("part 2:", 75, 222, 200),
                                                                                        ("escape", 125, 349, 296)])
                    self.timer.can_update = True

            # Once the progression has complete, set the progress var accordingly
            if progress and not pause:
                progress = False

            # Check if player has hit obstacles
            obstacle_hits = pygame.sprite.spritecollide(player, self.current_level.obstacle_list, False)
            if (len(obstacle_hits) or player.health <= 0) and not player.dying:

                # If the player has, then say the player is dying
                player.dying = True
                player.health = 0
                self.sound_engine.que_sound([self.sound_engine.dissolve_sound, 0])

            # This tells the game that it needs to reset the level
            if pause < 50 and reset:
                do_reset = True

            # These are things that should only happen when the game is not paused
            elif not pause:

                # Check if the guards got the player
                hit_list = pygame.sprite.spritecollide(player, self.current_level.entities, False)
                for hit in hit_list:
                    if isinstance(hit, torches.Torch):

                        # Due to the conical shape of the torchlight, we need to do pixel perfect collision here
                        # otherwise it would be really easy to 'hit' a torch when you haven't really

                        if funcs.pixel_perfect_collision(player.rect, player.hitmask, hit.rect, hit.hitmask):
                            pause = 180
                            reset = True

                            # Create an exclamation mark
                            # Nice addition that easily lets the player know which guard caught them
                            self.current_level.entities.add(entities.ExclamationMark(hit.guard))

                # Using a generator, create a list of booleans reporting if the laser is touching the player
                hit_laser = [laser.test_collision() for laser in self.current_level.lasers]
                if True in hit_laser:
                    # If the player did get caught,
                    # then pause the game and tell the level it needs to reset
                    pause = 180
                    reset = True

                # Player movement

                # First check if the player should actually move
                if run != 0 and not player.dying:
                    # Then check which direction the player needs to run in
                    # and move the player in that direction
                    if run == 1:
                        player.walk_right()
                    elif run == -1:
                        player.walk_left()

                # If the should crouch, then make the player crouch
                # otherwise stop the player from crouching
                if crouch:
                    player.do_crouch()
                else:
                    player.stop_crouching()

                # Don't allow the player to jump when crouching
                if jump:
                    player.jump()

            # Check for collisions between the player and bullets
            # Gather a list of bullets and test for collision against the player
            hit_list = pygame.sprite.spritecollide(player, [bullet for bullet in self.current_level.entities
                                                            if isinstance(bullet, guard_parts.Bullet)], False)
            for bullet in hit_list:
                player.health -= 10
                self.current_level.entities.remove(bullet)

            # Update entities

            # Don't update the player when the games progressing
            if not progress:
                self.player_group.update()
            else:
                # Sometimes the player can get stuck in running pose
                # after it hits the right side of the screen
                # so here's a quick fix to that
                player.image = player.stand_image_r
            if not pause:
                # Don't update the level when the games paused
                self.current_level.update()
            else:
                # Lasers still need updated however to correct their position
                self.current_level.lasers.update()
            # There's no special cases for the rest of the sprites
            self.blackout.update()
            self.crosshair.update()
            self.hud.update()

            # Play all of the sounds that need to be played
            self.sound_engine.play_sounds()

            if len([guard for guard in self.current_level.guards.sprites() if isinstance(guard, guards.Guard)]):
                    # Find nearest guard
                    # This is done by generating a list of the distances to each guard
                    # calculated using Pythagoras' theorem.
                    # This list is then sorted, so the zeroth item of the list would
                    # be the distance to the nearest guard.
                    nearest_guard = [int(math.pow((math.pow(x.rect.x - player.rect.x, 2)) +
                                                  (math.pow(x.rect.y - player.rect.y, 2)), 0.5))
                                     for x in self.current_level.guards.sprites()]
                    nearest_guard.sort()

                    # Stops a special case where being very far away from all
                    # guards means that the sound can still be loud
                    if nearest_guard[0]-250 < 0:
                        # And then set the volume relative to the distance to the nearest guard
                        self.sound_engine.light_sound.set_volume(abs(nearest_guard[0]-250)/150)
                    else:
                        self.sound_engine.light_sound.set_volume(0)
            else:
                self.sound_engine.light_sound.set_volume(0)

            # Scrolling in all 4 directions

            # Only scroll when the player is nearing the edge of the screen
            if player.rect.x >= constants.SCREEN_WIDTH - 288:
                # Calculate how far past the point of scrolling the player is
                diff = player.rect.x - (constants.SCREEN_WIDTH - 288)

                # If the level has reached its limit of scrolling then allow the player to move
                # otherwise the player wouldn't be able to get right up to the edges of the level
                if not self.current_level.at_edge_x:
                    player.rect.x = constants.SCREEN_WIDTH - 288

                # Then finally shift the level in the opposite direction of where the player moved
                self.current_level.shift_world(-diff, 0)

            # Repeat this again for the other direction
            if player.rect.x <= 288:
                diff = player.rect.x - 288
                if not self.current_level.at_edge_x:
                    player.rect.x = 288
                self.current_level.shift_world(-diff, 0)

            # Again it's a similar thing on the y axis,
            # but it's inverted since the y axis is flipped
            if player.rect.y >= constants.SCREEN_HEIGHT - 240:
                diff = player.rect.y - (constants.SCREEN_HEIGHT - 240)
                if not self.current_level.at_edge_y:
                    player.rect.y = constants.SCREEN_HEIGHT - 240
                self.current_level.shift_world(0, diff)

            if player.rect.y <= 288:
                diff = player.rect.y - 288
                if not self.current_level.at_edge_y:
                    player.rect.y = 288
                self.current_level.shift_world(0, diff)

            # If the game is paused, and the level is resetting,
            # then show the 'game over' screen
            if reset and pause > 0:
                show_caught = True

            # And once the level has reset, hide the game over screen
            if show_caught and pause == 0:
                show_caught = False

            # Resetting the level
            if do_reset:
                # Start by resetting the objects in the level,
                # such as keypads and doors.
                # Then reset the scrolling back to the start position of the level.
                self.current_level.reset_objects()
                self.current_level.reset_world()
                self.current_level.set_scrolling()

                # Reset the player
                # If the player is crouching, then stop the player from crouching
                player.reset()
                if player.crouching:
                    player.stop_crouching()
                    player.crouching = False

                # And tell the game that the level has reset
                reset = False
                do_reset = False

            # And now a similar procedure when the player dies
            if player.dying and player.death_progress == 40:
                # Reset the players health and stamina
                player.health = 100
                player.stamina = 100

                # Then again reset the level and player
                self.current_level.reset_objects()
                self.current_level.reset_world()
                self.current_level.set_scrolling()
                player.reset()

            if self.timer.can_update:
                if self.timer.value <= 0:
                    time_up = True
                    pause = 150

                    self.timer.can_update = False
                    self.timer.reset()
                    saves.save_data["time_left"] = self.timer.value
                    saves.save()

                    self.sound_engine.que_sound([self.sound_engine.explosion_sound, 0])

            if time_up and pause == 30:
                # If the timer is out of time then reset to level 8

                # Reset the players health and stamina
                player.health = 100
                player.stamina = 100

                self.current_level.reset_objects()
                self.current_level.reset_world()
                self.current_level.set_scrolling()

                self.current_level_no = 7
                self.current_level = self.level_list[self.current_level_no]

                saves.save_data["current_level"] = self.current_level_no
                saves.save()

                self.current_level.player = player
                player.level = self.current_level

                self.current_level.reset_objects()
                self.current_level.reset_world()
                self.current_level.set_scrolling()
                player.reset()

                self.timer.reset()

            if time_up and not pause:
                time_up = False
                self.timer.can_update = True

            # Stop the player from dying once it's dead
            if player.dying and player.death_progress >= 75:
                player.dying = False
                player.death_progress = 0

            # All drawing goes here
            # Start by drawing the level, then on top of that the player
            # then the various other things on top of that
            self.current_level.draw(self.display)
            self.player_group.draw(self.display)
            self.blackout.draw(self.display)
            self.crosshair.draw(self.display)
            self.hud.draw(self.display)
            if self.timer.can_update:
                self.timer.draw(self.display)

            # Draw covers when player is caught/dies
            # there are certain periods where these covers fade in/out
            # Which makes the transition look a lot smoother than
            # simply appearing then disappearing.
            # During these periods the transparency needs to increase/decrease

            # First of all the 'player was caught' screen
            if show_caught and 67 < pause < 100:
                spritesheet.blit_alpha(self.display, self.game_over.image, (0, 0),
                                       abs(pause-100)*8)
            elif show_caught and 0 < pause < 17:
                spritesheet.blit_alpha(self.display, self.game_over.image, (0, 0),
                                       pause*16)
            elif show_caught and 16 < pause < 68:
                self.display.blit(self.game_over.image, (0, 0))

            # If the bomb has gone off
            # then show the other game over screen
            if time_up and 117 < pause < 150:
                spritesheet.blit_alpha(self.display, self.game_over2.image, (0, 0),
                                       abs(pause-150)*8)
            elif time_up and 0 < pause < 17:
                spritesheet.blit_alpha(self.display, self.game_over2.image, (0, 0),
                                       pause*16)
            elif time_up and 16 < pause < 118:
                self.display.blit(self.game_over2.image, (0, 0))

            # Then just a dark screen when the player dies
            # But this shouldn't be shown when the player is caught
            # If the player manages to get caught and die at the same time
            if not (show_caught or time_up):
                if player.dying and 16 < player.death_progress < 33:
                    spritesheet.blit_alpha(self.display, self.black_screen.image, (0, 0),
                                           (player.death_progress-16)*16)
                elif player.dying and 32 < player.death_progress < 60:
                    self.display.blit(self.black_screen.image, (0, 0))
                elif player.dying and 59 < player.death_progress < 76:
                    spritesheet.blit_alpha(self.display, self.black_screen.image, (0, 0),
                                           abs(player.death_progress-75)*16)

            # And again a dark screen when the level is changing
            if progress and 43 < pause < 61:
                spritesheet.blit_alpha(self.display, self.black_screen.image, (0, 0),
                                       abs(pause-60)*16)
            elif progress and 16 < pause < 54:
                self.display.blit(self.black_screen.image, (0, 0))
            elif progress and 0 < pause < 17:
                spritesheet.blit_alpha(self.display, self.black_screen.image, (0, 0),
                                       pause*16)

            # If the game should fade in then do so
            if fade_in and pause:
                spritesheet.blit_alpha(self.display, self.black_screen.image, (0, 0),
                                       pause*8)
            else:
                fade_in = False

            # Limit to 60 fps
            self.clock.tick(45)
            # Update the display
            pygame.display.flip()

        # Stop the light sound from playing once the game has finished
        self.sound_engine.light_sound.stop()
        self.sound_engine.siren_sound.stop()

        if play_outro:
            # Since the user has finished all of the levels
            # play the outro before returning to the menu
            self.play_intro(self.outro, self.outro_thresholds, [("thanks for playing!", 80, 649, 296)])

            # And since the game is done, we want to reset
            # anything left over from this play
            player.health = 100
            player.stamina = 100

        # Start the menu music
        # before returning to the menu
        pygame.mixer.music.load("resources/menu_music.mp3")
        pygame.mixer.music.set_volume(0.75)
        pygame.mixer.music.play(-1)

        # Then show the mouse pointer
        pygame.mouse.set_visible(True)
        elif command == "pickup":
            if data in story[locationCode][
                    'availableItems'] and data not in inventory:
                print(f"Added {data} to your inventory.")
                inventory.append(data)
            else:
                raise ItemDoesNotExist(data)
        elif command == "help":
            letterPrint(helpMessage)
        else:
            raise InvalidCommand
    except InvalidCommand:
        print("Invalid Command!")
    except ItemDoesNotExist as e:
        print(f'There is no item named {e}.')
    except ItemNotInInventory as e:
        print(f'You do not have the required {e}.')
    except IndexError:
        print("Wrong number of inputs!")
    except Exception as e:
        print(f"Unknown error: {e}")
    # add a newline for formatting (makes the interface easier on the eyes)
    print()
    time.sleep(0.5)

# save the file, if the user wishes (handled within the function)
saves.save(saveFile, inventory, locationCode)

print("Press any key to exit...", end='', flush=True)
os.system('pause >nul')