Example #1
0
File: menu.py Project: delmoras/tct
class Menu(State):

    ## initialize both the main and settings menu
    #
    # @param self the object pointer
    # @param game_opts the game's command line options
    def __init__(self, game_opts):
        # initialize the state
        State.__init__(self, 'menu')

        ## the game's command line options
        self.game_opts = game_opts

        ## the screen surface
        self.screen = pygame.display.get_surface() 

        ## flag to control the settings menu's loop
        self.menu_settings_running = None

        ## flag to control the main menu's loop
        self.menu_main_running = True

        # enable key repeat for the menu
        pygame.key.set_repeat(MENU_KEY_DEL, MENU_KEY_INT)

        ## set the main menu's background
        self.menu_main_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['main']['bg'][0])[0]

        ## set the settings menu's background
        self.menu_settings_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['bg'][0])[0]

        ## set the settings menu's background box
        self.menu_box_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['settings']['box'][0])[0]

        ## set the window frame
        self.window_frame = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['frame'][0])[0]

        ## set the mouse cursor
        self.mouse_cursor = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['cursor'][0])[0]

        ## set the sound when a menu option is entered
        self.select_option_snd = sound_mixer.load_sound(
            constants.FILES['sounds']['menu']['share']['sel'][0])

        ## create the main menu - string, callback function
        self.menu_main = KezMenu(self.game_opts,
                         ['Play'     , self._play_option],
                         ['Settings' , self._settings_option],
                         ['Credits'  , self._credits_option],
                         ['Quit'     , self._quit_option])

        # set the position of the main menu
        self.menu_main.set_position(MENU_MAIN_POS_X, MENU_MAIN_POS_Y)

        # set the main menu's font
        self.menu_main.set_font(graphics.load_font(
            constants.FILES['fonts']['menu']['share'][0], 30))

        # set the main menu's highlight color
        self.menu_main.set_highlight_color(pygame.Color('brown'))

        ## create the settings menu - string, callback function
        self.menu_settings = KezMenu(self.game_opts,
                             ['Fullscreen' , self._toggle_fullscreen_option],
                             ['Sounds'     , self._toggle_sounds_option],
                             ['Music'      , self._toggle_music_option],
                             ['Back'       , self._back_option])

        # disable the menu graphic for focused options
        self.menu_settings.toggle_image()

        # set the settings menu's font
        self.menu_settings.set_font(graphics.load_font(
            constants.FILES['fonts']['menu']['share'][0], 25))

        # set the position of the settings menu
        self.menu_settings.center_at(constants.SCREEN_WIDTH / 2.0,
                                     constants.SCREEN_HEIGHT / 2.0)
    
        # set the settings menu's highlight color
        self.menu_settings.set_highlight_color(pygame.Color('orange'))

        ## the animated sprite group
        self.anim_sprites = pygame.sprite.RenderUpdates()

        # vertical sprite sample
        self.anim_sprites.add(VertAnimSprite(
                constants.FILES['graphics']['menu']['share']['anim'][0],
                [0, 0], ANIM_SPRITE_SPEED))

        # horizontal sprite sample
        self.anim_sprites.add(HorAnimSprite(
                constants.FILES['graphics']['menu']['share']['anim'][1],
                [0, 0], ANIM_SPRITE_SPEED))

        ## create clock and track time
        self.clock = pygame.time.Clock()

    ## what to do when the main menu is enabled
    #
    # @param self the object pointer
    def do_actions(self):

        # display & update screen, get all the events
        while self.menu_main_running:
            # draw the background
            self.screen.blit(self.menu_main_bg, (0, 0))

            # count time passed in seconds
            time_passed_seconds = get_time_sec(self.clock.tick(50))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)
            rectlist = self.anim_sprites.draw(self.screen)

            # draw the main menu
            self.menu_main.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            self.screen.blit(self.window_frame, (0, 0))

            # display the screen surface
            pygame.display.update()
            
            # clear the sprites 
            self.anim_sprites.clear(self.screen, self.menu_main_bg)

            # get all the events
            events = pygame.event.get()

            # ......... and update the main menu
            # which needs access to those events
            self.menu_main.update(events)

            # main menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_p, pygame.K_s, pygame.K_c):
                            sound_mixer.play_sound(
                                self.select_option_snd, 0.2)

                    # when user presses escape or 'q'uit key
                    if e.key in (pygame.K_ESCAPE, pygame.K_q):
                        self._quit_option()
                    # when user presses 'p'lay key
                    elif e.key == pygame.K_p:
                        self._play_option()
                    # when user presses 's'ettings key
                    elif e.key == pygame.K_s:
                        self._settings_option()
                    # when user presses 'c'redits key
                    elif e.key == pygame.K_c:
                        self._credits_option()

    ## entry point for main menu's settings option
    #
    # @param self the object pointer
    def _settings_option(self):
        # each time we enter in settings
        # sub menu, set the flag to true
        self.menu_settings_running = True

        # decrease the alpha of animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(ANIM_SPRITE_ALPHA)

        # display & update screen, get all the events
        while self.menu_settings_running:
            # draw the background
            self.screen.blit(self.menu_settings_bg, (0, 0))

            # draw the main menu
            self.menu_main.draw(self.screen)

            # count time passed in seconds
            time_passed_seconds = get_time_sec(self.clock.tick(50))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)
            rectlist = self.anim_sprites.draw(self.screen)
            
            # draw settings menu background box
            self.screen.blit(self.menu_box_bg, (
             (constants.SCREEN_WIDTH - self.menu_box_bg.get_width()) / 2.0,
             (constants.SCREEN_HEIGHT - self.menu_box_bg.get_height()) / 2.0))

            # draw the settings menu
            self.menu_settings.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            self.screen.blit(self.window_frame, (0, 0))

            # display the screen surface
            pygame.display.update()

            # clear the sprites
            self.anim_sprites.clear(self.screen, self.menu_main_bg)

            # get all the events
            events = pygame.event.get()

            # ..... and update the settings menu
            # which needs access to those events
            self.menu_settings.update(events)

            # settings menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._back_option()
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_f, pygame.K_s, pygame.K_m,
                                     pygame.K_b, pygame.K_ESCAPE):
                            sound_mixer.play_sound(
                                self.select_option_snd, 0.2)

                    # when user presses escape key or 'b'ack key
                    if e.key in (pygame.K_ESCAPE, pygame.K_b):
                        self._back_option()
                    # when user presses 'f'ullscreen key
                    elif e.key == pygame.K_f:
                        self._toggle_fullscreen_option()
                    # when user presses 's'ounds key
                    elif e.key == pygame.K_s:
                        self._toggle_sounds_option()
                    # when user presses 'm'usic key
                    elif e.key == pygame.K_m:
                        self._toggle_music_option()

        # restore the alpha of the animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(255)

    ## entry point for main menu's new game option
    #
    # @param self the object pointer
    def _play_option(self):
        if self.game_opts.verbose:
            print 'Start a new game.'

    ## entry point for main menu's credits option
    #
    # @param self the object pointer
    def _credits_option(self):

        # get the path of the filename
        fullname = file_path(
            constants.FILES['texts']['menu']['credits']['text'][0],
            constants.TEXTS_DIR)

        # if credits text file exists and is readable
        if os.access(fullname, os.F_OK) and os.access(fullname, os.R_OK):
            if self.game_opts.verbose:
                print 'Go to the credits screen.'

            # create the credits screen
            c = Credits(self.screen,
                        self.game_opts,
                        self.window_frame,
                        self.menu_settings_bg,
                        self.select_option_snd,
                        fullname)

            # run the credits screen
            if not c.run():
                # quit if the close button is
                # pressed (inside the credits)
                self._quit_option()
        else:
            print ''.join(["Couldn't text file: ", fullname])

    ## entry point for main menu's quit option
    #
    # @param self the object pointer
    def _quit_option(self):
        if self.game_opts.verbose:
            print 'Exit the game!'

        # perform safe exit
        safe_exit()

    ## entry point for settings menu's toggle fullscreen option
    #
    # @param self the object pointer
    def _toggle_fullscreen_option(self):
        self.game_opts.fullscreen = not self.game_opts.fullscreen

        if self.game_opts.verbose:
            print 'Toggle fullscreen!'

        # store the position of the mouse cursor
        mouse_position = pygame.mouse.get_pos()

        # toggle the fullscreen <-> window mode
        pygame.display.set_mode(
            (constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT),
            pygame.FULLSCREEN if self.game_opts.fullscreen else 0)

        # update the mouse cursor position
        pygame.mouse.set_pos(mouse_position)

    ## entry point for settings menu's toggle sounds option
    #
    # @param self the object pointer
    def _toggle_sounds_option(self):
        self.game_opts.sound = not self.game_opts.sound
        if self.game_opts.verbose:
            print 'Toggle sounds!'

    ## entry point for settings menu's toggle music option
    #
    # @param self the object pointer
    def _toggle_music_option(self):
        if self.game_opts.verbose:
            print 'Toggle music!'

        self.game_opts.music = not self.game_opts.music
        if self.game_opts.music:
            pygame.mixer.music.unpause()
        else:
            pygame.mixer.music.pause()

    ## entry point for settings menu's back option
    #
    # @param self the object pointer
    def _back_option(self):
        self.menu_settings_running = False
        if self.game_opts.verbose:
            print 'Go back to main menu!'
