class Main(ShowBase, FSM): """Main function of the application initialise the engine (ShowBase)""" def __init__(self): """initialise the engine""" ShowBase.__init__(self) base.notify.info("Version {}".format(versionstring)) FSM.__init__(self, "FSM-Game") # # BASIC APPLICATION CONFIGURATIONS # # disable pandas default camera driver self.disableMouse() # set antialias for the complete sceen to automatic self.render.setAntialias(AntialiasAttrib.MAuto) # shader generator render.setShaderAuto() # Enhance font readability DGG.getDefaultFont().setPixelsPerUnit(100) # get the displays width and height for later usage self.dispWidth = self.pipe.getDisplayWidth() self.dispHeight = self.pipe.getDisplayHeight() # # CONFIGURATION LOADING # # load given variables or set defaults # check if particles should be enabled # NOTE: If you use the internal physics engine, this always has # to be enabled! particles = ConfigVariableBool("particles-enabled", True).getValue() if particles: self.enableParticles() def setFullscreen(): """Helper function to set the window fullscreen with width and height set to the screens size""" # 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(self.dispWidth, self.dispHeight) # request the new properties base.win.requestProperties(props) # Set the config variables so we correctly store the # new size and fullscreen setting later winSize = ConfigVariableString("win-size") winSize.setValue("{} {}".format(self.dispWidth, self.dispHeight)) fullscreen = ConfigVariableBool("fullscreen") fullscreen.setValue(True) # Render a frame to make sure the fullscreen is applied # before we do anything else self.taskMgr.step() # make sure to propagate the new aspect ratio properly so # the GUI and other things will be scaled appropriately aspectRatio = self.dispWidth / self.dispHeight self.adjustWindowAspectRatio(aspectRatio) # check if the config file hasn't been created if not os.path.exists(prcFile): setFullscreen() # automatically safe configuration at application exit #base.exitFunc = self.__writeConfig # # INITIALIZE GAME CONTENT # base.cTrav = CollisionTraverser("base collision traverser") base.pusher = CollisionHandlerPusher() self.menu = Menu() self.credits = Credits() self.charSelection = CharacterSelection() self.levelSelection = LevelSelection() self.koScreen = KoScreen() self.hud = Hud() self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg") self.menuMusic.setLoop(True) self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg") self.fightMusic.setLoop(True) base.audio3d = Audio3DManager(base.sfxManagerList[0], camera) # # EVENT HANDLING # # By default we accept the escape key self.accept("escape", self.__escape) # # ENTER GAMES INITIAL FSM STATE # self.request("Menu") # # FSM PART # def enterMenu(self): show_cursor() self.accept("Menu-Start", self.request, ["CharSelection"]) self.accept("Menu-Credits", self.request, ["Credits"]) self.accept("Menu-Quit", self.userExit) self.ignore("KoScreen-Back") self.koScreen.hide() self.menu.show() if self.menuMusic.status() != AudioSound.PLAYING: self.menuMusic.play() if self.fightMusic.status() == AudioSound.PLAYING: self.fightMusic.stop() def exitMenu(self): self.ignore("Menu-Start") self.ignore("Menu-Credits") self.ignore("Menu-Quit") self.menu.hide() def enterCredits(self): self.accept("Credits-Back", self.request, ["Menu"]) self.koScreen.hide() self.credits.show() def exitCredits(self): self.ignore("Credits-Back") self.credits.hide() def enterCharSelection(self): self.accept("CharSelection-Back", self.request, ["Menu"]) self.accept("CharSelection-Start", self.request, ["LevelSelection"]) self.charSelection.show() def exitCharSelection(self): self.ignore("CharSelection-Start") self.ignore("CharSelection-Back") self.charSelection.hide() self.selectedChar1 = self.charSelection.selectedCharacter1 self.selectedChar2 = self.charSelection.selectedCharacter2 def enterLevelSelection(self): self.accept("LevelSelection-Back", self.request, ["CharSelection"]) self.accept("LevelSelection-Start", self.request, ["Game"]) self.levelSelection.show() def exitLevelSelection(self): self.ignore("LevelSelection-Start") self.ignore("LevelSelection-Back") self.levelSelection.hide() def enterGame(self): # main game code should be called here self.arena = Arena(self.levelSelection.selectedLevel) self.arena.start() self.camera.setPos(0, -5, 1.25) self.player = Player(0, self.selectedChar1, "p1") self.player2 = Player(1, self.selectedChar2, "p2") self.player.setEnemy(self.player2.collisionNodeName) self.player2.setEnemy(self.player.collisionNodeName) self.player.start(self.arena.getStartPos(1)) self.player2.start(self.arena.getStartPos(2)) self.taskMgr.add(self.updateWorldCam, "world camera update task") self.accept("gameOver", self.gameOver) self.hud.show() def lifeChanged(charId, health): base.messenger.send("hud_setLifeBarValue", [charId, health]) self.accept("lifeChanged", lifeChanged) hide_cursor() if self.fightMusic.status() != AudioSound.PLAYING: self.fightMusic.play() if self.menuMusic.status() == AudioSound.PLAYING: self.menuMusic.stop() def exitGame(self): # cleanup for game code self.taskMgr.remove("world camera update task") self.player.stop() self.player2.stop() del self.player del self.player2 self.arena.stop() self.ignore("gameOver") self.ignore("lifeChanged") self.hud.hide() # # FSM PART END # # # BASIC FUNCTIONS # def gameOver(self, LoosingCharId): show_cursor() winningChar = 1 if LoosingCharId == 0: winningChar = 2 self.accept("KoScreen-Back", self.request, ["Credits"]) self.koScreen.show(winningChar) def updateWorldCam(self, task): playerVec = self.player.getPos() - self.player2.getPos() playerDist = playerVec.length() x = self.player.getX() + playerDist / 2.0 self.camera.setX(x) zoomout = False if not self.cam.node().isInView(self.player.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not self.cam.node().isInView(self.player2.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not zoomout: if self.camera.getY() < -5: camPosUpdate = 2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) return task.cont def __escape(self): """Handle user escape key klicks""" if self.state == "Menu": # In this state, we will stop the application self.userExit() elif self.state == "LevelSelection": self.request("CharSelection") else: # In every other state, we switch back to the Menu state self.request("Menu") 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 # #TODO: add any configuration variable names that you have added # to the dictionaries in the next lines. Set the current # configurations value as value in this dictionary and it's # name as key. configVariables = { # set the window size in the config file "win-size": ConfigVariableString( "win-size", "{} {}".format(self.dispWidth, self.dispHeight)).getValue(), # set the default to fullscreen in the config file "fullscreen": "#t" if ConfigVariableBool("fullscreen", True).getValue() else "#f", # particles "particles-enabled": "#t" if self.particleMgrEnabled else "#f", # audio "audio-volume": str(round(self.musicManager.getVolume(), 2)), "audio-music-active": "#t" if ConfigVariableBool("audio-music-active").getValue() else "#f", "audio-sfx-active": "#t" if ConfigVariableBool("audio-sfx-active").getValue() else "#f", # logging "notify-output": os.path.join(basedir, "game.log"), # window "framebuffer-multisample": "#t" if ConfigVariableBool("framebuffer-multisample").getValue() else "#f", "multisamples": str(ConfigVariableInt("multisamples", 8).getValue()), "texture-anisotropic-degree": str(ConfigVariableInt("texture-anisotropic-degree").getValue()), "textures-auto-power-2": "#t" if ConfigVariableBool("textures-auto-power-2", True).getValue() else "#f", } page = None # Check if we have an existing configuration file 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 configVariables.keys(): removeDecls.append(page.modifyDeclaration(dec)) for dec in removeDecls: page.deleteDeclaration(dec) else: # Create a config file and set default values cpMgr = ConfigPageManager.getGlobalPtr() page = cpMgr.makeExplicitPage("Application Config") # always write custom configurations for key, value in configVariables.items(): page.makeDeclaration(key, value) # create a stream to the specified config file configfile = OFileStream(prcFile) # and now write it out page.write(configfile) # close the stream configfile.close()
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) # shader generator render.setShaderAuto() # # 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() # check if particles should be enabled particles = ConfigVariableBool("particles-enabled", True).getValue() if particles: self.enableParticles() # check if the config file hasn't been created if not os.path.exists(prcFile): # 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) elif base.appRunner: # As when the application is started as appRunner instance # it doesn't respect our loadPrcFile configurations specific # to the window, hence we need to manually set them here. for dec in range(mainConfig.getNumDeclarations()): #TODO: Check for all window specific variables like # fullscreen, screen size, title and window # decoration that you have in your configuration # and set them by your own. if mainConfig.getVariableName(dec) == "fullscreen": if not mainConfig.getDeclaration(dec).getBoolWord(0): break # 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) break # 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 # base.cTrav = CollisionTraverser("base collision traverser") base.pusher = CollisionHandlerPusher() self.menu = Menu() self.credits = Credits() self.charSelection = CharacterSelection() self.levelSelection = LevelSelection() self.koScreen = KoScreen() self.hud = Hud() self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg") self.menuMusic.setLoop(True) self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg") self.fightMusic.setLoop(True) base.audio3d = Audio3DManager(base.sfxManagerList[0], camera) # # Event handling # self.accept("escape", self.__escape) # # Start with the menu # self.request("Menu") # # FSM PART # def enterMenu(self): show_cursor() self.accept("Menu-Start", self.request, ["CharSelection"]) self.accept("Menu-Credits", self.request, ["Credits"]) self.accept("Menu-Quit", self.quit) self.ignore("KoScreen-Back") self.koScreen.hide() self.menu.show() if self.menuMusic.status() != AudioSound.PLAYING: self.menuMusic.play() if self.fightMusic.status() == AudioSound.PLAYING: self.fightMusic.stop() def exitMenu(self): self.ignore("Menu-Start") self.ignore("Menu-Credits") self.ignore("Menu-Quit") self.menu.hide() def enterCredits(self): self.accept("Credits-Back", self.request, ["Menu"]) self.koScreen.hide() self.credits.show() def exitCredits(self): self.ignore("Credits-Back") self.credits.hide() def enterCharSelection(self): self.accept("CharSelection-Back", self.request, ["Menu"]) self.accept("CharSelection-Start", self.request, ["LevelSelection"]) self.charSelection.show() def exitCharSelection(self): self.ignore("CharSelection-Start") self.ignore("CharSelection-Back") self.charSelection.hide() self.selectedChar1 = self.charSelection.selectedCharacter1 self.selectedChar2 = self.charSelection.selectedCharacter2 def enterLevelSelection(self): self.accept("LevelSelection-Back", self.request, ["CharSelection"]) self.accept("LevelSelection-Start", self.request, ["Game"]) self.levelSelection.show() def exitLevelSelection(self): self.ignore("LevelSelection-Start") self.ignore("LevelSelection-Back") self.levelSelection.hide() def enterGame(self): # main game code should be called here self.arena = Arena(self.levelSelection.selectedLevel) self.arena.start() self.camera.setPos(0, -5, 1.25) self.player = Player(0, self.selectedChar1, "p1") self.player2 = Player(1, self.selectedChar2, "p2") self.player.setEnemy(self.player2.collisionNodeName) self.player2.setEnemy(self.player.collisionNodeName) self.player.start(self.arena.getStartPos(1)) self.player2.start(self.arena.getStartPos(2)) self.taskMgr.add(self.updateWorldCam, "world camera update task") self.accept("gameOver", self.gameOver) self.hud.show() def lifeChanged(charId, health): base.messenger.send("hud_setLifeBarValue", [charId, health]) self.accept("lifeChanged", lifeChanged) hide_cursor() if self.fightMusic.status() != AudioSound.PLAYING: self.fightMusic.play() if self.menuMusic.status() == AudioSound.PLAYING: self.menuMusic.stop() def exitGame(self): # cleanup for game code self.taskMgr.remove("world camera update task") self.player.stop() self.player2.stop() del self.player del self.player2 self.arena.stop() self.ignore("gameOver") self.ignore("lifeChanged") self.hud.hide() # # FSM PART END # # # BASIC FUNCTIONS # def gameOver(self, LoosingCharId): show_cursor() winningChar = 1 if LoosingCharId == 0: winningChar = 2 self.accept("KoScreen-Back", self.request, ["Credits"]) self.koScreen.show(winningChar) def updateWorldCam(self, task): playerVec = self.player.getPos() - self.player2.getPos() playerDist = playerVec.length() x = self.player.getX() + playerDist / 2.0 self.camera.setX(x) zoomout = False if not self.cam.node().isInView(self.player.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not self.cam.node().isInView(self.player2.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not zoomout: if self.camera.getY() < -5: camPosUpdate = 2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) return task.cont def __escape(self): if self.state == "Menu": self.quit() elif self.state == "LevelSelection": self.request("CharSelection") 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 #TODO: get values of configurations here particles = "#f" if not base.particleMgrEnabled else "#t" volume = str(round(base.musicManager.getVolume(), 2)) mute = "#f" if base.AppHasAudioFocus else "#t" #TODO: add any configuration variable name that you have added customConfigVariables = [ "", "particles-enabled", "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: particles-enabled and audio-mute are custom variables and # have to be loaded by hand at startup # Particles page.makeDeclaration("particles-enabled", particles) # 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") # particles page.makeDeclaration("particles-enabled", "#t") # 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()
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) # shader generator render.setShaderAuto() # # 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() # check if particles should be enabled particles = ConfigVariableBool("particles-enabled", True).getValue() if particles: self.enableParticles() # check if the config file hasn't been created if not os.path.exists(prcFile): # 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) elif base.appRunner: # As when the application is started as appRunner instance # it doesn't respect our loadPrcFile configurations specific # to the window, hence we need to manually set them here. for dec in range(mainConfig.getNumDeclarations()): #TODO: Check for all window specific variables like # fullscreen, screen size, title and window # decoration that you have in your configuration # and set them by your own. if mainConfig.getVariableName(dec) == "fullscreen": if not mainConfig.getDeclaration(dec).getBoolWord(0): break # 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) break # 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 # base.cTrav = CollisionTraverser("base collision traverser") base.pusher = CollisionHandlerPusher() self.menu = Menu() self.credits = Credits() self.charSelection = CharacterSelection() self.levelSelection = LevelSelection() self.koScreen = KoScreen() self.hud = Hud() self.menuMusic = loader.loadMusic("assets/audio/menuMusic.ogg") self.menuMusic.setLoop(True) self.fightMusic = loader.loadMusic("assets/audio/fightMusic.ogg") self.fightMusic.setLoop(True) base.audio3d = Audio3DManager(base.sfxManagerList[0], camera) # # Event handling # self.accept("escape", self.__escape) # # Start with the menu # self.request("Menu") # # FSM PART # def enterMenu(self): show_cursor() self.accept("Menu-Start", self.request, ["CharSelection"]) self.accept("Menu-Credits", self.request, ["Credits"]) self.accept("Menu-Quit", self.quit) self.ignore("KoScreen-Back") self.koScreen.hide() self.menu.show() if self.menuMusic.status() != AudioSound.PLAYING: self.menuMusic.play() if self.fightMusic.status() == AudioSound.PLAYING: self.fightMusic.stop() def exitMenu(self): self.ignore("Menu-Start") self.ignore("Menu-Credits") self.ignore("Menu-Quit") self.menu.hide() def enterCredits(self): self.accept("Credits-Back", self.request, ["Menu"]) self.koScreen.hide() self.credits.show() def exitCredits(self): self.ignore("Credits-Back") self.credits.hide() def enterCharSelection(self): self.accept("CharSelection-Back", self.request, ["Menu"]) self.accept("CharSelection-Start", self.request, ["LevelSelection"]) self.charSelection.show() def exitCharSelection(self): self.ignore("CharSelection-Start") self.ignore("CharSelection-Back") self.charSelection.hide() self.selectedChar1 = self.charSelection.selectedCharacter1 self.selectedChar2 = self.charSelection.selectedCharacter2 def enterLevelSelection(self): self.accept("LevelSelection-Back", self.request, ["CharSelection"]) self.accept("LevelSelection-Start", self.request, ["Game"]) self.levelSelection.show() def exitLevelSelection(self): self.ignore("LevelSelection-Start") self.ignore("LevelSelection-Back") self.levelSelection.hide() def enterGame(self): # main game code should be called here self.arena = Arena(self.levelSelection.selectedLevel) self.arena.start() self.camera.setPos(0, -5, 1.25) self.player = Player(0, self.selectedChar1, "p1") self.player2 = Player(1, self.selectedChar2, "p2") self.player.setEnemy(self.player2.collisionNodeName) self.player2.setEnemy(self.player.collisionNodeName) self.player.start(self.arena.getStartPos(1)) self.player2.start(self.arena.getStartPos(2)) self.taskMgr.add(self.updateWorldCam, "world camera update task") self.accept("gameOver", self.gameOver) self.hud.show() def lifeChanged(charId, health): base.messenger.send( "hud_setLifeBarValue", [charId, health]) self.accept("lifeChanged", lifeChanged) hide_cursor() if self.fightMusic.status() != AudioSound.PLAYING: self.fightMusic.play() if self.menuMusic.status() == AudioSound.PLAYING: self.menuMusic.stop() def exitGame(self): # cleanup for game code self.taskMgr.remove("world camera update task") self.player.stop() self.player2.stop() del self.player del self.player2 self.arena.stop() self.ignore("gameOver") self.ignore("lifeChanged") self.hud.hide() # # FSM PART END # # # BASIC FUNCTIONS # def gameOver(self, LoosingCharId): show_cursor() winningChar = 1 if LoosingCharId == 0: winningChar = 2 self.accept("KoScreen-Back", self.request, ["Credits"]) self.koScreen.show(winningChar) def updateWorldCam(self, task): playerVec = self.player.getPos() - self.player2.getPos() playerDist = playerVec.length() x = self.player.getX() + playerDist / 2.0 self.camera.setX(x) zoomout = False if not self.cam.node().isInView(self.player.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not self.cam.node().isInView(self.player2.getPos(self.cam)): camPosUpdate = -2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) zoomout = True if not zoomout: if self.camera.getY() < -5: camPosUpdate = 2 * globalClock.getDt() self.camera.setY(self.camera, camPosUpdate) return task.cont def __escape(self): if self.state == "Menu": self.quit() elif self.state == "LevelSelection": self.request("CharSelection") 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 #TODO: get values of configurations here particles = "#f" if not base.particleMgrEnabled else "#t" volume = str(round(base.musicManager.getVolume(), 2)) mute = "#f" if base.AppHasAudioFocus else "#t" #TODO: add any configuration variable name that you have added customConfigVariables = [ "", "particles-enabled", "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: particles-enabled and audio-mute are custom variables and # have to be loaded by hand at startup # Particles page.makeDeclaration("particles-enabled", particles) # 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") # particles page.makeDeclaration("particles-enabled", "#t") # 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()