예제 #1
0
    def __init__(self) -> None:
        """Create a new SceneManager and setup the static instance variable."""
        if (SceneManager.instance is None):
            SceneManager.instance = self

        # Tell pygame to center the window
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        pygame.font.init()

        self._screen_size = (0, 0)
        self._is_fullscreen = True
        self._clock = pygame.time.Clock()
        self._scenes = [MainMenuScene, SettingsScene, GameScene]
        self._running = True

        self._setup_screen()

        # Always visible components
        self._root = Panel(self._screen.get_rect(),
                           style=Style(background_color=(255, 0, 0),
                                       border_width=0))

        self._fps_counter = Label(text="Calculating",
                                  rect=pygame.Rect(0, 25, 75, 20),
                                  style=Style(background_color=(255, 0, 0),
                                              border_width=0,
                                              primary_color=(255, 255, 255)),
                                  parent=self._root)
        self._rest_fps_counter_position()

        # Start the game
        self.change_scene(0)
        self._run_game_loop()
예제 #2
0
    def __init__(self, root: Panel):
        """Create a new MainMenuScene, creating the gui components to
        display.
        """
        size = root.get_rect().size
        title_rect = Rect(0, 0, 500, 70)
        title_rect.center = (size[0] / 2, size[1] / 2 - 200)

        # A panel for all the options
        options_panel = VerticalPanel(rect=Rect(size[0] / 4, size[1] / 2,
                                                size[0] / 2, size[1] / 4),
                                      expand_height=False,
                                      parent=root)

        # Title label
        Label(text="BATTLE SHIP!",
              rect=title_rect,
              style=Style(background_color=None,
                          border_width=0,
                          font=pygame.font.Font('freesansbold.ttf', 64),
                          primary_color=(255, 255, 255)),
              parent=root)

        # A style for all of the menu options
        button_style = Style(primary_color=(255, 255, 255),
                             background_color=(128, 0, 0),
                             border_width=1,
                             border_color=(0, 0, 0),
                             font=pygame.font.Font('freesansbold.ttf', 32))

        # Player vs Computer button
        Button(rect=Rect(0, 0, 400, 40),
               on_click=self._pvc_clicked,
               text="Player vs Computer",
               style=button_style,
               parent=options_panel)

        # Player vs Player button
        Button(rect=Rect(0, 0, 400, 40),
               on_click=self._pvp_clicked,
               text="Player vs Player",
               style=button_style,
               parent=options_panel)

        # Settings button
        Button(rect=Rect(0, 0, 400, 40),
               on_click=self._settings_clicked,
               text="Settings",
               style=button_style,
               parent=options_panel)

        # Quit button
        Button(rect=Rect(0, 0, 400, 40),
               on_click=self._quit_clicked,
               text="Quit",
               style=button_style,
               parent=options_panel)
예제 #3
0
    def set_parent(self, parent: Optional[Component]) -> None:
        """Set the component's parent. The default style is used if <parent>
        is None.
        """
        Panel.set_parent(self, parent)

        if (self._parent is None):
            return

        self.set_rect(self._parent.get_rect())
        size = self.get_rect().size

        title_rect = Rect(0, 0, 500, 70)
        title_rect.center = (size[0] / 2, size[1] / 2 - 200)

        self.clear_children()

        self.options_panel = VerticalPanel(rect=Rect(size[0] / 4, size[1] / 2,
                                                     size[0] / 2, size[1] / 4),
                                           expand_height=False,
                                           parent=self)

        self.title_label = Label(text="BATTLE SHIP!",
                                 rect=title_rect,
                                 style=Style(background_color=None,
                                             border_width=0,
                                             font=pygame.font.Font(
                                                 'freesansbold.ttf', 64),
                                             primary_color=(255, 255, 255)),
                                 parent=self)

        button_style = Style(primary_color=(255, 255, 255),
                             background_color=(128, 0, 0),
                             border_width=1,
                             border_color=(0, 0, 0),
                             font=pygame.font.Font('freesansbold.ttf', 32))

        self.cont_button = Button(rect=Rect(0, 0, 400, 40),
                                  on_click=self._cont_clicked,
                                  text="Continue",
                                  style=button_style,
                                  parent=self.options_panel)

        self.main_menu_button = Button(rect=Rect(0, 0, 400, 40),
                                       on_click=self._main_menu_clicked,
                                       text="Main menu",
                                       style=button_style,
                                       parent=self.options_panel)

        self.quit_button = Button(rect=Rect(0, 0, 400, 40),
                                  on_click=self._quit_clicked,
                                  text="Quit",
                                  style=button_style,
                                  parent=self.options_panel)
예제 #4
0
    def _create_player_grids(self, rect: Rect, style: Style) -> \
            Tuple[AnimatedGrid, AnimatedGrid, AnimatedGrid]:
        """Create a ship grid, hit grid, and miss grid. The function returns
        the grids as a list in the same order."""

        # A style for the hit and miss grids
        overlay_style = Style(background_color=None,
                              primary_color=(0, 0, 0, 0),
                              secondary_color=None,
                              border_color=None,
                              border_width=0,
                              force_parent_redraw=True)

        # A grid of boats
        ships = AnimatedGrid(rect=rect,
                             folder_path="images/boat",
                             style=style,
                             parent=self._background_water)

        # A grid of hits
        hits = AnimatedGrid(rect=rect,
                            folder_path="images/hit",
                            style=overlay_style,
                            parent=ships)

        # A grid of misses
        misses = AnimatedGrid(rect=rect,
                              folder_path="images/miss",
                              style=overlay_style,
                              parent=hits)

        return (ships, hits, misses)