class Menu(State):

    def __init__(self, game_opts):
        State.__init__(self, constants.SCENES['menu'])

        self.game_opts = game_opts
        self.screen = pygame.display.get_surface() 

        self.menu_settings_running = None
        self.menu_main_running = True

        pygame.key.set_repeat(MENU_KEY_DEL, MENU_KEY_INT)

        self.menu_main_bg = ResourceManager().getImage(
            constants.FILES['graphics']['menu']['main']['bg'][0])
        self.menu_settings_bg = ResourceManager().getImage(
            constants.FILES['graphics']['menu']['share']['bg'][0])
        self.menu_box_bg = ResourceManager().getImage(
            constants.FILES['graphics']['menu']['settings']['box'][0])
        self.window_frame = ResourceManager().getImage(
            constants.FILES['graphics']['menu']['share']['frame'][0])
        self.mouse_cursor = ResourceManager().getImage(
            constants.FILES['graphics']['menu']['share']['cursor'][0])

        self.select_option_snd = sound_mixer.load_sound(
            constants.FILES['sounds']['menu']['share']['sel'][0])

        # create the main menu - string, callback function
        self.menu_main = KezMenu(self.game_opts,
                         ['Play'     , self._play_option],
                         ['Settings' , self._settings_option],
                         ['Credits'  , self._credits_option],
                         ['Quit'     , self._quit_option])

        self.menu_main.set_position(MENU_MAIN_POS_X, MENU_MAIN_POS_Y)
        self.menu_main.set_font(graphics.load_font(
            constants.FILES['fonts']['menu']['share'][0], MAIN_FONT_SIZE))
        self.menu_main.set_highlight_color(MAIN_FOCUS_COLOR)

        # create the settings menu - string, callback function
        self.menu_settings = KezMenu(self.game_opts,
                             ['Fullscreen' , self._toggle_fullscreen_option],
                             ['Sounds'     , self._toggle_sounds_option],
                             ['Music'      , self._toggle_music_option],
                             ['Back'       , self._back_option])

        # disable the menu graphic for focused options
        self.menu_settings.toggle_image()

        self.menu_settings.set_font(graphics.load_font(
            constants.FILES['fonts']['menu']['share'][0], MENU_FONT_SIZE))
        self.menu_settings.center_at(constants.SCREEN_WIDTH / 2.0,
                                     constants.SCREEN_HEIGHT / 2.0)
        self.menu_settings.set_highlight_color(SETTINGS_FOCUS_COLOR)

        self.sprites = pygame.sprite.LayeredUpdates()

        sprites_number = len(constants.FILES['graphics']['menu']['share']['anim'])
        sprite_area = self.screen.get_rect()
        sprite_limiter = LimiterFactory().getInstance('Default')
        for i in range(sprites_number):
            sprite = MenuSprite(constants.FILES['graphics']['menu']['share']['anim'][i],
                                (sprite_area.center), i, MAX_ALPHA, False, SPRITE_SPEED,
                                sprite_area, 'Random')
            sprite.limiter = sprite_limiter
            self.sprites.add(sprite)

        self.clock = pygame.time.Clock()


    def do_actions(self):
        while self.menu_main_running:
            bg = self.screen.blit(self.menu_main_bg, (0, 0))
            time_passed_seconds = get_time_sec(self.clock.tick(MENU_CLOCK_TICK))

            self.sprites.update(time_passed_seconds)
            self.sprites.draw(self.screen)

            self.menu_main.draw(self.screen)

            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            fr = self.screen.blit(self.window_frame, (0, 0))
            need_update = (bg, fr)
            pygame.display.update(need_update)
            
            events = pygame.event.get()
            self.menu_main.update(events)

            for e in events:
                if e.type == pygame.QUIT:
                    self._quit_option()
                elif e.type == pygame.KEYDOWN:
                    if self.game_opts.sound:
                        if e.key in (pygame.K_p, pygame.K_s, pygame.K_c):
                            sound_mixer.play_sound(
                                self.select_option_snd, SOUND_VOL)
                    if e.key in (pygame.K_ESCAPE, pygame.K_q):
                        self._quit_option()
                    elif e.key == pygame.K_p:
                        self._play_option()
                    elif e.key == pygame.K_s:
                        self._settings_option()
                    elif e.key == pygame.K_c:
                        self._credits_option()

    # TODO eliminate this duplicate code
    def _settings_option(self):
        '''Entry point for main menu's settings option.'''
        # each time we enter in settings
        # sub menu, set the flag to true
        self.menu_settings_running = True

        for s in self.sprites:
            s.alpha = SPRITE_ALPHA

        while self.menu_settings_running:
            bg = self.screen.blit(self.menu_settings_bg, (0, 0))

            self.menu_main.draw(self.screen)

            time_passed_seconds = get_time_sec(self.clock.tick(MENU_CLOCK_TICK))

            self.sprites.update(time_passed_seconds)
            self.sprites.draw(self.screen)
            
            menu_bg = self.screen.blit(self.menu_box_bg, (
                    (constants.SCREEN_WIDTH - self.menu_box_bg.get_width()) / 2.0,
                    (constants.SCREEN_HEIGHT - self.menu_box_bg.get_height()) / 2.0))
            self.menu_settings.draw(self.screen)

            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)
            fr = self.screen.blit(self.window_frame, (0, 0))
            need_update = (bg, menu_bg, fr)

            pygame.display.update(need_update)
            events = pygame.event.get()
            self.menu_settings.update(events)

            for e in events:
                if e.type == pygame.QUIT:
                    self._back_option()
                    self._quit_option()
                elif e.type == pygame.KEYDOWN:
                    if self.game_opts.sound:
                        if e.key in (pygame.K_f, pygame.K_s, pygame.K_m,
                                     pygame.K_b, pygame.K_ESCAPE):
                            sound_mixer.play_sound(
                                self.select_option_snd, SOUND_VOL)
                    if e.key in (pygame.K_ESCAPE, pygame.K_b):
                        self._back_option()
                    elif e.key == pygame.K_f:
                        self._toggle_fullscreen_option()
                    elif e.key == pygame.K_s:
                        self._toggle_sounds_option()
                    elif e.key == pygame.K_m:
                        self._toggle_music_option()

        for s in self.sprites:
            s.alpha = MAX_ALPHA

    def _play_option(self):
        if self.game_opts.verbose:
            print('Start a new game.')
        self.menu_main_running = False


    def check_conditions(self):
        if not self.menu_main_running:
            return constants.SCENES['level_one']
        return None


    ## entry point for main menu's credits option
    #
    # @param self the object pointer
    def _credits_option(self):

        fullname = file_path(
            constants.FILES['texts']['menu']['credits']['text'][0],
            constants.TEXTS_DIR)

        if os.access(fullname, os.F_OK) and os.access(fullname, os.R_OK):
            if self.game_opts.verbose:
                print('Go to the credits screen.')

            c = Credits(self.screen,
                        self.game_opts,
                        self.window_frame,
                        self.menu_settings_bg,
                        self.select_option_snd,
                        fullname)

            if not c.run():
                # quit if the close button is
                # pressed (inside the credits)
                self._quit_option()
        else:
            path = os.path.basename(__file__)
            print("{0}: couldn't read text file: {1}".format(path, fullname))
            raise SystemExit

    def _quit_option(self):
        if self.game_opts.verbose:
            print('Exit the game!')

        # perform safe exit
        safe_exit()

    def _toggle_fullscreen_option(self):
        self.game_opts.fullscreen = not self.game_opts.fullscreen

        if self.game_opts.verbose:
            print('Toggle fullscreen!')

        mouse_position = pygame.mouse.get_pos()

        pygame.display.set_mode(
            (constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT),
            pygame.FULLSCREEN if self.game_opts.fullscreen else 0)

        pygame.mouse.set_pos(mouse_position)

    def _toggle_sounds_option(self):
        self.game_opts.sound = not self.game_opts.sound
        if self.game_opts.verbose:
            print('Toggle sounds!')

    def _toggle_music_option(self):
        if self.game_opts.verbose:
            print('Toggle music!')

        self.game_opts.music = not self.game_opts.music
        if self.game_opts.music:
            pygame.mixer.music.unpause()
        else:
            pygame.mixer.music.pause()

    def _back_option(self):
        self.menu_settings_running = False
        if self.game_opts.verbose:
            print('Go back to main menu!')
