class Game(): def __init__(self, _parent=None): self.parent = _parent # Containers self.game_objects = {} self.game_doors = {} self.game_objects_np = render.attachNewNode("Game_Objects") self.game_doors_np = render.attachNewNode("Player_Doors") self.game_doors_np.setPos(0, 0, 0) self.game_counter_node = None self.game_collector_nodes = [] self.redDudesCount = 0 self.blueDudesCount = 0 # Physics world self.physics_world = None self.builder = Builder(self) # level lights self.directLight = None # Dude class self.dude = None self.spawnPoints = self.builder.spawnPoints # HUD self.hud = Hud() # Lightshow self.elapsed = 0.0 def start(self, levelID, winCondition=25): self.winCondition = winCondition self.loadLevel("assets/level{}".format(levelID)) self.loadLights() # player self.loadPlayer("default") self.loadDude() # Timer taskMgr.add(self.update, "Game_Update_Task", 0) self.hud.show() # start the Lightshow taskMgr.add(self.discoLightTask, "the lightshow") def stop(self): self.player.stop() self.dude.stop() self.builder.cleanup() self.physics_world = None render.clearLight() self.directLight = None self.hud.hide() taskMgr.remove("the lightshow") def update(self, task): if self.game_counter_node is None: return ghost = self.game_counter_node.node() for node in ghost.getOverlappingNodes(): if "red" in node.name: self.redDudesCount += 1 self.physics_world.removeRigidBody(self.dude.dudes[node.name].node()) self.dude.dudes[node.name].removeNode() self.hud.update(self.redDudesCount, self.blueDudesCount) del self.dude.dudes[node.name] break elif "blue" in node.name: self.blueDudesCount += 1 self.physics_world.removeRigidBody(self.dude.dudes[node.name].node()) self.dude.dudes[node.name].removeNode() self.hud.update(self.redDudesCount, self.blueDudesCount) del self.dude.dudes[node.name] break if self.redDudesCount > self.blueDudesCount: base.messenger.send("lostGame") return Task.done elif self.blueDudesCount >= self.winCondition: base.messenger.send("wonGame") return Task.done for collectorGhostNP in self.game_collector_nodes: collectorGhost = collectorGhostNP.node() for node in collectorGhost.getOverlappingNodes(): if "red" in node.name: self.physics_world.removeRigidBody(self.dude.dudes[node.name].node()) self.dude.dudes[node.name].removeNode() self.hud.update(self.redDudesCount, self.blueDudesCount) del self.dude.dudes[node.name] return Task.cont def setPhysicsWorld(self, _physicsworld): self.physics_world = _physicsworld #### LOADERS #### def loadLevel(self, _filename): self.builder.parseEggFile(_filename) def loadLights(self): # Set a simple light dlight = DirectionalLight('DirectLight') dlnp = render.attachNewNode(dlight) dlnp.setHpr(-30, 0, 0) render.setLight(dlnp) self.directLight = dlnp self.discoLights = [] p1 = PointLight("PointLight1") p1.setColor(VBase4(1, 0, 0, 1)) p1.setAttenuation((0.08, 0, 0.05)) p1np = render.attachNewNode(p1) p1np.setPos(0, -5, 0) render.setLight(p1np) self.discoLights.append(p1) p2 = PointLight("PointLight2") p2.setColor(VBase4(0, 1, 0, 1)) p2.setAttenuation((0.08, 0, 0.05)) p2np = render.attachNewNode(p2) p2np.setPos(5, -5, 0) render.setLight(p2np) self.discoLights.append(p2) p3 = PointLight("PointLight3") p3.setColor(VBase4(0, 0, 1, 1)) p3.setAttenuation((0.08, 0, 0.05)) p3np = render.attachNewNode(p3) p3np.setPos(-5, -5, 0) render.setLight(p3np) self.discoLights.append(p3) p4 = PointLight("PointLight4") p4.setColor(VBase4(0, 0, 1, 1)) p4.setAttenuation((0.08, 0, 0.05)) p4np = render.attachNewNode(p4) p4np.setPos(-5, -5, 5) render.setLight(p4np) self.discoLights.append(p4) p5 = PointLight("PointLight1") p5.setColor(VBase4(0, 0, 1, 1)) p5.setAttenuation((0.08, 0, 0.05)) p5np = render.attachNewNode(p5) p5np.setPos(0, -5, 5) render.setLight(p5np) self.discoLights.append(p5) p6 = PointLight("PointLight1") p6.setColor(VBase4(0, 0, 1, 1)) p6.setAttenuation((0.08, 0, 0.05)) p6np = render.attachNewNode(p6) p6np.setPos(5, -5, 5) render.setLight(p6np) self.discoLights.append(p6) def discoLightTask(self, task): self.elapsed += globalClock.getDt() if self.elapsed > 0.75: for light in self.discoLights: newcolor = choice( [VBase4(0, 0, 1, 1), VBase4(0, 1, 0, 1), VBase4(1, 0, 0, 1), VBase4(0, 1, 1, 1), VBase4(1, 0, 1, 1), VBase4(1, 1, 0, 1),] ) light.setColor(newcolor) self.elapsed = 0.0 return task.cont def loadPlayer(self, _name): self.player = Player(self) self.player.start() def loadDude(self): self.dude = Dude(self) self.dude.start()
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 Game(GameState): def do_setup(self, level): super(Game, self).do_setup() self.level = level self.setup_panda() self.level.setup_entities(self.entities) self.setup_input() self.setup_controllers() self.setup_hud() self.setup_logic() self.enter_transition() self.events.event('panda-escape').connect(self.enter_menu) self.events.event('panda-p').connect(self.toggle_pause) self.manager.enter_state( GameMessage, message=(('You have to kill %i pigeons in this level...\n' + 'Can you make it?') % self.total_pigeons)) def enter_transition(self): self._transition_bg = ui.ImageEntity(entities=self.entities, image='hud/red-bg.png') self._transition_bg.alpha = 1.0 self._transition_bg.fade_out() def leave_transition(self, next_st='menu'): self._transition_bg.fade_in().add_next( task.run(lambda: self.manager.leave_state(last_state=next_st))) def enter_menu(self): self.manager.enter_state('menu-noload', None, 'ingame') @weak_slot def on_kill_pigeon(self): self.hud.dec_counter('pigeons', 1) self.dead_pigeons += 1 if self.dead_pigeons >= self.total_pigeons: self.win_game() @weak_slot def on_kill_boy(self): self.fail_game( random.choice([ 'You are dead!', 'Was it that hard to stay alive?', "Your soul is burning in hell..." ])) @weak_slot def on_finish_time(self): self.fail_game( random.choice([ 'No more time for you!', 'Too slow man...', 'Hurry up the next time!' ])) def win_game(self): if self.manager.current == self: self.manager.enter_state( GameMessage, 'YOU WON!\n' 'This was a show-case level of an in-development game,\n' 'there is more to come in the future.', 'quit') def fail_game(self, reason): if self.manager.current == self: msg = random.choice([ 'LOOOOOOOOSER', 'You lost!', 'What a pity!', 'Hey, no luck today!' ]) self.manager.enter_state(GameMessage, reason + '\n' + msg, 'retry') @weak_slot def on_place_stick(self): if self.player_ctl.can_place_stick: self.num_sticks -= 1 if self.num_sticks == 0: self.player_ctl.can_place_stick = False self.hud.set_counter('sticks', self.num_sticks) def highlight_stick_task(self, timer): pos = self.player_ctl.get_place_position(5) best = self.player_ctl.laser.best_stick(pos) if best != self._curr_best_stick: if self._curr_best_stick: self._curr_best_stick.unhighlight() if self.player_ctl.can_place_stick: self._curr_best_stick = best if best: best.highlight() return task.running def do_update(self, timer): super(Game, self).do_update(timer) @weak_slot def on_shader_change(self, cfg): if cfg.value: self.glow_filter.enable(self.manager.panda) else: self.glow_filter.disable() @weak_slot def on_control_change(self, cfg): self.player_input.unassoc_action(cfg.name) if cfg.value: self.player_input.assoc(cfg.name, cfg.value) def setup_panda(self): self.glow_filter = shader.GlowFilter() panda = self.manager.panda if GlobalConf().path('game.shader').value: self.glow_filter.enable(panda) panda.relative_mouse() panda.loop_music(self.level.music) def setup_input(self): self.player_input = GameInput() self.camera_input = GameInput(CAMERA_INPUT_MAP) self.events.connect(self.player_input) self.events.connect(self.camera_input) self.tasks.add(self.player_input) self.tasks.add(self.camera_input) self.player_input.assoc('on_steer', 'panda-mouse-move') cfg = GlobalConf().path('game.player0.keys') for c in cfg.childs(): if c.value: self.player_input.assoc(c.name, c.value) c.on_conf_change += self.on_control_change GlobalConf ().path ('game.shader').on_conf_change += \ self.on_shader_change def setup_controllers(self): self.camera_ctl = CameraController(entities=self.entities, camera=base.camera) self.player_ctl = PlayerController(entities=self.entities, delegate=self.level.boy) self.level.boy.connect(self.camera_ctl) self.camera_input.connect(self.camera_ctl) self.player_input.connect(self.player_ctl) def setup_hud(self): self.hud = Hud(entities=self.entities) self.hud.add_counter('clock', 'hud/clock.png') self.hud.add_counter('pigeons', 'hud/pigeon.png') self.hud.add_counter('sticks', 'hud/stick.png') self.hud.hide() def setup_logic(self): total_pigeons = 0 for f in self.level.flocks: total_pigeons += len(f.boids) for b in f.boids: b.on_death += self.on_kill_pigeon self.total_pigeons = total_pigeons self.dead_pigeons = 0 self.level.boy.on_death += self.on_kill_boy self.num_sticks = self.level.max_sticks self.player_ctl.on_place_stick_down += self.on_place_stick self.hud.set_counter('sticks', self.num_sticks) self.timer = self.tasks.add( task.TimerTask(duration=self.level.max_time)) self.timer.on_tick = lambda: self.hud.set_counter( 'clock', int(self.timer.remaining)) self.timer.on_finish = self.on_finish_time self.tasks.add(self.highlight_stick_task) self._curr_best_stick = None self.pigeon_food = [] def do_sink(self): super(Game, self).do_sink() if self.manager.current.state_name == 'menu-noload': for x in self.entities.entities: if isinstance(x, task.Task): x.pause() self.events.quiet = True self.hud.soft_hide() self.timer.pause() def do_unsink(self, action='continue'): super(Game, self).do_unsink() self.manager.panda.relative_mouse() self.tasks.resume() for x in self.entities.entities: if isinstance(x, task.Task): x.resume() if action == 'continue': self.events.quiet = False self.hud.soft_show() self.timer.resume() elif action == 'quit': self.leave_transition() elif action == 'retry': self.leave_transition('game') def do_release(self): self.level.dispose() # TODO: To entity! self.glow_filter.disable() super(Game, self).do_release()
class Game (GameState): def do_setup (self, level): super (Game, self).do_setup () self.level = level self.setup_panda () self.level.setup_entities (self.entities) self.setup_input () self.setup_controllers () self.setup_hud () self.setup_logic () self.enter_transition () self.events.event ('panda-escape').connect (self.enter_menu) self.events.event ('panda-p').connect (self.toggle_pause) self.manager.enter_state ( GameMessage, message = (('You have to kill %i pigeons in this level...\n' + 'Can you make it?') % self.total_pigeons)) def enter_transition (self): self._transition_bg = ui.ImageEntity (entities = self.entities, image = 'hud/red-bg.png') self._transition_bg.alpha = 1.0 self._transition_bg.fade_out () def leave_transition (self, next_st = 'menu'): self._transition_bg.fade_in ().add_next (task.run (lambda: self.manager.leave_state (last_state = next_st))) def enter_menu (self): self.manager.enter_state ('menu-noload', None, 'ingame') @weak_slot def on_kill_pigeon (self): self.hud.dec_counter ('pigeons', 1) self.dead_pigeons += 1 if self.dead_pigeons >= self.total_pigeons: self.win_game () @weak_slot def on_kill_boy (self): self.fail_game (random.choice (['You are dead!', 'Was it that hard to stay alive?', "Your soul is burning in hell..."])) @weak_slot def on_finish_time (self): self.fail_game (random.choice (['No more time for you!', 'Too slow man...', 'Hurry up the next time!'])) def win_game (self): if self.manager.current == self: self.manager.enter_state ( GameMessage, 'YOU WON!\n' 'This was a show-case level of an in-development game,\n' 'there is more to come in the future.', 'quit') def fail_game (self, reason): if self.manager.current == self: msg = random.choice (['LOOOOOOOOSER', 'You lost!', 'What a pity!', 'Hey, no luck today!']) self.manager.enter_state (GameMessage, reason + '\n' + msg, 'retry') @weak_slot def on_place_stick (self): if self.player_ctl.can_place_stick: self.num_sticks -= 1 if self.num_sticks == 0: self.player_ctl.can_place_stick = False self.hud.set_counter ('sticks', self.num_sticks) def highlight_stick_task (self, timer): pos = self.player_ctl.get_place_position (5) best = self.player_ctl.laser.best_stick (pos) if best != self._curr_best_stick: if self._curr_best_stick: self._curr_best_stick.unhighlight () if self.player_ctl.can_place_stick: self._curr_best_stick = best if best: best.highlight () return task.running def do_update (self, timer): super (Game, self).do_update (timer) @weak_slot def on_shader_change (self, cfg): if cfg.value: self.glow_filter.enable (self.manager.panda) else: self.glow_filter.disable () @weak_slot def on_control_change (self, cfg): self.player_input.unassoc_action (cfg.name) if cfg.value: self.player_input.assoc (cfg.name, cfg.value) def setup_panda (self): self.glow_filter = shader.GlowFilter () panda = self.manager.panda if GlobalConf ().path ('game.shader').value: self.glow_filter.enable (panda) panda.relative_mouse () panda.loop_music (self.level.music) def setup_input (self): self.player_input = GameInput () self.camera_input = GameInput (CAMERA_INPUT_MAP) self.events.connect (self.player_input) self.events.connect (self.camera_input) self.tasks.add (self.player_input) self.tasks.add (self.camera_input) self.player_input.assoc ('on_steer', 'panda-mouse-move') cfg = GlobalConf ().path ('game.player0.keys') for c in cfg.childs (): if c.value: self.player_input.assoc (c.name, c.value) c.on_conf_change += self.on_control_change GlobalConf ().path ('game.shader').on_conf_change += \ self.on_shader_change def setup_controllers (self): self.camera_ctl = CameraController ( entities = self.entities, camera = base.camera) self.player_ctl = PlayerController ( entities = self.entities, delegate = self.level.boy) self.level.boy.connect (self.camera_ctl) self.camera_input.connect (self.camera_ctl) self.player_input.connect (self.player_ctl) def setup_hud (self): self.hud = Hud (entities = self.entities) self.hud.add_counter ('clock', 'hud/clock.png') self.hud.add_counter ('pigeons', 'hud/pigeon.png') self.hud.add_counter ('sticks', 'hud/stick.png') self.hud.hide () def setup_logic (self): total_pigeons = 0 for f in self.level.flocks: total_pigeons += len (f.boids) for b in f.boids: b.on_death += self.on_kill_pigeon self.total_pigeons = total_pigeons self.dead_pigeons = 0 self.level.boy.on_death += self.on_kill_boy self.num_sticks = self.level.max_sticks self.player_ctl.on_place_stick_down += self.on_place_stick self.hud.set_counter ('sticks', self.num_sticks) self.timer = self.tasks.add ( task.TimerTask (duration = self.level.max_time)) self.timer.on_tick = lambda: self.hud.set_counter ( 'clock', int (self.timer.remaining)) self.timer.on_finish = self.on_finish_time self.tasks.add (self.highlight_stick_task) self._curr_best_stick = None self.pigeon_food = [] def do_sink (self): super (Game, self).do_sink () if self.manager.current.state_name == 'menu-noload': for x in self.entities.entities: if isinstance (x, task.Task): x.pause () self.events.quiet = True self.hud.soft_hide () self.timer.pause () def do_unsink (self, action = 'continue'): super (Game, self).do_unsink () self.manager.panda.relative_mouse () self.tasks.resume () for x in self.entities.entities: if isinstance (x, task.Task): x.resume () if action == 'continue': self.events.quiet = False self.hud.soft_show () self.timer.resume () elif action == 'quit': self.leave_transition () elif action == 'retry': self.leave_transition ('game') def do_release (self): self.level.dispose () # TODO: To entity! self.glow_filter.disable () super (Game, self).do_release ()
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 Game(GameBase, FSM): def __init__(self): GameBase.__init__(self, debug=False) FSM.__init__(self, "GUI FSM") base.disableMouse() self.menu = Menu() self.missionScreen = MissionScreen() self.debrief = Debrief() self.hud = Hud() self.missionSelect = MissionSelect() base.camLens.setFov(90) self.setMusic("audio/music.mp3", volume=0.5) self.setMusic("audio/engine1.wav", volume=0.3) self.request("Menu") base.taskMgr.add(self.missionOverTask, "is mission over") def enterMenu(self): self.menu.show() self.accept("menu-start", self.request, ["MissionSelect"]) self.accept("menu-instructions", self.request, ["Instructions"]) self.accept("menu-quit", sys.exit) def exitMenu(self): self.menu.hide() self.ignore("menu-start") self.ignore("menu-instructions") self.ignore("menu-quit") def enterMissionSelect(self): self.missionSelect.show() self.accept("missionselect-m1", self.setMission, ["m1"]) self.accept("missionselect-m2", self.setMission, ["m2"]) self.accept("missionselect-test", self.setMission, ["test"]) def exitMissionSelect(self): self.missionSelect.hide() self.ignore("missionselect-m1") self.ignore("missionselect-m2") def enterMissionScreen(self): self.missionScreen.showWithTitle(self.currentMission.objective) self.accept("mission-start", self.request, ["Game"]) def exitMissionScreen(self): self.missionScreen.hide() self.ignore("mission-start") def enterGame(self): self.world = World(self.currentMission.mapName) self.startTime = "Not yet set - not loaded" #set in self.missionOverTask self.player = Player(self.world) self.accept("player-into-Collision", self.player.reset) self.accept("game-quit", self.request, ["Menu"]) def exitGame(self): self.world.destroy() self.player.model.removeNode() del self.player base.taskMgr.remove("hud update") self.hud.timer.setText("") self.hud.hide() base.taskMgr.remove("update player") self.ignore("game-quit") def enterDebrief(self): self.debrief.show() self.debrief.setTitle(self.currentMission.question, isAnswer=False) self.debrief.setButtons(self.currentMission.options) self.accept("debrief-correct", self.debrief.setTitle, ["Correct"]) self.accept("debrief-wrong", self.debrief.setTitle, ["Wrong"]) self.accept("debrief-back", self.request, ["Menu"]) self.accept("debrief-restart", self.request, ["Game"]) def exitDebrief(self): self.debrief.hide() self.ignore("debrief-correct") self.ignore("debrief-wrong") self.debrief.initialise( ) #clear all settings on it, ie title and buttons, as they are mission specific def setMission(self, name): self.currentMission = missions[name] self.request("MissionScreen") def missionOverTask(self, task): if self.state == "Game" and self.world.loaded and self.startTime == "Not yet set - not loaded": self.startTime = time.time() self.hud.show() self.hud.initialise(self.currentMission.objective, self.currentMission.timeAllowed) base.taskMgr.add(self.hud.hudTask, "hud update") if self.state == "Game" and self.world.loaded: if time.time() - self.startTime > self.currentMission.timeAllowed: self.request("Debrief") return task.cont
class Player(DirectObject): def __init__(self, _main): self.main = _main self.name = "" self.points = 0 self.health = 100.0 self.runSpeed = 1.8 self.keyMap = { "left":False, "right":False, "up":False, "down":False } base.camera.setPos(0,0,0) self.model = loader.loadModel("Player") self.model.find('**/+SequenceNode').node().stop() self.model.find('**/+SequenceNode').node().pose(0) base.camera.setP(-90) self.playerHud = Hud() self.playerHud.hide() self.model.hide() # Weapons: size=2, 0=main, 1=offhand self.mountSlot = [] self.activeWeapon = None self.isAutoActive = False self.trigger = False self.lastShot = 0.0 self.fireRate = 0.0 self.playerTraverser = CollisionTraverser() self.playerEH = CollisionHandlerEvent() ## INTO PATTERNS self.playerEH.addInPattern('intoPlayer-%in') #self.playerEH.addInPattern('colIn-%fn') self.playerEH.addInPattern('intoHeal-%in') self.playerEH.addInPattern('intoWeapon-%in') ## OUT PATTERNS self.playerEH.addOutPattern('outOfPlayer-%in') playerCNode = CollisionNode('playerSphere') playerCNode.setFromCollideMask(BitMask32.bit(1)) playerCNode.setIntoCollideMask(BitMask32.bit(1)) self.playerSphere = CollisionSphere(0, 0, 0, 0.6) playerCNode.addSolid(self.playerSphere) self.playerNP = self.model.attachNewNode(playerCNode) self.playerTraverser.addCollider(self.playerNP, self.playerEH) #self.playerNP.show() self.playerPusher = CollisionHandlerPusher() self.playerPusher.addCollider(self.playerNP, self.model) self.playerPushTraverser = CollisionTraverser() self.playerPushTraverser.addCollider(self.playerNP, self.playerPusher) def acceptKeys(self): self.accept("w", self.setKey, ["up", True]) self.accept("w-up", self.setKey, ["up", False]) self.accept("a", self.setKey, ["left", True]) self.accept("a-up", self.setKey, ["left", False]) self.accept("s", self.setKey, ["down", True]) self.accept("s-up", self.setKey, ["down", False]) self.accept("d", self.setKey, ["right", True]) self.accept("d-up", self.setKey, ["right", False]) # Add mouse btn for fire() self.accept("mouse1", self.setWeaponTrigger, [True]) self.accept("mouse1-up", self.setWeaponTrigger, [False]) # Killed enemies self.accept("killEnemy", self.addPoints) # Game states self.accept("doDamageToPlayer", self.doDamage) def ignoreKeys(self): self.ignore("w") self.ignore("a") self.ignore("s") self.ignore("d") self.ignore("killEnemy") self.ignore("mouse1") self.ignore("mouse1-up") for item in self.main.itemList: if item.type == "heal": self.ignore("intoHeal-" + "itemHeal" + str(item.id)) elif item.type == "gun": self. ignore("intoWeapon-" + "itemWeapon" + str(item.id)) for enemy in self.main.enemyList: self.ignore("intoPlayer-" + "colEnemy" + str(enemy.id)) # Add mouse btn for fire to ignore def setKey(self, action, pressed): self.keyMap[action] = pressed def start(self, startPos, playerName): self.name = playerName self.points = 0 self.health = 100 self.model.reparentTo(render) self.model.setPos(startPos.x, startPos.y, 0) for slot in self.mountSlot[:]: self.mountSlot.remove(slot) # Create a basic weapon self.mountSlot.append(Weapon(self.main, "Pistol", 0.30, 25, weaponType="Pistol")) # Mount the players default weapon self.mountWeapon(self.mountSlot[0]) self.playerHud.setWeapon("Pistol") self.acceptKeys() self.playerHud.show() taskMgr.add(self.move, "moveTask") def stop(self): taskMgr.remove("moveTask") self.ignoreKeys() self.unmountWeapon() self.playerHud.hide() self.model.hide() def addPoints(self, args): self.points += 10 base.messenger.send("setHighscore", [self.points]) def move(self, task): elapsed = globalClock.getDt() #self.playerTraverser.traverse(self.main.enemyParent) #self.playerTraverser.traverse(self.main.itemParent) # set headding pos = self.main.mouse.getMousePos() pos.setZ(0) self.model.lookAt(pos) self.model.setP(-90) # new player position if self.keyMap["up"]: # follow mouse mode #self.model.setZ(self.model, 5 * elapsed * self.runSpeed) # axis move mode self.model.setY(self.model.getY() + elapsed * self.runSpeed) elif self.keyMap["down"]: #self.model.setZ(self.model, -5 * elapsed * self.runSpeed) self.model.setY(self.model.getY() - elapsed * self.runSpeed) if self.keyMap["left"]: # follow mouse mode #self.model.setX(self.model, -5 * elapsed * self.runSpeed) # axis move mode self.model.setX(self.model.getX() - elapsed * self.runSpeed) elif self.keyMap["right"]: #self.model.setX(self.model, 5 * elapsed * self.runSpeed) self.model.setX(self.model.getX() + elapsed * self.runSpeed) # actualize cam position base.camera.setPos(self.model.getPos()) base.camera.setZ(20) return task.cont def mountWeapon(self, _weaponToMount): self.activeWeapon = _weaponToMount # self.mountSlot[0] if self.activeWeapon.style == "TwoHand": self.model.find('**/+SequenceNode').node().pose(0) else: self.model.find('**/+SequenceNode').node().pose(1) self.activeWeapon.model.reparentTo(self.model) self.activeWeapon.model.setY(self.model.getY() - 0.1) self.model.show() self.activeWeapon.model.show() self.fireRate = self.activeWeapon.fireRate def unmountWeapon(self): self.activeWeapon.model.hide() def setWeaponTrigger(self, _state): self.trigger = _state if _state: mpos = self.main.mouse.getMousePos() self.activeWeapon.doFire(mpos) if self.activeWeapon.weaponType == "MG": self.fireActiveWeapon() else: self.activeWeapon.stopFire() else: self.activeWeapon.stopFire() taskMgr.remove("Fire") def fireActiveWeapon(self): if self.activeWeapon: #mpos = self.main.mouse.getMousePos() taskMgr.add(self.fireUpdate, "Fire") #self.activeWeapon.doFire(mpos) def fireUpdate(self, task): dt = globalClock.getDt() self.lastShot += dt mpos = self.main.mouse.getMousePos() #print self.lastShot if self.lastShot >= self.fireRate: self.lastShot -= self.fireRate if self.trigger: self.activeWeapon.doFire(mpos) #task.delayTime += self.fireRate return task.again def setMouseBtn(self): self.trigger = False print "Mouse Released" def addEnemyDmgEvent(self, _id): self.accept("intoPlayer-" + "colEnemy" + str(_id), self.setEnemyAttack) #self.accept("outOfPlayer-" + "colEnemy" + str(_id), self.setEnemyAttackOutOfRange) def setEnemyAttack(self, _entry): enemyColName = _entry.getIntoNodePath().node().getName() base.messenger.send("inRange-" + enemyColName, [True]) def setEnemyAttackOutOfRange(self, _entry): enemyColName = _entry.getIntoNodePath().node().getName() base.messenger.send("inRange-" + enemyColName, [False]) def doDamage(self, _dmg): if self.health <= 0: #print "KILLED IN ACTION" self.main.stop() else: self.health -= _dmg #print "Remaining Health: ", self.health base.messenger.send("setHealth", [self.health]) def addHealItemEvent(self, _id): self.accept("intoHeal-" + "itemHeal" + str(_id), self.healPlayer) def healPlayer(self, _entry): itemColName = _entry.getIntoNodePath().node().getName() if self.health == 100: pass else: self.health += 50 base.messenger.send("into-" + itemColName) if self.health > 100: self.health = 100 print self.health def addWeaponItemEvent(self, _id): self.accept("intoWeapon-" + "itemWeapon" + str(_id), self.changeWeapon) def changeWeapon(self, _entry): itemColName = _entry.getIntoNodePath().node().getName() base.messenger.send("into-" + itemColName) for weapon in self.mountSlot: if weapon.name == "MachineGun": return self.unmountWeapon() self.mountSlot.append(Weapon(self.main, "MachineGun", 0.15, 50, weaponType="MG")) self.playerHud.setWeapon("MG") self.mountWeapon(self.mountSlot[len(self.mountSlot) - 1]) self.activeWeapon.model.show()