コード例 #1
0
ファイル: main.py プロジェクト: grimfang/pyweek21
class Main(ShowBase, FSM):
    """Main function of the application
    initialise the engine (ShowBase)"""
    def __init__(self):
        """initialise the engine"""
        ShowBase.__init__(self)
        FSM.__init__(self, "FSM-Game")

        #
        # BASIC APPLICATION CONFIGURATIONS
        #
        # disable pandas default camera driver
        self.disableMouse()
        # set background color to black
        self.setBackgroundColor(0, 0, 0)
        # set antialias for the complete sceen to automatic
        self.render.setAntialias(AntialiasAttrib.MAuto)
        helper.hide_cursor()

        #
        # CONFIGURATION LOADING
        #
        # load given variables or set defaults
        # check if audio should be muted
        mute = ConfigVariableBool("audio-mute", False).getValue()
        if mute:
            self.disableAllAudio()
        else:
            self.enableAllAudio()

        def setFullscreen():
            """Helper function to set the window fullscreen
            with width and height set to the screens size"""
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set window properties
            # clear all properties not previously set
            base.win.clearRejectedProperties()
            # setup new window properties
            props = WindowProperties()
            # Fullscreen
            props.setFullscreen(True)
            # set the window size to the screen resolution
            props.setSize(w, h)
            # request the new properties
            base.win.requestProperties(props)

        # check if the config file hasn't been created
        if not os.path.exists(prcFile):
            setFullscreen()
        elif base.appRunner:
            # When the application is started as appRunner instance, it
            # doesn't respect our loadPrcFiles configurations specific
            # to the window as the window is already created, hence we
            # need to manually set them here.
            for dec in range(mainConfig.getNumDeclarations()):
                # check if we have the fullscreen variable
                if mainConfig.getVariableName(dec) == "fullscreen":
                    setFullscreen()
        # automatically safe configuration at application exit
        base.exitFunc = self.__writeConfig

        # due to the delayed window resizing and switch to fullscreen
        # we wait some time until everything is set so we can savely
        # proceed with other setups like the menus
        if base.appRunner:
            # this behaviour only happens if run from p3d files and
            # hence the appRunner is enabled
            taskMgr.doMethodLater(0.5,
                                  self.postInit,
                                  "post initialization",
                                  extraArgs=[])
        else:
            self.postInit()

    def postInit(self):
        #
        # initialize game content
        #

        # Menus
        self.mainmenu = Mainmenu()
        self.optionsmenu = Optionsmenu()
        self.loadingscreen = LoadingScreen()

        self.music_menu = loader.loadMusic("music/menu.ogg")
        self.music_menu.setLoop(True)
        self.music_game = loader.loadMusic("music/game.ogg")
        self.music_game.setLoop(True)
        self.music_intro = loader.loadMusic("music/logos.ogg")

        # The games Intro
        def create16To9LogoCard(logoPath, tsName):
            cm = CardMaker("fade")
            scale = abs(base.a2dLeft) / 1.7776
            cm.setFrame(-1, 1, -1 * scale, 1 * scale)
            logo = NodePath(cm.generate())
            logo.setTransparency(TransparencyAttrib.MAlpha)
            logoTex = loader.loadTexture(logoPath)
            logoTs = TextureStage(tsName)
            logoTs.setMode(TextureStage.MReplace)
            logo.setTexture(logoTs, logoTex)
            logo.setBin("fixed", 5000)
            logo.reparentTo(render2d)
            logo.hide()
            return logo

        self.gfLogo = create16To9LogoCard("intro/GrimFangLogo.png", "gfLogoTS")
        self.pandaLogo = create16To9LogoCard("intro/Panda3DLogo.png",
                                             "pandaLogoTS")
        self.gameLogo = create16To9LogoCard("intro/GameLogo.png", "gameLogoTS")

        def createFadeIn(logo):
            return LerpColorScaleInterval(logo, 2,
                                          LVecBase4f(0.0, 0.0, 0.0, 1.0),
                                          LVecBase4f(0.0, 0.0, 0.0, 0.0))

        def createFadeOut(logo):
            return LerpColorScaleInterval(logo, 2,
                                          LVecBase4f(0.0, 0.0, 0.0, 0.0),
                                          LVecBase4f(0.0, 0.0, 0.0, 1.0))

        gfFadeInInterval = createFadeIn(self.gfLogo)
        gfFadeOutInterval = createFadeOut(self.gfLogo)
        p3dFadeInInterval = createFadeIn(self.pandaLogo)
        p3dFadeOutInterval = createFadeOut(self.pandaLogo)
        gameFadeInInterval = createFadeIn(self.gameLogo)
        gameFadeOutInterval = createFadeOut(self.gameLogo)
        self.introFadeInOutSequence = Sequence(Func(self.music_intro.play),
                                               Func(self.gfLogo.show),
                                               gfFadeInInterval,
                                               Wait(1.0),
                                               gfFadeOutInterval,
                                               Wait(0.5),
                                               Func(self.gfLogo.hide),
                                               Func(self.pandaLogo.show),
                                               p3dFadeInInterval,
                                               Wait(1.0),
                                               p3dFadeOutInterval,
                                               Wait(0.5),
                                               Func(self.pandaLogo.hide),
                                               Func(self.gameLogo.show),
                                               gameFadeInInterval,
                                               Wait(1.0),
                                               gameFadeOutInterval,
                                               Wait(0.5),
                                               Func(self.gameLogo.hide),
                                               Func(self.messenger.send,
                                                    "intro_done"),
                                               Func(self.music_intro.stop),
                                               name="fadeInOut")
        # game intro end

        # collision setup
        base.cTrav = CollisionTraverser("base collision traverser")
        base.cTrav.setRespectPrevTransform(True)
        # setup default physics
        base.enableParticles()

        #
        # Event handling
        #
        self.accept("escape", self.__escape)
        # accept menu events
        self.accept("menu_start", self.request, ["Game"])
        self.accept("menu_options", self.request, ["Options"])
        self.accept("menu_quit", self.quit)
        self.accept("options_back", self.request, ["Menu"])
        # game over
        self.accept("GameOver", self.demand, ["Menu"])

        #
        # Start with the menu after the intro has been played
        #
        self.introFadeInOutSequence.start()
        self.accept("intro_done", self.request, ["Menu"])

    #
    # FSM PART
    #

    def enterMenu(self):
        """Enter the main menu state"""
        helper.show_cursor()
        self.mainmenu.show()
        if self.music_menu.status() != AudioSound.PLAYING:
            self.music_menu.play()

    def exitMenu(self):
        """Leave the main menu state"""
        self.mainmenu.hide()

    def enterOptions(self):
        """Enter the options menu state"""
        self.optionsmenu.show()

    def exitOptions(self):
        """Leave the options menu state"""
        self.optionsmenu.hide()

    def enterGame(self):
        # main game code should be called here
        print _("Enter Game")
        self.loadingscreen.start()
        helper.hide_cursor()
        self.world = World()
        self.music_menu.stop()
        self.music_game.play()
        self.loadingscreen.stop()

    def exitGame(self):
        # cleanup for game code
        print _("Exit Game")
        helper.show_cursor()
        self.world.stop()
        del self.world

    #
    # FSM PART END
    #

    #
    # BASIC FUNCTIONS
    #

    def __escape(self):
        if self.state == "Off":
            self.introFadeInOutSequence.finish()
        elif self.state == "Menu":
            self.quit()
        elif self.state == "Game":
            if self.world.requestEscape():
                self.request("Menu")
        else:
            self.request("Menu")

    def quit(self):
        """This function will stop the application"""
        self.userExit()

    def __writeConfig(self):
        """Save current config in the prc file or if no prc file exists
        create one. The prc file is set in the prcFile variable"""
        page = None

        volume = str(round(base.musicManager.getVolume(), 2))
        mute = "#f" if base.AppHasAudioFocus else "#t"
        customConfigVariables = ["", "audio-mute", "audio-volume"]
        if os.path.exists(prcFile):
            # open the config file and change values according to current
            # application settings
            page = loadPrcFile(Filename.fromOsSpecific(prcFile))
            removeDecls = []
            for dec in range(page.getNumDeclarations()):
                # Check if our variables are given.
                # NOTE: This check has to be done to not loose our base or other
                #       manual config changes by the user
                if page.getVariableName(dec) in customConfigVariables:
                    decl = page.modifyDeclaration(dec)
                    removeDecls.append(decl)
            for dec in removeDecls:
                page.deleteDeclaration(dec)
            # NOTE: audio-mute are custom variables and
            #       have to be loaded by hand at startup
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", mute)
        else:
            # Create a config file and set default values
            cpMgr = ConfigPageManager.getGlobalPtr()
            page = cpMgr.makeExplicitPage("%s Pandaconfig" % appName)
            # set OpenGL to be the default
            page.makeDeclaration("load-display", "pandagl")
            # get the displays width and height
            w = self.pipe.getDisplayWidth()
            h = self.pipe.getDisplayHeight()
            # set the window size in the config file
            page.makeDeclaration("win-size", "%d %d" % (w, h))
            # set the default to fullscreen in the config file
            page.makeDeclaration("fullscreen", "1")
            # audio
            page.makeDeclaration("audio-volume", volume)
            page.makeDeclaration("audio-mute", "#f")
        # create a stream to the specified config file
        configfile = OFileStream(prcFile)
        # and now write it out
        page.write(configfile)
        # close the stream
        configfile.close()