Example #3
0
class Menu(State):

    ## initialize both the main and settings menu
    #
    # @param self the object pointer
    # @param game_opts the game's command line options
    def __init__(self, game_opts):
        # initialize the state
        State.__init__(self, constants.SCENES['menu'])

        ## the game's command line options
        self.game_opts = game_opts

        ## the screen surface
        self.screen = pygame.display.get_surface()

        ## flag to control the settings menu's loop
        self.menu_settings_running = None

        ## flag to control the main menu's loop
        self.menu_main_running = True

        # enable key repeat for the menu
        pygame.key.set_repeat(MENU_KEY_DEL, MENU_KEY_INT)

        ## set the main menu's background
        self.menu_main_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['main']['bg'][0])[0]

        ## set the settings menu's background
        self.menu_settings_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['bg'][0])[0]

        ## set the settings menu's background box
        self.menu_box_bg = graphics.load_image(
            constants.FILES['graphics']['menu']['settings']['box'][0])[0]

        ## set the window frame
        self.window_frame = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['frame'][0])[0]

        ## set the mouse cursor
        self.mouse_cursor = graphics.load_image(
            constants.FILES['graphics']['menu']['share']['cursor'][0])[0]

        ## set the sound when a menu option is entered
        self.select_option_snd = sound_mixer.load_sound(
            constants.FILES['sounds']['menu']['share']['sel'][0])

        ## create the main menu - string, callback function
        self.menu_main = KezMenu(self.game_opts, ['Play', self._play_option],
                                 ['Settings', self._settings_option],
                                 ['Credits', self._credits_option],
                                 ['Quit', self._quit_option])

        # set the position of the main menu
        self.menu_main.set_position(MENU_MAIN_POS_X, MENU_MAIN_POS_Y)

        # set the main menu's font
        self.menu_main.set_font(
            graphics.load_font(constants.FILES['fonts']['menu']['share'][0],
                               MAIN_FONT_SIZE))

        # set the main menu's highlight color
        self.menu_main.set_highlight_color(MAIN_FOCUS_COLOR)

        ## create the settings menu - string, callback function
        self.menu_settings = KezMenu(
            self.game_opts, ['Fullscreen', self._toggle_fullscreen_option],
            ['Sounds', self._toggle_sounds_option],
            ['Music', self._toggle_music_option], ['Back', self._back_option])

        # disable the menu graphic for focused options
        self.menu_settings.toggle_image()

        # set the settings menu's font
        self.menu_settings.set_font(
            graphics.load_font(constants.FILES['fonts']['menu']['share'][0],
                               MENU_FONT_SIZE))

        # set the position of the settings menu
        self.menu_settings.center_at(constants.SCREEN_WIDTH / 2.0,
                                     constants.SCREEN_HEIGHT / 2.0)

        # set the settings menu's highlight color
        self.menu_settings.set_highlight_color(SETTINGS_FOCUS_COLOR)

        ## the animated sprite group
        self.anim_sprites = pygame.sprite.RenderUpdates()

        # create the animated sprites
        sprite_num = len(constants.FILES['graphics']['menu']['share']['anim'])
        sprite_fact = SpriteFactory()
        for i in range(sprite_num):
            # create the "right" type of animated sprite using the factory
            r_sprite = sprite_fact.create_anim_sprite(
                i, constants.FILES['graphics']['menu']['share']['anim'][i],
                ANIM_SPRITE_SPEED)
            self.anim_sprites.add(r_sprite)

        ## create clock and track time
        self.clock = pygame.time.Clock()

    ## what to do when the main menu is enabled
    #
    # @param self the object pointer
    def do_actions(self):

        # display & update screen, get all the events
        while self.menu_main_running:

            # draw the background
            bg = self.screen.blit(self.menu_main_bg, (0, 0))

            # count time passed in seconds
            time_passed_seconds = get_time_sec(
                self.clock.tick(MENU_CLOCK_TICK))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)

            # rectlist = self.anim_sprites.draw(self.screen)
            self.anim_sprites.draw(self.screen)

            # draw the main menu
            self.menu_main.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            fr = self.screen.blit(self.window_frame, (0, 0))

            need_update = (bg, fr)

            # display the screen surface
            pygame.display.update(need_update)

            # get all the events
            events = pygame.event.get()

            # ......... and update the main menu
            # which needs access to those events
            self.menu_main.update(events)

            # main menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_p, pygame.K_s, pygame.K_c):
                            sound_mixer.play_sound(self.select_option_snd,
                                                   SOUND_VOL)

                    # when user presses escape or 'q'uit key
                    if e.key in (pygame.K_ESCAPE, pygame.K_q):
                        self._quit_option()
                    # when user presses 'p'lay key
                    elif e.key == pygame.K_p:
                        self._play_option()
                    # when user presses 's'ettings key
                    elif e.key == pygame.K_s:
                        self._settings_option()
                    # when user presses 'c'redits key
                    elif e.key == pygame.K_c:
                        self._credits_option()

    ## entry point for main menu's settings option
    #
    # @param self the object pointer
    def _settings_option(self):
        # each time we enter in settings
        # sub menu, set the flag to true
        self.menu_settings_running = True

        # decrease the alpha of animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(ANIM_SPRITE_ALPHA)

        # display & update screen, get all the events
        while self.menu_settings_running:
            # draw the background
            bg = self.screen.blit(self.menu_settings_bg, (0, 0))

            # draw the main menu
            self.menu_main.draw(self.screen)

            # count time passed in seconds
            time_passed_seconds = get_time_sec(
                self.clock.tick(MENU_CLOCK_TICK))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)
            self.anim_sprites.draw(self.screen)

            # draw settings menu background box
            menu_bg = self.screen.blit(
                self.menu_box_bg,
                ((constants.SCREEN_WIDTH - self.menu_box_bg.get_width()) / 2.0,
                 (constants.SCREEN_HEIGHT - self.menu_box_bg.get_height()) /
                 2.0))

            # draw the settings menu
            self.menu_settings.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            fr = self.screen.blit(self.window_frame, (0, 0))

            need_update = (bg, menu_bg, fr)

            # display the screen surface
            pygame.display.update(need_update)

            # get all the events
            events = pygame.event.get()

            # ..... and update the settings menu
            # which needs access to those events
            self.menu_settings.update(events)

            # settings menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._back_option()
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_f, pygame.K_s, pygame.K_m,
                                     pygame.K_b, pygame.K_ESCAPE):
                            sound_mixer.play_sound(self.select_option_snd,
                                                   SOUND_VOL)

                    # when user presses escape key or 'b'ack key
                    if e.key in (pygame.K_ESCAPE, pygame.K_b):
                        self._back_option()
                    # when user presses 'f'ullscreen key
                    elif e.key == pygame.K_f:
                        self._toggle_fullscreen_option()
                    # when user presses 's'ounds key
                    elif e.key == pygame.K_s:
                        self._toggle_sounds_option()
                    # when user presses 'm'usic key
                    elif e.key == pygame.K_m:
                        self._toggle_music_option()

        # restore the alpha of the animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(MAX_ALPHA)

    ## entry point for main menu's new game option
    #
    # @param self the object pointer
    def _play_option(self):
        if self.game_opts.verbose:
            print('Start a new game.')
        self.menu_main_running = False

    ## what should be satisfied for enabling the next scene
    #
    # @param self the object pointer
    # @return the name of the next scene
    def check_conditions(self):
        # if the scene is finished, returns back
        # to the caller the name of the next one
        if not self.menu_main_running:
            return constants.SCENES['level_one']
        return None

    ## entry point for main menu's credits option
    #
    # @param self the object pointer
    def _credits_option(self):

        # get the path of the filename
        fullname = file_path(
            constants.FILES['texts']['menu']['credits']['text'][0],
            constants.TEXTS_DIR)

        # if credits text file exists and is readable
        if os.access(fullname, os.F_OK) and os.access(fullname, os.R_OK):
            if self.game_opts.verbose:
                print('Go to the credits screen.')

            # create the credits screen
            c = Credits(self.screen, self.game_opts, self.window_frame,
                        self.menu_settings_bg, self.select_option_snd,
                        fullname)

            # run the credits screen
            if not c.run():
                # quit if the close button is
                # pressed (inside the credits)
                self._quit_option()
        else:
            print((' '.join(("Couldn't read text file:", fullname))))

    ## entry point for main menu's quit option
    #
    # @param self the object pointer
    def _quit_option(self):
        if self.game_opts.verbose:
            print('Exit the game!')

        # perform safe exit
        safe_exit()

    ## entry point for settings menu's toggle fullscreen option
    #
    # @param self the object pointer
    def _toggle_fullscreen_option(self):
        self.game_opts.fullscreen = not self.game_opts.fullscreen

        if self.game_opts.verbose:
            print('Toggle fullscreen!')

        # store the position of the mouse cursor
        mouse_position = pygame.mouse.get_pos()

        # toggle the fullscreen <-> window mode
        pygame.display.set_mode(
            (constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT),
            pygame.FULLSCREEN if self.game_opts.fullscreen else 0)

        # update the mouse cursor position
        pygame.mouse.set_pos(mouse_position)

    ## entry point for settings menu's toggle sounds option
    #
    # @param self the object pointer
    def _toggle_sounds_option(self):
        self.game_opts.sound = not self.game_opts.sound
        if self.game_opts.verbose:
            print('Toggle sounds!')

    ## entry point for settings menu's toggle music option
    #
    # @param self the object pointer
    def _toggle_music_option(self):
        if self.game_opts.verbose:
            print('Toggle music!')

        self.game_opts.music = not self.game_opts.music
        if self.game_opts.music:
            pygame.mixer.music.unpause()
        else:
            pygame.mixer.music.pause()

    ## entry point for settings menu's back option
    #
    # @param self the object pointer
    def _back_option(self):
        self.menu_settings_running = False
        if self.game_opts.verbose:
            print('Go back to main menu!')