예제 #5
0
    def create_labels(self, root: Component) -> None:
        """ Create all labels in the settings menu. """
        label_style = Style(background_color=(0, 128, 255),
                            primary_color=(255, 255, 255))

        self.soundFX = Label(text="Adjust Sound FX",
                             rect=Rect(150, 120, 250, 50),
                             style=label_style,
                             parent=self.soundFx_panel)

        self.music = Label(text="Music volume",
                           rect=Rect(200, 200, 200, 50),
                           style=label_style,
                           parent=self.music_panel)

        self.window_mode = Label(text="Window Mode",
                                 rect=Rect(200, 300, 200, 100),
                                 style=label_style,
                                 parent=self.window_mode_panel)

        size = sm.SceneManager.instance.get_screen_size()
        title_rect = Rect(400, 45, 250, 50)
        title_rect.centerx = size[0] / 2

        self.menu = Label(text="CHANGE SETTINGS",
                          rect=title_rect,
                          style=label_style,
                          parent=root)
예제 #6
0
    def set_style(self, style: Optional[Style]) -> None:
        """Set the component's style. The default style is used if <style> is
        None.
        """
        self._style = style

        if (style is None):
            self._style = Style()

        self._redraw()
예제 #7
0
    def create_buttons(self, root: Component) -> None:
        """Create all buttons in the settings menu"""

        button_style = Style(background_color=(0, 255, 255),
                             primary_color=(0, 0, 0),
                             border_color=(0, 0, 0),
                             border_width=1)

        size = sm.SceneManager.instance.get_screen_size()
        self.back_button = Button(on_click=self._open_main_menu,
                                  rect=Rect(20, 20, 100, 100),
                                  style=Style(
                                      background_color=(255, 0, 0),
                                      background_image=pygame.image.load(
                                          "images/left-arrow-icon.png")),
                                  parent=root)

        self.fullscreen_button = Button(on_click=self._toggle_fullscreen,
                                        text=self._get_window_mode_text(),
                                        rect=Rect(450, 320, 150, 50),
                                        style=button_style,
                                        parent=self.window_mode_panel)
예제 #8
0
    def create_sliders(self, root: Component) -> None:
        """ Create all sliders in the settings menu. """
        slider_style = Style(background_color=(255, 0, 0),
                             primary_color=(255, 255, 204),
                             secondary_color=(102, 0, 102),
                             tertiary_color=(255, 0, 128))

        self.soundFX_slider = Slider(
            on_value_changed=am.AudioManager.instance.set_fx_volume,
            value=am.AudioManager.instance.get_fx_volume(),
            rect=Rect(450, 140, 150, 20),
            style=slider_style,
            parent=self.soundFx_panel)

        self.music_slider = Slider(
            on_value_changed=am.AudioManager.instance.set_music_volume,
            value=am.AudioManager.instance.get_music_volume(),
            rect=Rect(450, 210, 150, 20),
            style=slider_style,
            parent=self.music_panel)
예제 #9
0
    def __init__(self, root: Panel):
        """Create a new GameScene, creating the gui components to
        display and starting the game.
        """
        self._pause_menu = PauseMenuPanel(Rect(0, 0, 0, 0),
                                          style=Style(
                                              background_color=None,
                                              border_width=0,
                                              force_parent_redraw=True))

        # A style for all
        button_style = Style(background_color=(0, 255, 255),
                             primary_color=(0, 0, 0),
                             border_color=(0, 0, 0),
                             border_width=1)

        size = root.get_rect().size

        rect1 = Rect(size[0] / 8, size[1] / 8, size[0] * 3 / 8,
                     size[1] * 3 / 4)
        rect2 = Rect(size[0] / 2, size[1] / 8, size[0] * 3 / 8,
                     size[1] * 3 / 4)

        # The background water for the game
        self._background_water = BackgroundWater(rect=Rect(
            0, 0, size[0], size[1]),
                                                 parent=root)

        # A style for for the pause button
        pause_style = Style(
            background_color=None,
            force_parent_redraw=True,
            border_color=(0, 0, 0),
            border_width=2,
            background_image=pygame.image.load("images/pause.jpg"))

        # Pause Button
        Button(on_click=self._pause_clicked,
               rect=Rect(20, 20, 100, 100),
               style=pause_style,
               parent=self._background_water)

        # A style for player 1 grids
        player1_grid_style = Style(background_color=None,
                                   primary_color=(255, 0, 0, 100),
                                   secondary_color=(0, 0, 0, 200),
                                   border_color=(0, 0, 0),
                                   border_width=1,
                                   force_parent_redraw=True)

        # Create player 1 grids
        self._player1_grids = self._create_player_grids(
            rect1, player1_grid_style)

        # A style for player 2 grids
        player2_grid_style = Style(background_color=None,
                                   primary_color=(0, 255, 0, 50),
                                   secondary_color=(0, 0, 0, 200),
                                   border_color=(0, 0, 0),
                                   border_width=1,
                                   force_parent_redraw=True)

        # Create player 2 grids
        self._player2_grids = self._create_player_grids(
            rect2, player2_grid_style)

        # Setup observers
        player1 = GameManager.instance.get_player1()
        player2 = GameManager.instance.get_player2()
        player1.clear_observers()
        player2.clear_observers()
        player1.add_observer(self)
        player2.add_observer(self)

        # Start the game
        current_player = GameManager.instance.get_whos_turn()
        current_player.on_turn_started()
        current_player.notify_observers()