Esempio n. 1
0
class Main(object):
    """
    The main class, load some parameters, sets initial states and takes care of
    the game main loop.
    """

    def __init__(self, players=None, level=None):
        """
        The constructor, create the render surface, set the menu initial state,
        parse command line params if any, launch the menu or the game depending
        on parameters.

        The init parameter determines if the Main object should be initialized
        once instanciated. The run parameter determines if the game should be run
        once the object is instantiated and initiated.

        """
        self.lock = threading.Lock()
        self.stop_thread = False
        self.text_thread = _("Loading...")

        self.level = level
        if players is None:
            self.players = []

        self.init()
        self.run()

    def init(self):
        pygame.init()
        self.clock = pygame.time.Clock()
        self.controls = Controls()
        self.initialized = False

        try:
            self.init_standalone()
            self.initialized = True
        except:
            self.stop_thread = True
            self.initialized = False
            raise

    def init_standalone(self):
        '''
        start a non network instance of the game
        '''

        self.init_screen()
        self.text_thread = "Loading sounds and musics..."
        thread = threading.Thread(None, self.loading_screen)
        thread.start()

        self.init_sound()
        self.ai_instance = AI()

        # if a level was provided and at least two players in the option
        # immediatly jump into game mode
        if len(self.players) > 1 and self.level is not None:
            self.game = Game(self.screen, self.level, self.players)
            self.state = "game"
            self.menu = Gui(self.screen)
            self.menu.handle_reply({'goto': 'configure'})
        else:
            self.lock.acquire()
            self.text_thread = "Loading GUI..."
            self.lock.release()

            self.menu = Gui(self.screen)

            self.state = "menu"

            self.game = None
            self.level = None

        self.lock.acquire()
        self.stop_thread = True
        self.lock.release()
        thread.join()
        # end of loading resources



    def init_screen(self):
        """ various screen initialisations
        """
        size = (CONFIG.general.WIDTH, CONFIG.general.HEIGHT)
        if (CONFIG.general.WIDTH, CONFIG.general.HEIGHT) == (0, 0):
            if (800, 600) in pygame.display.list_modes():
                (CONFIG.general.WIDTH, CONFIG.general.HEIGHT) = (800, 600)

            else:
                #the old default value...
                (CONFIG.general.WIDTH, CONFIG.general.HEIGHT) = (800, 480)
            CONFIG.display.FULLSCREEN = False

        size = (CONFIG.general.WIDTH, CONFIG.general.HEIGHT)
        self.screen = pygame.display.set_mode(size)

        pygame.display.set_caption('Ultimate Smash Friends')
        icon = loaders.image(os.path.join(CONFIG.system_path, 'icon',
                                          'icon_50.png'))[0]
        pygame.display.set_icon(icon)
        if CONFIG.display.FULLSCREEN:
            pygame.display.toggle_fullscreen()

    def init_sound(self):
        """ various audio initialisations
        """
        self.music = Music()

    def manage_menu(self):
        """ manage input and update menu if we are in the menu state
        """
        # return of the menu update function may contain a new game
        # instance to switch to.
        start_loop = pygame.time.get_ticks()
        menu_was = self.menu.current_screen
        newgame, game_ = self.menu.update()
        if menu_was == 'keyboard' and self.menu.current_screen != 'keyboard':
            self.controls.load_keys()
            self.controls.load_sequences()

        if newgame:
            self.state = 'game'
            if game_ is not self.game:
                print "starting game"
                self.ai_instance = AI()

                del(self.game)
                self.game = game_

        max_fps = 1000/CONFIG.general.MAX_GUI_FPS

        if self.menu.current_screen == 'about':
            self.music_state = 'credits'
        else:
            self.music_state = self.state

        if pygame.time.get_ticks() < max_fps + start_loop:
            pygame.time.wait(max_fps + start_loop - pygame.time.get_ticks())

    def manage_ai(self):
        """ update the ai
        """
        for i, p in enumerate(self.game.players):
            if p.ai and p.present:
                self.ai_instance.update(self.game, i)

    def manage_game(self, dt):
        """ call the various submethod to update the whole game and render it
	    to the screen
        """
        #d = self.game.update_clock(was_paused or self.game.first_frame)
        self.state = self.game.update(dt)
        self.manage_ai()

        if self.state in ('game', 'victory'):
            self.game.draw(
                debug_params={
                    'controls': CONFIG.debug.CONTROLS and self.controls,
                    'action': CONFIG.debug.ACTIONS,
                    'hardshape': CONFIG.debug.HARDSHAPES,
                    'footrect': CONFIG.debug.FOOTRECT,
                    'current_animation': CONFIG.debug.CURRENT_ANIMATION,
                    'levelshape': CONFIG.debug.LEVELSHAPES,
                    'levelmap': CONFIG.debug.LEVELMAP})

            self.menu.load = False
        else:
            self.menu.current_screen = "main_screen"

        self.music_state = self.state

    def display_fps(self):
        """ FPS counter
        """
        if CONFIG.display.SHOW_FPS:
            self.screen.blit(
                    loaders.text(
                        "FPS: " + str(self.clock.get_fps()),
                        fonts["mono"]["38"]),
                    (10, 5))

    def run(self):
        """
        The main game loop, take care of the state of the game/menu.
        """

        if not self.initialized:
            return False

        pygame.mouse.set_visible(False)
        self.clock.tick()

        while (True):
            # poll controls and update informations on current state of the UI
            state_was = self.state

            if self.game:
                dt = self.clock.tick(CONFIG.general.MAX_FPS) / 1000.0
            else:
                dt = self.clock.tick(CONFIG.general.MAX_GUI_FPS) / 1000.0

            if self.state != "menu":
                self.state = self.controls.poll( self.game, self.menu)

            # this depends on the previous assertion, it's NOT an elif
            if self.state == "menu":
                self.manage_menu()

            else:
                # update the fps counter
                if state_was == "menu":
                    dt = 0

                self.manage_game(dt)

            self.display_fps()
            pygame.display.update()

            if CONFIG.audio.MUSIC:
                self.music.update(self.music_state)

            # verify there is not a QUIT event waiting for us, in case of we
            # have to quit.
            self.ended = pygame.event.get(QUIT)
            if self.ended:
                logging.debug('fps = '+str(self.clock.get_fps()))
                pygame.quit()
                break

    def loading_screen(self):
        """
        update the screen display during loading
        """
        while not self.stop_thread:
            self.lock.acquire()
            text = loaders.paragraph(self.text_thread, fonts['mono']['normal'])
            self.lock.release()

            x = self.screen.get_width()/2 - text.get_width()/2
            y = self.screen.get_height()/2 - text.get_height()/2

            self.screen.fill(pygame.color.Color("black"))
            self.screen.blit(text, (x, y))
            pygame.display.update()

            pygame.time.wait(10)
Esempio n. 2
0
 def init_sound(self):
     """ various audio initialisations
     """
     self.music = Music()