Example #4
0
class Menu(State):

    ## initialize both the main and settings menu
    #
    # @param self the object pointer
    # @param game_opts the game's command line options
    def __init__(self, game_opts):
        # initialize the state
        State.__init__(self, constants.SCENES["menu"])

        ## the game's command line options
        self.game_opts = game_opts

        ## the screen surface
        self.screen = pygame.display.get_surface()

        ## flag to control the settings menu's loop
        self.menu_settings_running = None

        ## flag to control the main menu's loop
        self.menu_main_running = True

        # enable key repeat for the menu
        pygame.key.set_repeat(MENU_KEY_DEL, MENU_KEY_INT)

        ## set the main menu's background
        self.menu_main_bg = graphics.load_image(constants.FILES["graphics"]["menu"]["main"]["bg"][0])[0]

        ## set the settings menu's background
        self.menu_settings_bg = graphics.load_image(constants.FILES["graphics"]["menu"]["share"]["bg"][0])[0]

        ## set the settings menu's background box
        self.menu_box_bg = graphics.load_image(constants.FILES["graphics"]["menu"]["settings"]["box"][0])[0]

        ## set the window frame
        self.window_frame = graphics.load_image(constants.FILES["graphics"]["menu"]["share"]["frame"][0])[0]

        ## set the mouse cursor
        self.mouse_cursor = graphics.load_image(constants.FILES["graphics"]["menu"]["share"]["cursor"][0])[0]

        ## set the sound when a menu option is entered
        self.select_option_snd = sound_mixer.load_sound(constants.FILES["sounds"]["menu"]["share"]["sel"][0])

        ## create the main menu - string, callback function
        self.menu_main = KezMenu(
            self.game_opts,
            ["Play", self._play_option],
            ["Settings", self._settings_option],
            ["Credits", self._credits_option],
            ["Quit", self._quit_option],
        )

        # set the position of the main menu
        self.menu_main.set_position(MENU_MAIN_POS_X, MENU_MAIN_POS_Y)

        # set the main menu's font
        self.menu_main.set_font(graphics.load_font(constants.FILES["fonts"]["menu"]["share"][0], MAIN_FONT_SIZE))

        # set the main menu's highlight color
        self.menu_main.set_highlight_color(MAIN_FOCUS_COLOR)

        ## create the settings menu - string, callback function
        self.menu_settings = KezMenu(
            self.game_opts,
            ["Fullscreen", self._toggle_fullscreen_option],
            ["Sounds", self._toggle_sounds_option],
            ["Music", self._toggle_music_option],
            ["Back", self._back_option],
        )

        # disable the menu graphic for focused options
        self.menu_settings.toggle_image()

        # set the settings menu's font
        self.menu_settings.set_font(graphics.load_font(constants.FILES["fonts"]["menu"]["share"][0], MENU_FONT_SIZE))

        # set the position of the settings menu
        self.menu_settings.center_at(constants.SCREEN_WIDTH / 2.0, constants.SCREEN_HEIGHT / 2.0)

        # set the settings menu's highlight color
        self.menu_settings.set_highlight_color(SETTINGS_FOCUS_COLOR)

        ## the animated sprite group
        self.anim_sprites = pygame.sprite.RenderUpdates()

        # create the animated sprites
        sprite_num = len(constants.FILES["graphics"]["menu"]["share"]["anim"])
        sprite_fact = SpriteFactory()
        for i in range(sprite_num):
            # create the "right" type of animated sprite using the factory
            r_sprite = sprite_fact.create_anim_sprite(
                i, constants.FILES["graphics"]["menu"]["share"]["anim"][i], ANIM_SPRITE_SPEED
            )
            self.anim_sprites.add(r_sprite)

        ## create clock and track time
        self.clock = pygame.time.Clock()

    ## what to do when the main menu is enabled
    #
    # @param self the object pointer
    def do_actions(self):

        # display & update screen, get all the events
        while self.menu_main_running:

            # draw the background
            bg = self.screen.blit(self.menu_main_bg, (0, 0))

            # count time passed in seconds
            time_passed_seconds = get_time_sec(self.clock.tick(MENU_CLOCK_TICK))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)

            # rectlist = self.anim_sprites.draw(self.screen)
            self.anim_sprites.draw(self.screen)

            # draw the main menu
            self.menu_main.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            fr = self.screen.blit(self.window_frame, (0, 0))

            need_update = (bg, fr)

            # display the screen surface
            pygame.display.update(need_update)

            # get all the events
            events = pygame.event.get()

            # ......... and update the main menu
            # which needs access to those events
            self.menu_main.update(events)

            # main menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_p, pygame.K_s, pygame.K_c):
                            sound_mixer.play_sound(self.select_option_snd, SOUND_VOL)

                    # when user presses escape or 'q'uit key
                    if e.key in (pygame.K_ESCAPE, pygame.K_q):
                        self._quit_option()
                    # when user presses 'p'lay key
                    elif e.key == pygame.K_p:
                        self._play_option()
                    # when user presses 's'ettings key
                    elif e.key == pygame.K_s:
                        self._settings_option()
                    # when user presses 'c'redits key
                    elif e.key == pygame.K_c:
                        self._credits_option()

    ## entry point for main menu's settings option
    #
    # @param self the object pointer
    def _settings_option(self):
        # each time we enter in settings
        # sub menu, set the flag to true
        self.menu_settings_running = True

        # decrease the alpha of animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(ANIM_SPRITE_ALPHA)

        # display & update screen, get all the events
        while self.menu_settings_running:
            # draw the background
            bg = self.screen.blit(self.menu_settings_bg, (0, 0))

            # draw the main menu
            self.menu_main.draw(self.screen)

            # count time passed in seconds
            time_passed_seconds = get_time_sec(self.clock.tick(MENU_CLOCK_TICK))

            # animate the sprites
            self.anim_sprites.update(time_passed_seconds)
            self.anim_sprites.draw(self.screen)

            # draw settings menu background box
            menu_bg = self.screen.blit(
                self.menu_box_bg,
                (
                    (constants.SCREEN_WIDTH - self.menu_box_bg.get_width()) / 2.0,
                    (constants.SCREEN_HEIGHT - self.menu_box_bg.get_height()) / 2.0,
                ),
            )

            # draw the settings menu
            self.menu_settings.draw(self.screen)

            # draw the custom mouse cursor
            graphics.handle_mouse_cursor(self.mouse_cursor, self.screen)

            # draw the frame of the window
            fr = self.screen.blit(self.window_frame, (0, 0))

            need_update = (bg, menu_bg, fr)

            # display the screen surface
            pygame.display.update(need_update)

            # get all the events
            events = pygame.event.get()

            # ..... and update the settings menu
            # which needs access to those events
            self.menu_settings.update(events)

            # settings menu event loop
            for e in events:
                # quit when the close button is pressed
                if e.type == pygame.QUIT:
                    self._back_option()
                    self._quit_option()
                # handle keyboard keys
                elif e.type == pygame.KEYDOWN:
                    # play the sound if there was a menu key shortcut
                    if self.game_opts.sound:
                        if e.key in (pygame.K_f, pygame.K_s, pygame.K_m, pygame.K_b, pygame.K_ESCAPE):
                            sound_mixer.play_sound(self.select_option_snd, SOUND_VOL)

                    # when user presses escape key or 'b'ack key
                    if e.key in (pygame.K_ESCAPE, pygame.K_b):
                        self._back_option()
                    # when user presses 'f'ullscreen key
                    elif e.key == pygame.K_f:
                        self._toggle_fullscreen_option()
                    # when user presses 's'ounds key
                    elif e.key == pygame.K_s:
                        self._toggle_sounds_option()
                    # when user presses 'm'usic key
                    elif e.key == pygame.K_m:
                        self._toggle_music_option()

        # restore the alpha of the animated sprites
        for s in self.anim_sprites:
            s.image.set_alpha(MAX_ALPHA)

    ## entry point for main menu's new game option
    #
    # @param self the object pointer
    def _play_option(self):
        if self.game_opts.verbose:
            print("Start a new game.")
        self.menu_main_running = False

    ## what should be satisfied for enabling the next scene
    #
    # @param self the object pointer
    # @return the name of the next scene
    def check_conditions(self):
        # if the scene is finished, returns back
        # to the caller the name of the next one
        if not self.menu_main_running:
            return constants.SCENES["level_one"]
        return None

    ## entry point for main menu's credits option
    #
    # @param self the object pointer
    def _credits_option(self):

        # get the path of the filename
        fullname = file_path(constants.FILES["texts"]["menu"]["credits"]["text"][0], constants.TEXTS_DIR)

        # if credits text file exists and is readable
        if os.access(fullname, os.F_OK) and os.access(fullname, os.R_OK):
            if self.game_opts.verbose:
                print("Go to the credits screen.")

            # create the credits screen
            c = Credits(
                self.screen, self.game_opts, self.window_frame, self.menu_settings_bg, self.select_option_snd, fullname
            )

            # run the credits screen
            if not c.run():
                # quit if the close button is
                # pressed (inside the credits)
                self._quit_option()
        else:
            print((" ".join(("Couldn't read text file:", fullname))))

    ## entry point for main menu's quit option
    #
    # @param self the object pointer
    def _quit_option(self):
        if self.game_opts.verbose:
            print("Exit the game!")

        # perform safe exit
        safe_exit()

    ## entry point for settings menu's toggle fullscreen option
    #
    # @param self the object pointer
    def _toggle_fullscreen_option(self):
        self.game_opts.fullscreen = not self.game_opts.fullscreen

        if self.game_opts.verbose:
            print("Toggle fullscreen!")

        # store the position of the mouse cursor
        mouse_position = pygame.mouse.get_pos()

        # toggle the fullscreen <-> window mode
        pygame.display.set_mode(
            (constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT), pygame.FULLSCREEN if self.game_opts.fullscreen else 0
        )

        # update the mouse cursor position
        pygame.mouse.set_pos(mouse_position)

    ## entry point for settings menu's toggle sounds option
    #
    # @param self the object pointer
    def _toggle_sounds_option(self):
        self.game_opts.sound = not self.game_opts.sound
        if self.game_opts.verbose:
            print("Toggle sounds!")

    ## entry point for settings menu's toggle music option
    #
    # @param self the object pointer
    def _toggle_music_option(self):
        if self.game_opts.verbose:
            print("Toggle music!")

        self.game_opts.music = not self.game_opts.music
        if self.game_opts.music:
            pygame.mixer.music.unpause()
        else:
            pygame.mixer.music.pause()

    ## entry point for settings menu's back option
    #
    # @param self the object pointer
    def _back_option(self):
        self.menu_settings_running = False
        if self.game_opts.verbose:
            print("Go back to main menu!")