async def loadScene(self, task): text = OnscreenText("Loading...") self.terrain = await loader.loadModel(models["terrain"], blocking=False) self.terrain.reparentTo(render) if USE_RENDER_PIPELINE: rp.prepare_scene(self.terrain) self.terrain.setScale(18) modelList = parseMissionFile(self.map) print(modelList) for model in modelList: try: m = loader.loadModel("models/" + model.modelName) m.reparentTo(self.terrain) m.setPos(*model.modelPos) except: #Its a particle system floater = render.attachNewNode("particle floater") floater.setPos(self.terrain, *model.particlePos) floater.setScale(5) self.particles = ParticleEffect() self.particles.loadConfig(model.ptfFile) print(model.particlePos) self.particles.start(parent=floater, renderParent=floater) #self.particles.setPos(*model.particlePos) #Once loaded, remove loading text text.hide() del text self.loaded = True
class UI(DirectObject): def __init__(self): self.root = render.attachNewNode("Root") base.setBackgroundColor(0, 0, 0) # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball In Maze", style=1, fg=(1, 1, 0, 1), pos=(0.7, -0.95), scale=.07) self.instructions = OnscreenText(text="Press Esc to exit", pos=(-1.3, .95), fg=(1, 1, 0, 1), align=TextNode.ALeft, scale=.05) self.central_msg = OnscreenText(text="", pos=(0, 0), fg=(1, 1, 0, 1), scale=.1) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1) def show_message(self, message=''): if message: self.central_msg.setText(message) self.central_msg.show() else: self.central_msg.hide()
class UI(DirectObject): def __init__(self): self.root = render.attachNewNode("Root") base.setBackgroundColor(0,0,0) # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball In Maze", style=1, fg=(1,1,0,1), pos=(0.7,-0.95), scale = .07) self.instructions = OnscreenText(text="Press Esc to exit", pos = (-1.3, .95), fg=(1,1,0,1), align = TextNode.ALeft, scale = .05) self.central_msg = OnscreenText(text="", pos = (0, 0), fg=(1, 1, 0, 1), scale = .1 ) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1,1,1,1)) m.setShininess(96) self.ball.setMaterial(m, 1) def show_message(self, message=''): if message: self.central_msg.setText(message) self.central_msg.show() else: self.central_msg.hide()
class Popup: '''Meta class for messages that appear on certain actions and disappear into nowhere''' def __init__(self, text=None, pos=(0, 0), align=TextNode.ACenter, scale=1, fg=(1, 1, 1, 1), parent=None, name="Popup", duration=1): if not parent: parent = base.aspect2d self.duration = duration self.name = name #maybe make it possible for popup message to be not just text? idk self.popup_msg = OnscreenText(pos=pos, align=align, scale=scale, fg=fg, parent=parent, mayChange=True) if text: self.set_text(text) self.popup_msg.hide() def set_duration(self, duration): #duration may be both int and float, idk how to do that yet self.duration = duration def set_text(self, text: str): '''Set message's text. Same as setText of panda's native gui items''' self.popup_msg.setText(text) def show(self): '''Show popup for self.duration seconds, then auto-hide it away''' #todo: add ability to use some visual effects self.popup_msg.show() #todo: maybe remake it into lerp, so there wont be need to involve base. #this function is hidden inside, coz we have no use for it outside def hide_popup_task(event): self.popup_msg.hide() return base.task_mgr.do_method_later(self.duration, hide_popup_task, self.name)
class AttractScreenBase(GameScreen): ''' This is the base class for all attract screens. All attract screens must have the credit flashing at the bottom, so the easiest way is to have all attract screens sublcass this class, where the common elements live. ''' _creditAnim = None def __init__(self, screen_manager, name): ''' Constructor ''' super(AttractScreenBase, self).__init__(screen_manager, name) self._creditText=OnscreenText("FREE PLAY PRESS START", 1, font=base.fontLoader.load('digital.ttf'), fg=(1,1,1,1), pos=(0,-.95), align=TextNode.ACenter, scale=.1, mayChange=True, parent=self.node2d) self._creditAnim = None def startAnimations(self): self._creditAnim = base.taskMgr.doMethodLater(0.8, self.toggleCreditLine, 'credit_flash') def stopAnimations(self): if self._creditAnim == None: return base.taskMgr.remove(self._creditAnim) self._creditAnim = None def toggleCreditLine(self, task): if self._creditText.isHidden(): self._creditText.show() else: self._creditText.hide() return task.again def show(self): self.startAnimations() super(AttractScreenBase, self).show() def hide(self): self.stopAnimations() super(AttractScreenBase, self).hide()
class Users: def __init__(self, connection, world): self.cManager = connection self.world = world self.visible = False self.display_users = "Connected Users" # self.active_users = ["Connected Users"] self.users_object = OnscreenText(text=self.display_users, style=1, fg=(1, 1, 1, 1), pos=(0, .9), align=TextNode.ALeft, scale=.05, mayChange=1) self.users_object.hide() self.cManager.sendRequest(110) def get_active_users(self): return self.active_users def add(self, username): self.active_users.append(username) def remove(self, username): self.active_users.remove(username) def show(self): self.update() self.users_object.show() def hide(self): self.users_object.hide() def toggle(self): if self.visible == False: self.show() self.visible = True else: self.hide() self.visible = False def update(self): self.display_users = "Connected Users\n" # print self.world.characters.__len__() # print self.world.characters.__s for user in self.world.characters: print user.getPlayerId() self.display_users = self.display_users + user.getPlayerId() + "\n" self.users_object = OnscreenText(text=self.display_users, style=1, fg=(1, 1, 1, 1), pos=(0, .9), align=TextNode.ALeft, scale=.05)
class TextMsg: """Simple text message. Basically a wrapper on top of OnscreenText with sane argument names. Has limited set of supported functions, in comparison with original. """ # **kwargs is there to accept garbage items passed from childs. Should be # removed when childs will get proper init args instead of these #TODO def __init__( self, text: str, text_pos: tuple = (0, 0), text_align=TextNode.ACenter, text_scale: float = 0.1, text_color: tuple = (1, 1, 1, 1), parent=None, **kwargs ): self.msg = OnscreenText( pos=text_pos, align=text_align, scale=text_scale, fg=text_color, parent=parent or base.aspect2d, mayChange=True, ) self.set_text(text) self.hide() # None of these functions is necessary - I just want to provide unified way # to do these things for all childs. And to avoid camelCase where possible. # I may remove these in future, if it will seem pointless def set_text(self, text: str): """Set message's text""" self.msg.setText(text) def hide(self): """Hide message""" self.msg.hide() def show(self): """Show message""" self.msg.show()
class CogdoMazeHud: LETTERS_PER_SECOND = 4.0 NEXT_NOTIFICATION_TASK_NAME = "CogdoMazeHud_NextNotification" def __init__(self): self._initNotificationText() def _initNotificationText(self): self._notificationText = OnscreenText( text="", font=ToontownGlobals.getSignFont(), pos=(0, -0.8), scale=0.11, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ACenter, mayChange=True, ) self._notificationText.hide() def destroy(self): self._stopDelayedNotification() self._notificationText.removeNode() del self._notificationText def displayNotification(self, messageText, nextMessageText=None): assert messageText is not None self._stopDelayedNotification() self._notificationText["text"] = messageText self._notificationText.show() if nextMessageText is not None: taskMgr.doMethodLater( len(messageText) / CogdoMazeHud.LETTERS_PER_SECOND, self.displayNotification, CogdoMazeHud.NEXT_NOTIFICATION_TASK_NAME, extraArgs=[nextMessageText] ) def _stopDelayedNotification(self): taskMgr.remove(CogdoMazeHud.NEXT_NOTIFICATION_TASK_NAME)
class CarAIPanel(GameObject): def __init__(self): GameObject.__init__(self) self.curr_logic = '' self.curr_wp = '' self.curr_car_dot_traj = '' self.curr_obsts = [] self.curr_obsts_back = [] self.curr_input = None self.wp_txt = OnscreenText(text='', pos=(-1.74, .5), scale=.06, fg=(1, 1, 1, 1), align=TextNode.A_left) def update(self): txt = 'current logic: ' + self.curr_logic.split('AiLogic')[0] txt += '\ncurrent wp: ' + self.curr_wp txt += '\ncar dot traj: %s' % self.curr_car_dot_traj txt += '\nobst center: %s (%s)' % (self.curr_obsts[0].name, round(self.curr_obsts[0].dist, 2)) txt += '\nobst left: %s (%s)' % (self.curr_obsts[1].name, round(self.curr_obsts[1].dist, 2)) txt += '\nobst right: %s (%s)' % (self.curr_obsts[2].name, round(self.curr_obsts[2].dist, 2)) txt += '\nobst center back: %s (%s)' % ( self.curr_obsts_back[0].name, round(self.curr_obsts_back[0].dist, 2)) txt += '\nobst left back: %s (%s)' % ( self.curr_obsts_back[1].name, round(self.curr_obsts_back[1].dist, 2)) txt += '\nobst right back: %s (%s)' % ( self.curr_obsts_back[2].name, round(self.curr_obsts_back[2].dist, 2)) txt += '\nforward: %s' % self.curr_input.forward txt += '\nbrake: %s' % self.curr_input.rear txt += '\nleft: %s' % self.curr_input.left txt += '\nright: %s' % self.curr_input.right self.wp_txt['text'] = txt def hide(self): self.wp_txt.hide()
class CarNetworkGui(CarGui): def __init__(self, mediator, car_props, players): self.car_props = car_props CarGui.__init__(self, mediator) for player in players: if player.car == car_props.name: name = player.name break sprops = self.car_props.race_props.season_props menu_props = sprops.gameprops.menu_props pars = { 'scale': .04, 'fg': menu_props.text_normal_col, 'font': self.eng.font_mgr.load_font(sprops.font) } if '@' in name: name = name[:name.index('@')] self.name_txt = OnscreenText(name, **pars) self.eng.attach_obs(self.on_frame) @staticmethod def __2d_pos(node): p3d = base.cam.get_relative_point(node.node, Point3(0, 0, 0)) p2d = Point2() return p2d if base.camLens.project(p3d, p2d) else None def on_frame(self): pos = self.__2d_pos(self.mediator.gfx.nodepath) if pos: self.name_txt.show() self.name_txt.set_pos((pos[0], 1, pos[1] + .16)) else: self.name_txt.hide() def hide(self): CarGui.hide(self) self.name_txt.hide() def destroy(self): self.name_txt.destroy() self.eng.detach_obs(self.on_frame) CarGui.destroy(self)
class Gameover: def __init__(self,score): self.loadMenu(score) def loadMenu(self,score): mapsparkour = loader.loadModel("assets/gui/retour_maps") self.screen=OnscreenImage(image=str(MAINDIR)+'/assets/gui/gameover_screen.png',pos=(0,0,0),scale=(0.65,0.65,0.65)) self.screen.setTransparency(1) self.font = loader.loadFont(str(MAINDIR)+'/assets/fonts/allerdisplay.ttf') self.score = OnscreenText(text="{}".format(score), pos=(0,-0.2),scale=0.15, fg=(1, 1, 1, 1), align=TextNode.ACenter,font= self.font) def hideMenu(self): self.gameover_button.hide() self.screen.hide() self.score.hide() def showMenu(self): self.screen.show() self.gameover_button.show() self.score.show()
async def loadScene(self, task): text = OnscreenText("Loading...") self.terrain = await loader.loadModel("models/terrain.bam", blocking=False) self.terrain.reparentTo(render) rp.prepare_scene(self.terrain) self.terrain.setScale(18) modelList = parseMissionFile(self.map) print(modelList) for model in modelList: m = loader.loadModel("models/" + model.modelName) m.reparentTo(self.terrain) m.setPos(*model.modelPos) #Once loaded, remove loading text text.hide() del text rp.prepare_scene(self.terrain) self.loaded = True
class start: def __init__(self): self.exit = DirectButton(text=("Start"), scale=0.06, parent=base.aspect2d, pressEffect=1, text_fg=(1, 1, 0, 1), text_bg=(0, 0, 1, 1), pos=(0, 0, 0), command=self.starts) self.title = OnscreenText(text="PSYCHEDELIC", parent=base.aspect2d, scale=.2, align=TextNode.ARight, pos=(0.6, -0.9), fg=(0, 0.7, 0.6, 1), shadow=(0, 0, 0, 0.5)) def starts(self): DrawAidPickups() DrawAmmoPickups() DrawAst_Left() DrawAst_Right() DrawAst_Floor() DrawAst_Corridor() gui.healthText.show() gui.health['value'] = 3 gui.health.show() gui.ammo.show() gui.timerText.show() gui.timer['value'] = 0 gui.timer.show() gui.score.show() self.exit.hide() self.title.hide()
def __init__(self): ShowBase.__init__(self) wp = core.WindowProperties() wp.setTitle("Dorfdelf") self.win.requestProperties(wp) self.render.setAntialias(core.AntialiasAttrib.MAuto) self.setBackgroundColor(0.5, 0.5, 0.5) self.disableMouse() self.enableParticles() font = self.loader.loadFont('media/calibri.ttf') font.setPixelsPerUnit(120) font.setPageSize(512, 1024) loading = OnscreenText(text='Loading...', scale=0.2, pos=(0.0, 0.0), fg=(1, 1, 1, 1), shadow=(0.3, 0.3, 0.3, 1.0), align=core.TextNode.ACenter, mayChange=True, font=font, parent=self.aspect2d) self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() loading.setText('Generating world') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world = world.World(128, 128, 100) self.world.generate() loading.setText('Creating world geometry') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world_geometry = geometry.WorldGeometry(self.world) self.camLens.setFocalLength(1) self.camera.setPos(0, 0, 100) self.camera.lookAt(self.world.midpoint.x, self.world.midpoint.y, 100) self.cam.setPos(0, 0, 0) self.cam.setHpr(0, -45, 0) self.cc = camera.CameraController(self.world.size, self.mouseWatcherNode, self.camera, self.cam) self.gui = gui.GUI(self.pixel2d, font) self.world_geometry.node.setPos(0, 0, 0) self.world_geometry.node.reparentTo(self.render) self.explore_mode = True self.current_slice = int(self.world.midpoint.z) self.accept_keyboard() self.accept('mouse1', self.toggle_block) self.accept('console-command', self.console_command) self.designation = designation.Designation() self.dorfs = [] self.tool = lambda w, x, y, z: None self.toolargs = () self.tools = { 'bomb': tools.bomb, 'block': tools.block, 'd': self.designation.add } self.console = console.Console(self) self.picker = block_picker.BlockPicker(self.world, self) self.zmap = zmap.ZMap(self.world, self) self.change_slice(0) arrow = LineNodePath() arrow.reparentTo(self.render) arrow.drawArrow2d(Vec3(-5, -5, self.world.midpoint.z), Vec3(15, -5, self.world.midpoint.z), 30, 3) arrow.create() loading.hide()
class DeveloperConsole(InteractiveInterpreter, DirectObject): """The name says it all.""" def __init__(self, manager, xml): sys.stdout = PseudoFile(self.writeOut) sys.stderr = PseudoFile(self.writeErr) tpErr = TextProperties() tpErr.setTextColor(1, 0.5, 0.5, 1) TextPropertiesManager.getGlobalPtr().setProperties("err", tpErr) self.manager = manager font = loader.loadFont("cmss12") self.frame = DirectFrame(parent=base.a2dTopCenter, text_align=TextNode.ALeft, text_pos=(-base.getAspectRatio() + TEXT_MARGIN[0], TEXT_MARGIN[1]), text_scale=0.05, text_fg=(1, 1, 1, 1), frameSize=(-2.0, 2.0, -0.5, 0.0), frameColor=(0, 0, 0, 0.5), text='', text_font=font) self.entry = DirectEntry(parent=base.a2dTopLeft, command=self.command, scale=0.05, width=1000.0, pos=(-0.02, 0, -0.48), relief=None, text_pos=(1.5, 0, 0), text_fg=(1, 1, 0.5, 1), rolloverSound=None, clickSound=None, text_font=font) self.otext = OnscreenText(parent=self.entry, scale=1, align=TextNode.ALeft, pos=(1, 0, 0), fg=(1, 1, 0.5, 1), text=':', font=font) self.lines = [''] * 9 self.commands = [] # All previously sent commands self.cscroll = None # Index of currently navigated command, None if current self.command = '' # Currently entered command self.block = '' # Temporarily stores a block of commands self.hide() self.initialized = False def prevCommand(self): if self.hidden: return if len(self.commands) == 0: return if self.cscroll == None: self.cscroll = len(self.commands) self.command = self.entry.get() elif self.cscroll <= 0: return else: self.commands[self.cscroll] = self.entry.get() self.cscroll -= 1 self.entry.set(self.commands[self.cscroll]) self.entry.setCursorPosition(len(self.commands[self.cscroll])) def nextCommand(self): if self.hidden: return if len(self.commands) == 0: return if self.cscroll == None: return self.commands[self.cscroll] = self.entry.get() self.cscroll += 1 if self.cscroll >= len(self.commands): self.cscroll = None self.entry.set(self.command) self.entry.setCursorPosition(len(self.command)) else: self.entry.set(self.commands[self.cscroll]) self.entry.setCursorPosition(len(self.commands[self.cscroll])) def writeOut(self, line, copy=True): if copy: sys.__stdout__.write(line) lines = line.split('\n') firstline = lines.pop(0) self.lines[-1] += firstline self.lines += lines self.frame['text'] = '\n'.join(self.lines[-9:]) def writeErr(self, line, copy=True): if copy: sys.__stderr__.write(line) line = '\1err\1%s\2' % line lines = line.split('\n') firstline = lines.pop(0) self.lines[-1] += firstline self.lines += lines self.frame['text'] = '\n'.join(self.lines[-9:]) def command(self, text): if not self.hidden: self.cscroll = None self.command = '' self.entry.set('') self.entry['focus'] = True self.writeOut(self.otext['text'] + ' ' + text + '\n', False) if text != '' and (len(self.commands) == 0 or self.commands[-1] != text): self.commands.append(text) # Insert plugins into the local namespace locals = __main__.__dict__ locals['manager'] = self.manager for plugin in self.manager.named.keys(): locals[plugin] = self.manager.named[plugin] locals['panda3d'] = panda3d # Run it and print the output. if not self.initialized: InteractiveInterpreter.__init__(self, locals=locals) self.initialized = True try: if self.runsource(self.block + '\n' + text) and text != '': self.otext['text'] = '.' self.block += '\n' + text else: self.otext['text'] = ':' self.block = '' except Exception: # Not just "except", it will also catch SystemExit # Whoops! Print out a traceback. self.writeErr(traceback.format_exc()) def toggle(self): if self.hidden: self.show() else: self.hide() def show(self): self.accept('arrow_up', self.prevCommand) self.accept('arrow_up-repeat', self.prevCommand) self.accept('arrow_down', self.nextCommand) self.accept('arrow_down-repeat', self.nextCommand) self.hidden = False self.entry['focus'] = True self.frame.show() self.entry.show() self.otext.show() def hide(self): self.ignoreAll() self.hidden = True self.entry['focus'] = False self.frame.hide() self.entry.hide() self.otext.hide() def destroy(self): sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ self.ignoreAll() self.frame.destroy() self.entry.destroy() self.otext.destroy()
class TeamActivityGui: COUNTDOWN_TASK_NAME = 'updateCountdownTask' timer = None statusText = None countdownText = None exitButton = None switchButton = None def __init__(self, activity): self.activity = activity def load(self): buttonModels = loader.loadModel('phase_3.5/models/gui/inventory_gui') upButton = buttonModels.find('**//InventoryButtonUp') downButton = buttonModels.find('**/InventoryButtonDown') rolloverButton = buttonModels.find('**/InventoryButtonRollover') self.exitButton = DirectButton(relief=None, text=TTLocalizer.PartyTeamActivityExitButton, text_fg=(1, 1, 0.65, 1), text_pos=(0, -0.15), text_scale=0.5, image=(upButton, downButton, rolloverButton), image_color=(1, 0, 0, 1), image_scale=(14.5, 1, 9), pos=(0, 0, 0.8), scale=0.15, command=self.handleExitButtonClick) self.exitButton.hide() if self.activity.toonsCanSwitchTeams(): self.switchButton = DirectButton(relief=None, text=TTLocalizer.PartyTeamActivitySwitchTeamsButton, text_fg=(1, 1, 1, 1), text_pos=(0, 0.1), text_scale=0.5, image=(upButton, downButton, rolloverButton), image_color=(0, 1, 0, 1), image_scale=(15, 1, 15), pos=(0, 0, 0.5), scale=0.15, command=self.handleSwitchButtonClick) self.switchButton.hide() else: self.switchButton = None buttonModels.removeNode() self.countdownText = OnscreenText(text='', pos=(0.0, -0.2), scale=PartyGlobals.TeamActivityTextScale * 1.2, fg=(1.0, 1.0, 0.65, 1.0), align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), mayChange=True) self.countdownText.hide() self.statusText = OnscreenText(text='', pos=(0.0, 0.0), scale=PartyGlobals.TeamActivityTextScale, fg=PartyGlobals.TeamActivityStatusColor, align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), mayChange=True) self.statusText.hide() self.timer = PartyUtils.getNewToontownTimer() self.timer.hide() return def unload(self): self.hideWaitToStartCountdown() if self.exitButton is not None: self.exitButton.destroy() self.exitButton = None if self.switchButton is not None: self.switchButton.destroy() self.switchButton = None if self.countdownText is not None: self.countdownText.destroy() self.countdownText.removeNode() self.countdownText = None if self.statusText is not None: self.statusText.destroy() self.statusText.removeNode() self.statusText = None if self.timer is not None: self.timer.destroy() del self.timer return def showStatus(self, text): self.statusText.setText(text) self.statusText.show() def hideStatus(self): self.statusText.hide() def enableExitButton(self): self.exitButton.show() def disableExitButton(self): self.exitButton.hide() def handleExitButtonClick(self): self.disableExitButton() self.disableSwitchButton() self.activity.d_toonExitRequest() def enableSwitchButton(self): self.switchButton.show() def disableSwitchButton(self): if self.switchButton is not None: self.switchButton.hide() return def handleSwitchButtonClick(self): self.disableSwitchButton() self.disableExitButton() self.activity.d_toonSwitchTeamRequest() def showWaitToStartCountdown(self, duration, waitToStartTimestamp, almostDoneCallback = None): self._countdownAlmostDoneCallback = almostDoneCallback currentTime = globalClock.getRealTime() waitTimeElapsed = currentTime - waitToStartTimestamp if duration - waitTimeElapsed > 1.0: countdownTask = Task(self._updateCountdownTask) countdownTask.duration = duration - waitTimeElapsed self.countdownText.setText(str(int(countdownTask.duration))) self.countdownText.show() taskMgr.remove(TeamActivityGui.COUNTDOWN_TASK_NAME) taskMgr.add(countdownTask, TeamActivityGui.COUNTDOWN_TASK_NAME) def hideWaitToStartCountdown(self): taskMgr.remove(TeamActivityGui.COUNTDOWN_TASK_NAME) self._countdownAlmostDoneCallback = None if self.countdownText is not None: self.countdownText.hide() return def _updateCountdownTask(self, task): countdownTime = int(task.duration - task.time) seconds = str(countdownTime) if self.countdownText['text'] != seconds: self.countdownText['text'] = seconds if countdownTime == 3 and self._countdownAlmostDoneCallback is not None: self._countdownAlmostDoneCallback() self._countdownAlmostDoneCallback = None if task.time >= task.duration: return Task.done else: return Task.cont return def showTimer(self, duration): self.timer.setTime(duration) self.timer.countdown(duration, self._handleTimerExpired) self.timer.show() def hideTimer(self): self.timer.hide() self.timer.stop() def _handleTimerExpired(self): self.activity.handleGameTimerExpired()
class App(ShowBase): def __init__(self): ShowBase.__init__(self) # Print all events sent through the messenger #self.messenger.toggleVerbose() self.lblWarning = OnscreenText( text = "No devices found", fg=(1,0,0,1), scale = .25) self.lblAction = OnscreenText( text = "Action", fg=(1,1,1,1), scale = .15) self.lblAction.hide() # Is there a steering wheel connected? self.wheel = None devices = self.devices.getDevices(InputDevice.DeviceClass.steering_wheel) if devices: self.connect(devices[0]) self.currentMoveSpeed = 0.0 self.maxAccleration = 28.0 self.deaccleration = 10.0 self.deaclerationBreak = 37.0 self.maxSpeed = 80.0 # Accept device dis-/connection events self.accept("connect-device", self.connect) self.accept("disconnect-device", self.disconnect) self.accept("escape", exit) # Accept button events of the first connected steering wheel self.accept("steering_wheel0-face_a", self.action, extraArgs=["Action"]) self.accept("steering_wheel0-face_a-up", self.actionUp) self.accept("steering_wheel0-hat_up", self.center_wheel) self.environment = loader.loadModel("environment") self.environment.reparentTo(render) # save the center position of the wheel # NOTE: here we assume, that the wheel is centered when the application get started. # In real world applications, you should notice the user and give him enough time # to center the wheel until you store the center position of the controler! self.wheelCenter = 0 if self.wheel is not None: self.wheelCenter = self.wheel.findAxis(InputDevice.Axis.wheel).value # disable pandas default mouse-camera controls so we can handle the camera # movements by ourself self.disableMouse() self.reset() self.taskMgr.add(self.moveTask, "movement update task") def connect(self, device): """Event handler that is called when a device is discovered.""" # We're only interested if this is a steering wheel and we don't have a # wheel yet. if device.device_class == InputDevice.DeviceClass.steering_wheel and not self.wheel: print("Found %s" % (device)) self.wheel = device # Enable this device to ShowBase so that we can receive events. # We set up the events with a prefix of "steering_wheel0-". self.attachInputDevice(device, prefix="steering_wheel0") # Hide the warning that we have no devices. self.lblWarning.hide() def disconnect(self, device): """Event handler that is called when a device is removed.""" if self.wheel != device: # We don't care since it's not our wheel. return # Tell ShowBase that the device is no longer needed. print("Disconnected %s" % (device)) self.detachInputDevice(device) self.wheel = None # Do we have any steering wheels? Attach the first other steering wheel. devices = self.devices.getDevices(InputDevice.DeviceClass.steering_wheel) if devices: self.connect(devices[0]) else: # No devices. Show the warning. self.lblWarning.show() def reset(self): """Reset the camera to the initial position.""" self.camera.setPosHpr(0, -200, 2, 0, 0, 0) def action(self, button): # Just show which button has been pressed. self.lblAction.text = "Pressed %s" % button self.lblAction.show() def actionUp(self): # Hide the label showing which button is pressed. self.lblAction.hide() def center_wheel(self): """Reset the wheels center rotation to the current rotation of the wheel""" self.wheelCenter = self.wheel.findAxis(InputDevice.Axis.wheel).value def moveTask(self, task): dt = globalClock.getDt() movementVec = Vec3() if not self.wheel: return task.cont if self.currentMoveSpeed > 0: self.currentMoveSpeed -= dt * self.deaccleration if self.currentMoveSpeed < 0: self.currentMoveSpeed = 0 # we will use the first found wheel # Acclerate accleratorPedal = self.wheel.findAxis(InputDevice.Axis.accelerator).value accleration = accleratorPedal * self.maxAccleration if self.currentMoveSpeed > accleratorPedal * self.maxSpeed: self.currentMoveSpeed -= dt * self.deaccleration self.currentMoveSpeed += dt * accleration # Break breakPedal = self.wheel.findAxis(InputDevice.Axis.brake).value deacleration = breakPedal * self.deaclerationBreak self.currentMoveSpeed -= dt * deacleration if self.currentMoveSpeed < 0: self.currentMoveSpeed = 0 # Steering rotation = self.wheelCenter - self.wheel.findAxis(InputDevice.Axis.wheel).value base.camera.setH(base.camera, 100 * dt * rotation) # calculate movement base.camera.setY(base.camera, dt * self.currentMoveSpeed) return task.cont
class Tutorial(Game): def __init__(self, backend, index): engine.log.info("Starting tutorial.") Game.__init__(self, backend) self.backend.matchLimit = 10 self.promptText.hide() self.scoreText.hide() if index < 2: self.unitSelector.hide() self.tutorialScreens = [] self.messages = [ "Find and capture the drop pods to earn money!", "Use your units to help defeat the enemy.", "Try using your special abilities." ] visitorFont = loader.loadFont("menu/visitor2.ttf") self.messageText = OnscreenText(pos=(-engine.aspectRatio + 0.05, 0.9), align=TextNode.ALeft, scale=0.07, fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=visitorFont, mayChange=True) for i in range(4): image = OnscreenImage(image="images/part" + str(i + 1) + ".jpg", pos=(0, 0, 0), scale=(1680.0 / 1050.0, 1, 1)) image.hide() self.tutorialScreens.append(image) self.tutorialIndex = index render.hide() self.tutorialScreens[self.tutorialIndex].show() self.messageText.hide() self.enemyAiUnits = [(constants.CHAINGUN, None), (constants.SNIPER, None), (constants.PISTOL, None)] self.enemyTeam = None self.matchStartTime = -1 def handleSpacebar(self): if self.tutorialIndex == 3: self.backend.connected = False # Exit tutorial else: if render.isHidden(): render.show() self.backend.map.hidePlatforms() self.tutorialScreens[self.tutorialIndex].hide() if self.tutorialIndex == 2: self.showBuyScreen(True) else: self.startMatch() else: Game.handleSpacebar(self) def endMatch(self, winningTeam): self.matchReset() def reset(self): Game.reset(self) self.unitSelector.hide() def showBuyScreen(self, override=False): if self.tutorialIndex >= 2 and (self.matchInProgress or override): Game.showBuyScreen(self) def startMatch(self): if not self.matchInProgress: self.matchStartTime = engine.clock.time if self.tutorialIndex == 0: self.localTeam.setPrimaryWeapon(constants.CHAINGUN) self.localTeam.setSecondaryWeapon(constants.SNIPER) self.localTeam.setSpecial(None) self.enemyAiUnits = [(constants.SHOTGUN, None)] self.backend.scoreLimit = 400 elif self.tutorialIndex == 1: self.localTeam.setPrimaryWeapon(constants.SHOTGUN) self.localTeam.setSecondaryWeapon(constants.GRENADE_LAUNCHER) self.localTeam.setSpecial(None) self.localTeam.purchaseUnit(constants.PISTOL, None) self.localTeam.purchaseUnit(constants.MOLOTOV_THROWER, None) self.enemyAiUnits = choice([[(constants.GRENADE_LAUNCHER, None), (constants.SNIPER, None), (None, None)], [(constants.CHAINGUN, None), (constants.SHOTGUN, None), (None, None)], [(constants.PISTOL, None), (constants.SNIPER, None), (None, None)]]) self.backend.scoreLimit = 800 elif self.tutorialIndex == 2: self.enemyAiUnits = choice( [[(constants.SHOTGUN, constants.CLOAK_SPECIAL), (constants.SNIPER, None), (constants.PISTOL, None)], [(constants.GRENADE_LAUNCHER, constants.CLOAK_SPECIAL), (constants.CHAINGUN, constants.SHIELD_SPECIAL), (None, None)], [(constants.PISTOL, None), (constants.MOLOTOV_THROWER, constants.SHIELD_SPECIAL), (constants.SHOTGUN, None)]]) self.backend.scoreLimit = 1200 if self.tutorialIndex <= 2: self.messageText.setText(self.messages[self.tutorialIndex]) self.messageText.show() # Purchase AI units self.enemyTeam = self.backend.entityGroup.teams[1] self.enemyTeam.setLocal(True) self.enemyTeam.setUsername("Computer") self.enemyTeam.controller.tutorialMode = True self.enemyTeam.resetScore() for u in self.enemyAiUnits: self.enemyTeam.purchaseUnit(u[0], u[1]) if self.tutorialIndex == 2: Game.startMatch(self) else: self.spawnedOnce = False self.matchInProgress = True self.gameui.show() self.promptText.hide() self.scoreText.hide() def endMatchCallback(self, winningTeam): localTeam = self.localTeam Game.endMatchCallback(self, winningTeam) player = localTeam.getPlayer() if player is not None and player.active: player.delete(self.backend.entityGroup) localTeam.setPlayer(None) self.messageText.hide() render.hide() self.tutorialIndex += 1 self.tutorialScreens[self.tutorialIndex].show() localTeam.controller.addMoney(1000) self.unitSelector.hide() self.enemyTeam.resetScore() self.enemyTeam.score = 0 def update(self): if self.matchStartTime != -1: if engine.clock.time - self.matchStartTime < 2: blend = (engine.clock.time - self.matchStartTime) / 2.0 self.messageText["fg"] = (1, 1, 1, blend) self.messageText["scale"] = 0.06 + (1.0 - blend) * 0.4 else: self.messageText["scale"] = 0.06 self.messageText["fg"] = (1, 1, 1, 1) self.matchStartTime = -1 noTeamYet = False if self.localTeam is None: noTeamYet = True Game.update(self) if noTeamYet and self.localTeam is not None and self.tutorialIndex > 0: # We have a team now! self.localTeam.controller.addMoney(2000) if self.enemyTeam is not None: self.enemyTeam.respawnUnits() def hideTutorialScreen(self): render.show() self.tutorialScreens[self.tutorialIndex].hide() def delete(self): engine.log.info("Ending tutorial.") Game.delete(self) self.messageText.destroy() for screen in self.tutorialScreens: screen.removeNode()
class App(ShowBase): def __init__(self): ShowBase.__init__(self) # Print all events sent through the messenger #self.messenger.toggleVerbose() # Load the graphics for the gamepad buttons and register them, so that # we can embed them in our information text. graphics = loader.loadModel("models/xbone-icons.egg") mgr = TextPropertiesManager.getGlobalPtr() for name in [ "face_a", "face_b", "face_x", "face_y", "ltrigger", "rtrigger", "lstick", "rstick" ]: graphic = graphics.find("**/" + name) graphic.setScale(1.5) mgr.setGraphic(name, graphic) graphic.setZ(-0.5) # Show the informational text in the corner. self.lblInfo = OnscreenText(parent=self.a2dBottomLeft, pos=(0.1, 0.3), fg=(1, 1, 1, 1), bg=(0.2, 0.2, 0.2, 0.9), align=TextNode.A_left, text=INFO_TEXT) self.lblInfo.textNode.setCardAsMargin(0.5, 0.5, 0.5, 0.2) self.lblWarning = OnscreenText(text="No devices found", fg=(1, 0, 0, 1), scale=.25) self.lblAction = OnscreenText(text="Action", fg=(1, 1, 1, 1), scale=.15) self.lblAction.hide() # Is there a gamepad connected? self.gamepad = None devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad) if devices: self.connect(devices[0]) # Accept device dis-/connection events self.accept("connect-device", self.connect) self.accept("disconnect-device", self.disconnect) self.accept("escape", exit) # Accept button events of the first connected gamepad self.accept("gamepad-back", exit) self.accept("gamepad-start", exit) self.accept("gamepad-face_x", self.reset) self.accept("gamepad-face_a", self.action, extraArgs=["face_a"]) self.accept("gamepad-face_a-up", self.actionUp) self.accept("gamepad-face_b", self.action, extraArgs=["face_b"]) self.accept("gamepad-face_b-up", self.actionUp) self.accept("gamepad-face_y", self.action, extraArgs=["face_y"]) self.accept("gamepad-face_y-up", self.actionUp) self.environment = loader.loadModel("environment") self.environment.reparentTo(render) # Disable the default mouse-camera controls since we need to handle # our own camera controls. self.disableMouse() self.reset() self.taskMgr.add(self.moveTask, "movement update task") def connect(self, device): """Event handler that is called when a device is discovered.""" # We're only interested if this is a gamepad and we don't have a # gamepad yet. if device.device_class == InputDevice.DeviceClass.gamepad and not self.gamepad: print("Found %s" % (device)) self.gamepad = device # Enable this device to ShowBase so that we can receive events. # We set up the events with a prefix of "gamepad-". self.attachInputDevice(device, prefix="gamepad") # Hide the warning that we have no devices. self.lblWarning.hide() def disconnect(self, device): """Event handler that is called when a device is removed.""" if self.gamepad != device: # We don't care since it's not our gamepad. return # Tell ShowBase that the device is no longer needed. print("Disconnected %s" % (device)) self.detachInputDevice(device) self.gamepad = None # Do we have any other gamepads? Attach the first other gamepad. devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad) if devices: self.connect(devices[0]) else: # No devices. Show the warning. self.lblWarning.show() def reset(self): """Reset the camera to the initial position.""" self.camera.setPosHpr(0, -200, 10, 0, 0, 0) def action(self, button): # Just show which button has been pressed. self.lblAction.text = "Pressed \5%s\5" % button self.lblAction.show() def actionUp(self): # Hide the label showing which button is pressed. self.lblAction.hide() def moveTask(self, task): dt = globalClock.getDt() if not self.gamepad: return task.cont strafe_speed = 85 vert_speed = 50 turn_speed = 100 # If the left stick is pressed, we will go faster. lstick = self.gamepad.findButton("lstick") if lstick.pressed: strafe_speed *= 2.0 # we will use the first found gamepad # Move the camera left/right strafe = Vec3(0) left_x = self.gamepad.findAxis(InputDevice.Axis.left_x) left_y = self.gamepad.findAxis(InputDevice.Axis.left_y) strafe.x = left_x.value strafe.y = left_y.value # Apply some deadzone, since the sticks don't center exactly at 0 if strafe.lengthSquared() >= 0.01: self.camera.setPos(self.camera, strafe * strafe_speed * dt) # Use the triggers for the vertical position. trigger_l = self.gamepad.findAxis(InputDevice.Axis.left_trigger) trigger_r = self.gamepad.findAxis(InputDevice.Axis.right_trigger) lift = trigger_r.value - trigger_l.value self.camera.setZ(self.camera.getZ() + (lift * vert_speed * dt)) # Move the camera forward/backward right_x = self.gamepad.findAxis(InputDevice.Axis.right_x) right_y = self.gamepad.findAxis(InputDevice.Axis.right_y) # Again, some deadzone if abs(right_x.value) >= 0.1 or abs(right_y.value) >= 0.1: self.camera.setH(self.camera, turn_speed * dt * -right_x.value) self.camera.setP(self.camera, turn_speed * dt * right_y.value) # Reset the roll so that the camera remains upright. self.camera.setR(0) return task.cont
class Game(): HUD_TEXT_SCALE = 0.04 UPDATE_RATE = 1/60.0 MAX_PYLON_POWER = 50 def __init__(self): self.zoomLevels = deque([640, 512, 320, 1280]) self.curLev = self.zoomLevels[0] base.disableMouse() self.initCam() self.loadPhysics() self.loadLights() #map x boundary, map y boundary, amount of pylons self.map = Map(self, 150.0, 150.0, 7) self.shipList = [] self.ship1 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0.0)) self.ship2 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.6, 0.0)) self.ship1.setPos( Vec3(0, 120, 0) ) self.ship2.setPos( Vec3(0, -120, 0) ) self.shipList.append(self.ship1) self.shipList.append(self.ship2) self.LoadHUD() self.setKeys() self.collectibleList = [] self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo.addToCollectibleList(self.collectibleList) #self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) #self.pallo2.setPos( Vec3(30, 20, 0) ) #self.pallo2.addToCollectibleList(self.collectibleList) b=OnscreenImage(parent=render2d, image="Geminid.jpg") base.cam.node().getDisplayRegion(0).setSort(20) base.setBackgroundColor(0,0,0.0,0) self.collisionSfx = loader.loadSfx("shipcollision.wav") self.goalSfx = loader.loadSfx("goal.wav") self.victorySfx = loader.loadSfx("victory.wav") self.collision2Sfx = loader.loadSfx("pyloncollision.wav") filters = CommonFilters(base.win, base.cam) render.setShaderAuto() taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('rshift', self.ship1.releaseBall) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) base.accept('q', self.ship2.releaseBall) base.accept('+', self.zoom) base.accept('p', self.toggleAI) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsWorld.setGravity(0, 0, -20) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): self.player1HUD = OnscreenText( text = "Player 1: " + str( self.ship1.getPoints() ), fg = (1,1,1,1), #pos = ( x, y ) pos = (0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.player2HUD = OnscreenText( text = "Player 2: " + str( self.ship2.getPoints() ), fg = (1,1,1,1), pos = (-0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.2, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE*3 ) # self.winnerText.setZ(200) self.winnerText.hide() def updateHUD(self): self.player1HUD.setText( "Player 1: " + str( self.ship1.getPoints() ) ) self.player2HUD.setText( "Player 2: " + str( self.ship2.getPoints() ) ) if (self.ship1.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 1 won " + str(self.ship1.getPoints()) + "-" + str(self.ship2.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) # self.Pause() if (self.ship2.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 2 won " + str(self.ship2.getPoints()) + "-" + str(self.ship1.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.6, 0.6, 0.6, 0) ) render.setLight(lightNode1) #checks all collectibles for possible collisions with ships def checkAllCollectibles(self, shipList): for collectible in self.collectibleList: collectible.hitShips(shipList) #updates all collectible positions def updateAllCollectibles(self): for collectible in self.collectibleList: collectible.update(Game.UPDATE_RATE) def applyForceAllShips(self, shipList): for ship in shipList: ship.applyForces() #updates all ship positions def updateAllShips(self, shipList): for ship in shipList: ship.update(Game.UPDATE_RATE) shipList[0].shipsCollide(shipList[1]) #checks all pylons for possible collisions with ships def checkAllPylons(self, pylonList, shipList): for pylon in pylonList: pylon.checkCollisionList(shipList) def loop(self, task): self.applyForceAllShips(self.shipList) self.physicsSpace.autoCollide() self.checkAllCollectibles(self.shipList) self.map.getBase1().checkCollision(self.ship1, self.collectibleList) self.map.getBase2().checkCollision(self.ship2, self.collectibleList) self.checkAllPylons(self.map.getPylonList(), self.shipList) self.physicsWorld.quickStep(Game.UPDATE_RATE) self.updateAllShips(self.shipList) self.updateAllCollectibles() self.contactGroup.empty() return task.cont def toggleAI(self): if taskMgr.hasTaskNamed('Simple AI'): taskMgr.remove('Simple AI') return taskMgr.add( self.chaseBallsAround, name='Simple AI', sort=None, extraArgs=(self.ship1, self.ship2, self.collectibleList, self.map.getBase1()), priority=None, uponDeath=None, appendTask=True, taskChain=None, owner=None) def chaseBallsAround(self, chaser, enemy, chaseList, base, task): pos = chaser.getPos() nearestNormedPos = 1e10000 #represents infinity nearestRelPos = [0,0] if chaser.hasBall(): chasePos = base.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] elif enemy.hasBall(): chasePos = enemy.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] else: for collectible in chaseList: chasePos = collectible.getPos() relPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] if (math.fabs(relPos[0]) + math.fabs(relPos[1])) < nearestNormedPos: nearestNormedPos = math.fabs(relPos[0]) + math.fabs(relPos[1]) nearestRelPos = relPos if nearestRelPos[0] > 0: chaser.thrustRightOff() chaser.thrustLeftOn() elif nearestRelPos[0] < 0: chaser.thrustLeftOff() chaser.thrustRightOn() if nearestRelPos[1] < 0: chaser.thrustBackOff() chaser.thrustOn() elif nearestRelPos[1] > 0: chaser.thrustOff() chaser.thrustBackOn() else: chaser.thrustOff() chaser.thrustBackOff() return task.cont def initCam(self): base.camera.setPos(0,0,self.curLev) base.camera.lookAt(0,0,0) def zoom(self): self.curLev = self.zoomLevels.popleft() base.camera.setPos(0, 0, self.curLev) self.zoomLevels.append(self.curLev) def shakeCam(self): taskMgr.add(self.shakeCamTask, name='ShakeCam') def shakeCamTask(self, task): oldPos = base.camera.getPos() base.camera.setPos(oldPos[0]+random.randint(-1, 1), oldPos[1]+random.randint(-1, 1), oldPos[2]+random.randint(-4, 4)) if task.time < 0.5: return task.cont self.initCam() return task.done
### COLLISION HANDLER ### pusher = CollisionHandlerPusher() pusher.addCollider(persoNP, perso) traverser = CollisionTraverser('traverser') traverser.addCollider(persoNP, pusher) base.cTrav = traverser #### TEXTE #### instructions1 = OnscreenText(text = 'Use ZQSD to move', pos = (0, -0.10), scale = 0.09) instructions2 = OnscreenText(text = 'Move the mouse to turn the camera', pos = (0, -0.20), scale = 0.09) instructions3 = OnscreenText(text = "Hold 'echap' to pause", pos = (0, -0.30), scale = 0.09) instructions4 = OnscreenText(text = 'Please enlarge the screen for a better experience :)', pos = (0, -0.40), scale = 0.09) objective_text = OnscreenText(text = 'Find the treasure chest !', pos = (0, 0.5), scale = 0.12) lost = OnscreenText(text = 'LOST', pos = (0, 0), scale = 0.6) lost.hide() keyMap = {"z" : False, "q" : False, "s" : False, "d" : False, "collision" : False} tools = {"escape": False, "pause_text" : False, "lose": False, "win":True} def setKeys(button, boole): keyMap[button] = boole def setTools(button, boole): tools[button] = boole def collisionEvenement(message): setKeys("collision", True) def collisionEvenement2(message): setKeys("collision", False)
class RonnieRacer(DirectObject): gameState = 'INIT' gameLevel = 1 distanceTravelled = 0 speed = 0 score = 0 triesLeft = 3 count = 0 rot = 0 time = 0 pause = False def __init__(self): self.imageObject = OnscreenImage(image = 'media/images/splashscreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.loseScreen = OnscreenImage(image = 'media/images/gameover.png', pos=(0,0,0), scale=(1,1,0.8)) self.loseScreen.hide() self.retryScreen = OnscreenImage(image = 'media/images/retry.png', pos=(0,0,0), scale=(1,1,0.8)) self.retryScreen.hide() self.congratScreen = OnscreenImage(image = 'media/images/congratulations.png', pos=(0,0,0), scale = (1,1,0.8)) self.congratScreen.hide() self.winScreen = OnscreenImage(image = 'media/images/victory.png', pos=(0,0,0), scale = (1,1,0.8)) self.winScreen.hide() self.pauseScreen = OnscreenImage(image = 'media/images/pause.png', pos=(0,0,0), scale = (1,1,0.8)) self.pauseScreen.hide() self.instructionScreen = OnscreenImage(image = 'media/images/instructions.png', pos=(0,0,0), scale = (1,1,0.8)) self.instructionScreen.hide() preloader = Preloader() base.setBackgroundColor(0, 0, 0, 1) base.setFrameRateMeter(True) # Audio self.loseSound = base.loader.loadSfx("media/audio/sfxboo.wav") self.winSound = base.loader.loadSfx("media/audio/cheer2.aif") self.menuMusic = base.loader.loadSfx("media/audio/Scattershot.mp3") self.gameMusic = base.loader.loadSfx("media/audio/Ghostpocalypse - 7 Master.mp3") self.menuMusic.setLoop(True) self.menuMusic.setLoopCount(0) self.gameMusic.setLoop(True) self.gameMusic.setLoopCount(0) #setup buttons self.retryBtn = DirectButton(text="Retry", scale = 0.1, pos = (0,0,0), command = self.doRetry) self.retryBtn.hide() self.menuBtn = DirectButton(text="Main Menu", scale = 0.1, pos = (0,0,0), command = self.doMenu) self.menuBtn.hide() self.nextBtn = DirectButton(text='Next', scale = 0.1, pos = (0,0,0), command = self.doNext) self.nextBtn.hide() self.backBtn = DirectButton(text='back', scale = 0.1, pos = (-0.7,0,-0.7), command = self.doBack) self.backBtn.hide() #setup font self.font = loader.loadFont('media/SHOWG.TTF') self.font.setPixelsPerUnit(60) #setup text self.text = OnscreenText(text = '', pos = (0, 0), scale = 0.07, font = self.font) self.rpmText = OnscreenText(text = '', pos = (-0.9, -0.9), scale = 0.07, font = self.font) self.speedText = OnscreenText(text = '', pos = (0, -0.9), scale = 0.07, font = self.font) self.distanceText = OnscreenText(text = '', pos = (0.9, -0.9), scale = 0.07, font = self.font) self.triesLeftText = OnscreenText(text = '', pos = (1.0, 0.9), scale = 0.07, font = self.font) self.gameLevelText = OnscreenText(text = '', pos = (-1.0, 0.9), scale = 0.07, font = self.font) self.timeText = OnscreenText(text = '', pos = (0, 0.9), scale = 0.07, font = self.font) self.scoreText = OnscreenText(text = '', pos = (1.0, 0.8), scale = 0.07, font = self.font) self.finalScoreText = OnscreenText(text = '', pos = (0, 0.2), scale = 0.07, font = self.font) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'a') inputState.watchWithModifiers('turnRight', 'd') # Task taskMgr.add(self.update, 'updateWorld') # _____HANDLER_____ def doExit(self): sys.exit(1) def doReset(self): self.cleanup() self.terrain.getRoot().removeNode() self.setup() def doBack(self): self.backBtn.hide() self.instructionScreen.hide() self.imageObject.show() self.helpBtn.show() self.startBtn.show() self.exitBtn.show() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') # ____TASK___ def processInput(self, dt): # Process input engineForce = 0.0 brakeForce = 0.0 self.accept('p', self.doPause) if inputState.isSet('forward'): engineForce = 15.0 brakeForce = 0.0 if inputState.isSet('reverse'): engineForce = -25.0 brakeForce = 25.0 if inputState.isSet('turnLeft'): self.steering += dt * self.steeringIncrement self.steering = min(self.steering, self.steeringClamp) if inputState.isSet('turnRight'): self.steering -= dt * self.steeringIncrement self.steering = max(self.steering, -self.steeringClamp) # Apply steering to front wheels self.vehicle.setSteeringValue(self.steering, 0) self.vehicle.setSteeringValue(self.steering, 1) # Apply engine and brake to rear wheels self.vehicle.applyEngineForce(engineForce, 2) self.vehicle.applyEngineForce(engineForce, 3) self.vehicle.setBrake(brakeForce, 2) self.vehicle.setBrake(brakeForce, 3) def processContacts(self, dt): result = self.world.contactTestPair(self.vehicleNP.node(), self.flagNP.node()) if(result.getNumContacts() > 0): self.gameState = 'WIN' self.doContinue() def doContinue(self): if(self.gameState == 'INIT'): self.gameState = 'MENU' self.menuMusic.play() self.text.hide() self.startBtn = DirectButton(text=("Play"), scale = 0.1, pos = (0.5,0,0),command=self.playGame) self.helpBtn = DirectButton(text=("Help"), scale = 0.1, pos = (0.5,0,-0.2),command=self.help) self.exitBtn = DirectButton(text=("Exit"), scale = 0.1, pos = (0.5,0,-0.4), command = self.doExit) return if(self.gameState == 'RETRY'): self.retryScreen.show() self.retryBtn.show() self.loseSound.play() return if(self.gameState == 'LOSE'): self.loseScreen.show() self.menuBtn.show() return if(self.gameState == 'WIN'): if(self.gameLevel < 3): self.congratScreen.show() self.nextBtn.show() elif(self.gameLevel >= 3): self.winScreen.show() self.menuBtn.show() self.finalScoreText.setText('Your Score: '+str(int(self.score))) self.finalScoreText.show() self.winSound.play() def help(self): self.gameState = 'HELP' self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.imageObject.hide() self.instructionScreen.show() self.backBtn.show() def doNext(self): self.nextBtn.hide() self.finalScoreText.hide() self.congratScreen.hide() self.gameLevel += 1 if(self.gameLevel == 2): self.score += 2000 elif(self.gameLevel == 3): self.score += 3000 self.doReset() self.triesLeft = 3 self.gameState = 'PLAY' def doRetry(self): self.doReset() self.gameState = 'PLAY' self.retryScreen.hide() self.retryBtn.hide() self.triesLeft -= 1 def doMenu(self): self.cleanup() self.terrain.getRoot().removeNode() self.gameState = 'MENU' self.score = 0 self.imageObject.show() self.startBtn.show() self.exitBtn.show() self.helpBtn.show() self.loseScreen.hide() self.menuBtn.hide() self.winScreen.hide() self.finalScoreText.hide() self.speedText.hide() self.distanceText.hide() self.rpmText.hide() self.scoreText.hide() self.gameLevelText.hide() self.timeText.hide() self.triesLeftText.hide() self.gameMusic.stop() self.menuMusic.play() def doPause(self): self.pause = not self.pause if(self.pause): self.pauseScreen.show() else: self.pauseScreen.hide() def playGame(self): self.gameState = 'PLAY' self.triesLeft = 3 self.gameLevel = 1 self.imageObject.hide() self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.menuMusic.stop() self.gameMusic.play() self.speedText.show() self.distanceText.show() self.rpmText.show() self.scoreText.show() self.gameLevelText.show() self.triesLeftText.show() self.timeText.show() # Physics self.setup() def update(self, task): dt = globalClock.getDt() if(not self.pause): if(self.gameState == 'RETRY'): return task.cont if (self.gameState == 'INIT'): self.accept('space', self.doContinue) self.text.setText('Press Space to Continue') if(self.gameState == 'PLAY'): if (self.steering > 0): self.steering -= dt * 50 if (self.steering < 0): self.steering += dt * 50 playerOldSpeed = self.vehicle.getCurrentSpeedKmHour() self.processInput(dt) self.processContacts(dt) self.world.doPhysics(dt, 10, 0.008) #calculate speed,rpm,distance and display text self.speed = self.vehicle.getCurrentSpeedKmHour() if(self.speed<0): self.speed = -self.speed self.speedText.setText('Speed: ' + str(int(self.speed)) + 'Km/h') self.distanceTravelled += self.speed*(dt/3600) self.distanceText.setText('Distance: '+str(float(int(self.distanceTravelled * 1000))/1000) + 'Km') playerNewSpeed = self.vehicle.getCurrentSpeedKmHour() playerAcceleration = (playerNewSpeed - playerOldSpeed) / (dt/60) #playerPosText = self.vehicleNP.getPos() #self.text.setText('Player position: %s'%playerPosText) self.rpmText.setText('Engine RPM: ' + str(int(((self.vehicle.getCurrentSpeedKmHour() / 60) * 1000) / (2 * 0.4 * 3.14159265))) + ' Rpm') self.triesLeftText.setText('Tries Left: ' + str(self.triesLeft)) self.gameLevelText.setText('Level: '+ str(self.gameLevel)) #update camera #position d = self.vehicleNP.getPos() - base.cam.getPos() if(d.length() > 8): base.cam.setX(base.cam.getX() + d.getX()*dt) base.cam.setY(base.cam.getY() + d.getY()*dt) base.cam.setZ(self.vehicleNP.getZ() + 4) #lookat base.cam.lookAt(self.vehicleNP.getPos()+Vec3(0,0,1)) if(self.gameLevel == 1): if(self.vehicleNP.getZ() < -17): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() elif(self.gameLevel == 2): if(self.vehicleNP.getZ() < -20): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() elif(self.gameLevel == 3): if(self.vehicleNP.getZ() < -17): if(self.triesLeft > 0): self.gameState = 'RETRY' else: self.gameState = 'LOSE' self.doContinue() if(self.speed < 5): self.steeringIncrement = 120 elif(self.speed >= 5 and self.speed < 10): self.steeringIncrement = 100 elif(self.speed >= 10 and self.speed < 15): self.steeringIncrement = 80 elif(self.speed >=15 and self.speed < 30): self.steeringIncrement = 60 #spin the flag self.rot += 1 self.flagNP.setHpr(self.rot,0,0) #time self.time += dt self.timeText.setText('Time: ' + str(int(self.time))) if(self.score > 0): self.score -= dt self.scoreText.setText('Score: '+str(int(self.score))) return task.cont def cleanup(self): self.world = None self.worldNP.removeNode() def setup(self): # Steering info self.steering = 0.0 # degree self.steeringClamp = 30.0 # degree self.steeringIncrement = 80.0 # degree per second self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) #self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) if(self.gameLevel == 1): #set score print('GameLevel') self.score = 1000 self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_1.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-93, -88, -7)#-93, -88, -7) #(-82,65.8,-8) #(55,8.38,-6)#(45, -19, -8)#(-93, -88, -7) self.vehicleNP.setHpr(-90,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) #Obstacles self.setupObstacleOne(Vec3(50, -5, -4), 1.8, Vec3(60, 0, 0)) self.setupObstacleFour(Vec3(63.3, 59.2, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(41, 57, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(7.5, 53.8, -10), 1.5, Vec3(0,0,0)) self.setupObstacleFour(Vec3(-28, 81.4, -10), 1.5, Vec3(0,0,0)) self.setupObstacleSix(Vec3(-91, 81 , -6), 1, Vec3(60,0,0)) #Goal self.setupGoal(Vec3(-101,90.6,-6.5)) #self.vehicleNP.setPos(Vec3(6,52,-6)) self.setupTerrain() elif(self.gameLevel == 2): self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_2.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-99.6,105,-11.8)#(88, 21, -11)#(34.3,8.4,-11.8)#(-99.6,105,-11.8)#(86.4,41.2,-12) self.vehicleNP.setHpr(-130,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) self.setupObstacleFive(Vec3(91, 3, -9),1,Vec3(90,0,0)) self.setupObstacleFive(Vec3(94,-19, -10),0.9,Vec3(90,0,0)) self.setupObstacleFive(Vec3(85,-40, -10),1,Vec3(90,0,0)) self.setupObstacleFour(Vec3(-33.5, 23.4,-14.5),1,Vec3(0,0,0)) self.setupObstacleFour(Vec3(-43.3, 24.2,-14.5),1,Vec3(0,0,0)) self.setupObstacleTwo(Vec3(34.7,20.9,-8.5),1,Vec3(90,0,0)) self.setupObstacleTwo(Vec3(26.8,20.3,-8.5),1,Vec3(90,0,0)) self.setupObstacleTwo(Vec3(42.1,22.5,-8.5),1,Vec3(90,0,0)) #self.setupObstacleFive(Vec3(91,0.2, -8),2.1,Vec3(90,0,0)) #Goal self.setupGoal(Vec3(94,-89.7,-10)) self.setupTerrain() elif(self.gameLevel == 3): self.distanceTravelled = 0 self.time = 0 # Plane img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_3.png')) shape = BulletHeightfieldShape(img, 50.0, ZUp) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, 0) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) #skybox skybox = loader.loadModel('media/models/skybox/skybox_01.X') skybox.reparentTo(render) # Chassis shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5)) ts = TransformState.makePos(Point3(0, 0, 1.0)) self.vehicleNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Vehicle')) self.vehicleNP.node().addShape(shape, ts) self.vehicleNP.setPos(-110, -110, 0) self.vehicleNP.setHpr(-40,0,0) self.vehicleNP.node().setMass(5.0) self.vehicleNP.node().setDeactivationEnabled(False) base.cam.setPos(self.vehicleNP.getPos().getX()+2,self.vehicleNP.getPos().getY()+2,self.vehicleNP.getPos().getZ()+2) self.world.attachRigidBody(self.vehicleNP.node()) # Vehicle self.vehicle = BulletVehicle(self.world, self.vehicleNP.node()) self.vehicle.setCoordinateSystem(ZUp) self.world.attachVehicle(self.vehicle) self.hummerNP = loader.loadModel('media/models/vehicle/body.X') self.hummerNP.reparentTo(self.vehicleNP) # Right front wheel np = loader.loadModel('media/models/vehicle/front_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, 0.9, 0.8), True, np) # Left front wheel np = loader.loadModel('media/models/vehicle/front_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, 0.9, 0.8), True, np) # Right rear wheel np = loader.loadModel('media/models/vehicle/back_right.X') np.reparentTo(self.worldNP) self.addWheel(Point3( 0.8, -0.7, 0.8), False, np) # Left rear wheel np = loader.loadModel('media/models/vehicle/back_left.X') np.reparentTo(self.worldNP) self.addWheel(Point3(-0.8, -0.7, 0.8), False, np) self.setupTerrain() #Goal self.setupGoal(Vec3(114,100,-13)) #Obstacles self.setupObstacleFour(Vec3(-60, -73, -9), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(-63, -77, -9), 1, Vec3(0, 0, 0)) self.setupObstacleTwo(Vec3(-15, -40, -3), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(-60, 12, -11), 1, Vec3(0, 0, 0)) self.setupObstacleSix(Vec3(-15, 90, -6), 1.5, Vec3(-30, 0, 0)) self.setupObstacleFour(Vec3(28, 87, -11), 1, Vec3(0, 0, 0)) self.setupObstacleFour(Vec3(32, 90, -11), 1, Vec3(0, 0, 0)) def addWheel(self, pos, front, np): wheel = self.vehicle.createWheel() wheel.setNode(np.node()) wheel.setChassisConnectionPointCs(pos) wheel.setFrontWheel(front) wheel.setWheelDirectionCs(Vec3(0, 0, -1)) wheel.setWheelAxleCs(Vec3(1, 0, 0)) wheel.setWheelRadius(0.4) wheel.setMaxSuspensionTravelCm(40.0) wheel.setSuspensionStiffness(40.0) wheel.setWheelsDampingRelaxation(2.3) wheel.setWheelsDampingCompression(4.4) wheel.setFrictionSlip(100.0); wheel.setRollInfluence(0.1) def setupTerrain(self): if(self.gameLevel == 1): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_1.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(1000) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/longGrass.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/bigRockFace.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/greenrough.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/grayRock.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_1_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) elif(self.gameLevel == 2): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_2.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/sandripple.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/orangesand.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/grayRock.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/bigRockFace.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_2_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) elif(self.gameLevel == 3): #terrain setting img = PNMImage(Filename('media/terrain/SIMP_Assignment_2_Terrain_3.png')) self.terrain = GeoMipTerrain("myTerrain") self.terrain.setHeightfield(img) self.terrain.getRoot().setSz(50) self.terrain.setBlockSize(4) #self.terrain.setFactor(10) #self.terrain.setMinLevel(0) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) self.terrain.getRoot().reparentTo(render) offset = img.getXSize() / 2.0 - 0.5 self.terrain.getRoot().setPos(-offset, -offset, -50 / 2.0) self.terrain.generate() #load textures tex0 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_d.png") tex0.setMinfilter(Texture.FTLinearMipmapLinear) tex1 = loader.loadTexture("media/terrain/hardDirt.png") tex1.setMinfilter(Texture.FTLinearMipmapLinear) tex2 = loader.loadTexture("media/terrain/littlerocks.png") tex2.setMinfilter(Texture.FTLinearMipmapLinear) tex3 = loader.loadTexture("media/terrain/greenrough.png") tex3.setMinfilter(Texture.FTLinearMipmapLinear) tex4 = loader.loadTexture("media/terrain/bigRockFace.png") tex4.setMinfilter(Texture.FTLinearMipmapLinear) tex5 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_c.png") tex5.setMinfilter(Texture.FTLinearMipmapLinear) tex6 = loader.loadTexture("media/terrain/SIMP_Assignment_2_Terrain_3_l.png") tex6.setMinfilter(Texture.FTLinearMipmapLinear) #set mutiltextures self.terrain.getRoot().setTexture( TextureStage('tex0'),tex0 ) self.terrain.getRoot().setTexture( TextureStage('tex1'),tex1 ) self.terrain.getRoot().setTexture( TextureStage('tex2'),tex2 ) self.terrain.getRoot().setTexture( TextureStage('tex3'),tex3 ) self.terrain.getRoot().setTexture( TextureStage('tex4'),tex4 ) self.terrain.getRoot().setTexture( TextureStage('tex5'),tex5 ) self.terrain.getRoot().setTexture( TextureStage('tex6'),tex6 ) #load shader self.terrain.getRoot().setShader(loader.loadShader('terraintexture.sha')) def setupObstacleOne(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1) * scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2 * scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 0.9)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.9)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(0, 0, -0.1 * scale) pivotB = Point3(0, 0, 1 * scale) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) # Box B shape = BulletBoxShape(Vec3(3, 2, 0.1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn); visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 2, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(0, 0, 0) pivotB = Point3(0, 0, -1 * scale) hinge = BulletHingeConstraint(bodyB, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(0,360, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupObstacleTwo(self,pos,scale,turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(0.1, 1, 1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(100.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(2, 0, 0) pivotB = Point3(0, 0, 2) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) # Box C shape = BulletBoxShape(Vec3(0.1, 1, 1)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(100.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(-2, 0, 0) pivotB = Point3(0, 0, 2) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) self.world.attachConstraint(hinge) def setupObstacleThree(self, pos, scale, turn): # Box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)) bodyA = BulletRigidBodyNode('Box A') bodyA.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) #Box B shape = BulletBoxShape(Vec3(0.1,0.1,0.1)) bodyB = BulletRigidBodyNode('Box B') bodyB.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1,0.1,0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Slider frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) slider = BulletSliderConstraint(bodyA, bodyB, frameA, frameB, True) slider.setDebugDrawSize(2.0) slider.setLowerLinearLimit(0) slider.setUpperLinearLimit(12) slider.setLowerAngularLimit(-90) slider.setUpperAngularLimit(-85) self.world.attachConstraint(slider) # Box C shape = BulletBoxShape(Vec3(1, 3, 0.1)) bodyC = BulletRigidBodyNode('Box C') bodyC.setRestitution(1.0) bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(0.1) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(Vec3(pos.getX() + 3, pos.getY() - 4, pos.getZ())) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(1, 3, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) bodyNP.node().setLinearVelocity(-100) # Slider frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0)) slider = BulletSliderConstraint(bodyA, bodyC, frameA, frameB, True) slider.setDebugDrawSize(2.0) slider.setLowerLinearLimit(2) slider.setUpperLinearLimit(6) slider.setLowerAngularLimit(-90) slider.setUpperAngularLimit(-85) self.world.attachConstraint(slider) def setupObstacleFour(self, pos, scale, turn): #Start Here # Box A shape = BulletBoxShape(Vec3(0.01, 0.01, 0.01) * scale) bodyA = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 4) #(0, 0, 4) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.01, 0.01, 0.01)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletSphereShape(0.5*scale) bodyB = BulletRigidBodyNode('Sphere B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(10.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 5) #(0, 0, 0.001) visNP = loader.loadModel('media/models/ball.egg') visNP.clearModelNodes() visNP.setScale(1.25*scale) visNP.reparentTo(bodyNP) bodyNP.node().setLinearVelocity(100) self.world.attachRigidBody(bodyB) # Cone frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(2, 0, 0)*scale, Vec3(0, 0, 0)) cone = BulletConeTwistConstraint(bodyA, bodyB, frameA, frameB) cone.setDebugDrawSize(2.0) cone.setLimit(30, 90, 270, softness=1.0, bias=0.3, relaxation=10.0) self.world.attachConstraint(cone) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 1)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX(), pos.getY(), pos.getZ() + 3) self.world.attachRigidBody(bodyC) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) def setupObstacleSix(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOff()) bodyNP.setPos(pos.getX()-2,pos.getY(),pos.getZ()+2.5)#-2,0,2.5) bodyNP.setHpr(turn) # Box B shape = BulletBoxShape(Vec3(2, 0.1, 3)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX()-3,pos.getY(), pos.getZ())#, 0, 0) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(2, 0.1, 3)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(-2, 0, -3) pivotB = Point3(-2, 0, -3) axisA = Vec3(0, 0, 1) axisB = Vec3(0, 0, 1) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(0,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) #box A shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOff()) bodyNP.setPos(pos.getX()+2,pos.getY(),pos.getZ()+2.5)#2,0,2.5) bodyNP.setHpr(turn) # Box B shape = BulletBoxShape(Vec3(2, 0.1, 3)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setLinearDamping(0.5) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos.getX()+4, pos.getY(), pos.getZ())# 0, 0) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(2, 0.1, 3)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) pivotA = Point3(2, 0, -3) pivotB = Point3(2, 0, -3) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(-90,0, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupObstacleFive(self, pos, scale, turn): #box A shape = BulletBoxShape(Vec3(3, 0.1, 0.1)*scale) bodyA = BulletRigidBodyNode('Box A') bodyNP= self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 0.1, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyA) # Box B shape = BulletBoxShape(Vec3(3, 2, 0.1)*scale) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(3, 2, 0.1)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyB) # Hinge pivotA = Point3(0, 0, 0) pivotB = Point3(0, 0, 5) axisA = Vec3(1, 0, 0) axisB = Vec3(1, 0, 0) hinge = BulletHingeConstraint(bodyA, bodyB, pivotA, pivotB, axisA, axisB, True) hinge.setDebugDrawSize(2.0) hinge.setLimit(-50,50, softness=0.5, bias=0.3, relaxation=0.6) self.world.attachConstraint(hinge) # Box C shape = BulletBoxShape(Vec3(0.1, 0.1, 0.9)*scale) bodyC = BulletRigidBodyNode('Box C') bodyNP = self.worldNP.attachNewNode(bodyC) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setCollideMask(BitMask32.allOn()) bodyNP.setPos(pos) bodyNP.setHpr(turn) visNP = loader.loadModel('media/models/box.egg') visNP.setScale(Vec3(0.1, 0.1, 0.9)*2*scale) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.world.attachRigidBody(bodyC) pivotA = Point3(0, 0, -1.1) pivotB = Point3(0, 0, 1) hinge = BulletHingeConstraint(bodyA, bodyC, pivotA, pivotB, axisA, axisB, True) hinge.setLimit(-90,90, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(hinge) def setupGoal(self, pos): # Goal shape = BulletBoxShape(Vec3(1, 1, 1)) body = BulletRigidBodyNode('Flag') self.flagNP = self.worldNP.attachNewNode(body) self.flagNP.node().addShape(shape) self.flagNP.setCollideMask(BitMask32.allOn()) self.flagNP.setPos(pos) visNP = loader.loadModel('media/models/Flag.X') visNP.clearModelNodes() visNP.reparentTo(self.flagNP) self.world.attachRigidBody(body)
class LightingGUI: def __init__( self, dataPath, lighting1, config, agent1 ): self.dataPath = dataPath self.lighting1 = lighting1 #self.lighting2 = lighting2 self.agent1 = agent1 #self.agent2 = agent2 self.config = config # get lighting presets print 'Presets:' self.presets = [] for entry in self.config: if entry != 'Character1' and entry != 'Character2': self.presets.append(entry) print self.presets self.lighting = lighting1 self.agent = agent1 self.character = 1 self.characterConfig = 'Character1' self.visible = 1 self.lampsVisible = 1 self.addLamps() self.addGUI() self.setPresetsComboBox() #self.setLightingConfiguration() def setLightingConfiguration( self ): section = self.config[self.characterConfig]['Lighting'] ambient = self.config[ section ].as_float( 'Ambient' ) self.sliderAmbient['value'] = ambient for i in range(4): lightConfig = self.config[ section ][ 'Light'+str(i+1) ] theta = lightConfig.as_float( 'Theta' ) * math.pi / 180 phi = lightConfig.as_float( 'Phi' ) * math.pi / 180 intensity = lightConfig.as_float( 'Intensity' ) hue = lightConfig.as_float( 'Hue' ) saturation = lightConfig.as_float( 'Saturation' ) self.thetas[i] = theta self.phis[i] = phi self.intensities[i] = intensity self.hues[i] = hue self.saturations[i] = saturation self.selectLight( 0 ) self.selectLight( 1 ) self.selectLight( 2 ) self.selectLight( 3 ) self.selectLight( 0 ) self.update() def addLamps( self ): self.lamps = [] for i in range(4): lamp = loader.loadModel( self.dataPath + 'models/lamp'+str(i+1)+'/lamp'+str(i+1) ) lamp.reparentTo(render) materials = lamp.findAllMaterials() materials[0].setAmbient( Vec4(0,0,0,0) ) materials[0].setDiffuse( Vec4(0,0,0,0) ) materials[0].setEmission( Vec4(1,1,0,0) ) materials[0].setSpecular( Vec4(0,0,0,0) ) lamp.show(BitMask32.bit(0)) lamp.hide(BitMask32.bit(1)) self.lamps.append( lamp ) def updateLamps( self ): pos = self.agent.getPosition() for i in range(4): lamp = self.lamps[i] light = self.lighting.directionalLights[i] theta = self.thetas[i] phi = self.phis[i] materials = lamp.findAllMaterials() color = Vec4( light.color.getX()*light.intensity,light.color.getY()*light.intensity,light.color.getZ()*light.intensity,0) materials[0].setEmission( color ) radius=9 lamp.setPos( -light.direction.getX()*radius+pos.getX(),-light.direction.getY()*radius+pos.getY(),-light.direction.getZ()*radius+pos.getZ()) lamp.setScale( 0.5 ) lamp.setHpr( -theta*180/3.1416, phi*180/3.1416-90, 0 ) """characterIndex = self.character - 1 lamp.show(BitMask32.bit( characterIndex )) lamp.hide(BitMask32.bit( 1-characterIndex ))""" lamp.hide(BitMask32.bit( self.character )) def hideLamps( self ): self.lampsVisible = 0 for i in range(4): lamp = self.lamps[i] lamp.hide() def showLamps( self ): self.lampsVisible = 1 for i in range(4): lamp = self.lamps[i] lamp.show() def setPresetsComboBox( self ): preset = self.config[self.characterConfig]['Lighting'] index = 0 for entry in self.presets: if entry == preset: break index = index+1 self.presetsComboBox.set( index ) def presetSelected( self, args ): preset = self.presets[ self.presetsComboBox.selectedIndex ] print "Selected preset: " + preset self.config[self.characterConfig]['Lighting'] = preset self.setLightingConfiguration() def addGUI( self ): # Add some text #self.textObject = OnscreenText(text = "Lighting comparison", pos = (0.95,-0.95), scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1) #character self.label1 = OnscreenText(text = "Character: ", pos = (-1.02,0.95), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.characterLabel = OnscreenText(text = "1", pos = (-0.78,0.95), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.characterButton = DirectButton(text = ("Switch"), scale=.05, pos = (-0.9,0,0.95), command=self.toggleCharacter) #line self.label2 = OnscreenText(text = "-------------------------------------------------", pos = (-0.40,0.9), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label3 = OnscreenText(text = "Light: ", pos = (-1.02,0.75), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1 ) self.lightColorLabel = OnscreenText(text = "| |", pos = (-0.69,0.75), scale = 0.05,fg=(0,0,0,1),align=TextNode.ARight,mayChange=1, bg=(0,0,0,1) ) self.label4 = OnscreenText(text = "Theta [0..360]: ", pos = (-1.02,0.69), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label5 = OnscreenText(text = "Phi [-90..90]: ", pos = (-1.02,0.64), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label6 = OnscreenText(text = "Intensity [0..2]: ", pos = (-1.02,0.59), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label7 = OnscreenText(text = "Hue [0..360]: ", pos = (-1.02,0.54), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label8 = OnscreenText(text = "Saturation [0..1]: ", pos = (-1.02,0.49), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label9 = OnscreenText(text = "Ambient [0..1]: ", pos = (-1.02,0.44), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label10 = OnscreenText(text = "Lamps: ", pos = (-1.02,0.35), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label11 = OnscreenText(text = "-------------------------------------------------", pos = (-0.40,0.3), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.label12 = OnscreenText(text = "Config: ", pos = (-1.02,0.25), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) # Add button #presets self.label13 = OnscreenText(text = "Preset: ", pos = (-1.02,0.85), scale = 0.05,fg=(1,0.5,0.5,1),align=TextNode.ARight,mayChange=1) self.presetsComboBox = DirectOptionMenu(text="options", scale=.05,items=self.presets,initialitem=0, pos = (-1.0,0,0.85), highlightColor=(0.65,0.65,0.65,1),textMayChange=1,command=self.presetSelected, extraArgs=[]) self.button1 = DirectButton(text = ("Update Preset"), scale=.05, pos = (-0.6,0,0.85), command=self.updatePreset, extraArgs=[]) #lights self.button2 = DirectButton(text = (" 1 "), scale=.05, pos = (-1,0,0.75), command=self.selectLight, extraArgs=[0]) self.button3 = DirectButton(text = (" 2 "), scale=.05, pos = (-0.95,0,0.75), command=self.selectLight, extraArgs=[1]) self.button4 = DirectButton(text = (" 3 "), scale=.05, pos = (-0.9,0,0.75), command=self.selectLight, extraArgs=[2]) self.button5 = DirectButton(text = (" 4 "), scale=.05, pos = (-0.85,0,0.75), command=self.selectLight, extraArgs=[3]) self.button6 = DirectButton(text = ("Show"), scale=.05, pos = (-0.94,0,0.35), command=self.showLamps, extraArgs=[]) self.button7 = DirectButton(text = ("Hide"), scale=.05, pos = (-0.79,0,0.35), command=self.hideLamps, extraArgs=[]) self.button8 = DirectButton(text = ("Save"), scale=.05, pos = (-0.94,0,0.25), command=self.saveConfig, extraArgs=[]) self.sliderTheta = DirectSlider(range=(0,6.28), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.7), command=self.updateLights) self.sliderPhi = DirectSlider(range=(-3.1416/2,3.1416/2), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.65), command=self.updateLights) self.sliderIntensity = DirectSlider(range=(0,2), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.6), command=self.updateLights) self.sliderHue = DirectSlider(range=(0,360), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.55), command=self.updateLights) self.sliderSaturation = DirectSlider(range=(0,1), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.5), command=self.updateLights) self.sliderAmbient = DirectSlider(range=(0,1), value=0, pageSize=2, scale=.3, pos = (-0.7,0,0.45), command=self.updateLights) self.thetas = [ 0, 0, 0, 0 ] self.phis = [ 0, 0, 0, 0 ] self.intensities = [ 1, 0, 0, 0 ] self.hues = [ 0, 0, 0, 0 ] self.saturations = [ 0, 0, 0, 0 ] self.selectLight( 0 ) self.selectLight( 1 ) self.selectLight( 2 ) self.selectLight( 3 ) self.selectLight( 0 ) def saveConfig( self ): self.config.write() def updatePreset( self ): section = self.config[self.characterConfig]['Lighting'] ambient = self.sliderAmbient['value'] self.config[ section ]['Ambient'] = str( ambient ) for i in range(4): lightConfig = self.config[ section ][ 'Light'+str(i+1) ] theta = self.thetas[i] * 180 / math.pi phi = self.phis[i] * 180 / math.pi intensity = self.intensities[i] hue = self.hues[i] saturation = self.saturations[i] lightConfig['Theta'] = theta lightConfig['Phi'] = phi lightConfig['Intensity'] = intensity lightConfig['Hue'] = hue lightConfig['Saturation'] = saturation self.config[ section ][ 'Light'+str(i+1) ] = lightConfig self.toggleCharacter() print "Updating preset" self.toggleCharacter() def toggleCharacter( self ): if self.character == 1: self.character = 2 #self.lighting = self.lighting2 self.characterConfig = 'Character2' #self.agent = self.agent2 else: self.character = 1 self.lighting = self.lighting1 self.characterConfig = 'Character1' self.agent = self.agent1 #self.characterButton.setText('blub') self.characterLabel.setText( str(self.character) ) #self.setLightingConfiguration() self.setPresetsComboBox() def updateLights( self ): theta = self.sliderTheta['value'] phi = self.sliderPhi['value'] intensity = self.sliderIntensity['value'] hue = self.sliderHue['value'] saturation = self.sliderSaturation['value'] self.thetas[ self.lightIndex ] = theta self.phis[ self.lightIndex ] = phi self.intensities[ self.lightIndex ] = intensity self.hues[ self.lightIndex ] = hue self.saturations[ self.lightIndex ] = saturation light = self.lighting.directionalLights[ self.lightIndex ] light.direction = Vec3( math.sin(theta) * math.cos(phi), math.cos(theta) * math.cos(phi), math.sin(phi) ) light.intensity = intensity light.color = hsvToRGB( hue, saturation, 1 ) self.lightColorLabel['fg'] = Vec4(0,0,0,0) self.lightColorLabel['bg'] = light.color * intensity self.updateLamps() def updateGUI( self ): theta = self.thetas[ self.lightIndex ] phi = self.phis[ self.lightIndex ] intensity = self.intensities[ self.lightIndex ] hue = self.hues[ self.lightIndex ] saturation = self.saturations[ self.lightIndex ] self.sliderTheta['value'] = theta self.sliderPhi['value'] = phi self.sliderIntensity['value'] = intensity self.sliderHue['value'] = hue self.sliderSaturation['value'] = saturation # Callback function to set text def selectLight( self, index ): #self.textObject.setText( "Button Clicked " + str(index) ) self.lightIndex = index self.updateGUI() self.updateLights() def update( self ): intensity = self.sliderAmbient['value'] self.lighting.ambientColor = Vec4(intensity,intensity,intensity,0) self.lighting.update() def toggleVisible( self ): if self.visible == 1: self.visible = 0 self.characterLabel.hide() self.characterButton.hide() self.lightColorLabel.hide() self.presetsComboBox.hide() self.label1.hide() self.label2.hide() self.label3.hide() self.label4.hide() self.label5.hide() self.label6.hide() self.label7.hide() self.label8.hide() self.label9.hide() self.label10.hide() self.label11.hide() self.label12.hide() self.label13.hide() self.button1.hide() self.button2.hide() self.button3.hide() self.button4.hide() self.button5.hide() self.button6.hide() self.button7.hide() self.button8.hide() self.sliderTheta.hide() self.sliderPhi.hide() self.sliderIntensity.hide() self.sliderHue.hide() self.sliderSaturation.hide() self.sliderAmbient.hide() self.lampsWereVisible = self.lampsVisible self.hideLamps() else: self.visible = 1 self.characterLabel.show() self.characterButton.show() self.lightColorLabel.show() self.presetsComboBox.show() self.label1.show() self.label2.show() self.label3.show() self.label4.show() self.label5.show() self.label6.show() self.label7.show() self.label8.show() self.label9.show() self.label10.show() self.label11.show() self.label12.show() self.label13.show() self.button1.show() self.button2.show() self.button3.show() self.button4.show() self.button5.show() self.button6.show() self.button7.show() self.button8.show() self.sliderTheta.show() self.sliderPhi.show() self.sliderIntensity.show() self.sliderHue.show() self.sliderSaturation.show() self.sliderAmbient.show() if self.lampsWereVisible == 1: self.showLamps()
class App(ShowBase): def __init__(self): ShowBase.__init__(self) # Print all events sent through the messenger #self.messenger.toggleVerbose() self.lblWarning = OnscreenText( text = "No devices found", fg=(1,0,0,1), scale = .25) self.lblAction = OnscreenText( text = "Action", fg=(1,1,1,1), scale = .15) self.lblAction.hide() # Is there a gamepad connected? self.flightStick = None devices = self.devices.getDevices(InputDevice.DeviceClass.flight_stick) if devices: self.connect(devices[0]) self.currentMoveSpeed = 0.0 self.maxAccleration = 28.0 self.deaccleration = 10.0 self.deaclerationBreak = 37.0 self.maxSpeed = 80.0 # Accept device dis-/connection events self.accept("connect-device", self.connect) self.accept("disconnect-device", self.disconnect) self.accept("escape", exit) self.accept("flight_stick0-start", exit) # Accept button events of the first connected flight stick self.accept("flight_stick0-trigger", self.action, extraArgs=["Trigger"]) self.accept("flight_stick0-trigger-up", self.actionUp) self.environment = loader.loadModel("environment") self.environment.reparentTo(render) # disable pandas default mouse-camera controls so we can handle the camera # movements by ourself self.disableMouse() self.reset() self.taskMgr.add(self.moveTask, "movement update task") def connect(self, device): """Event handler that is called when a device is discovered.""" # We're only interested if this is a flight stick and we don't have a # flight stick yet. if device.device_class == InputDevice.DeviceClass.flight_stick and not self.flightStick: print("Found %s" % (device)) self.flightStick = device # Enable this device to ShowBase so that we can receive events. # We set up the events with a prefix of "flight_stick0-". self.attachInputDevice(device, prefix="flight_stick0") # Hide the warning that we have no devices. self.lblWarning.hide() def disconnect(self, device): """Event handler that is called when a device is removed.""" if self.flightStick != device: # We don't care since it's not our gamepad. return # Tell ShowBase that the device is no longer needed. print("Disconnected %s" % (device)) self.detachInputDevice(device) self.flightStick = None # Do we have any other gamepads? Attach the first other gamepad. devices = self.devices.getDevices(InputDevice.DeviceClass.flight_stick) if devices: self.connect(devices[0]) else: # No devices. Show the warning. self.lblWarning.show() def reset(self): """Reset the camera to the initial position.""" self.camera.setPosHpr(0, -200, 10, 0, 0, 0) def action(self, button): # Just show which button has been pressed. self.lblAction.text = "Pressed %s" % button self.lblAction.show() def actionUp(self): # Hide the label showing which button is pressed. self.lblAction.hide() def moveTask(self, task): dt = globalClock.getDt() if not self.flightStick: return task.cont if self.currentMoveSpeed > 0: self.currentMoveSpeed -= dt * self.deaccleration if self.currentMoveSpeed < 0: self.currentMoveSpeed = 0 # Accelerate using the throttle. Apply deadzone of 0.01. throttle = self.flightStick.findAxis(InputDevice.Axis.throttle).value if abs(throttle) < THROTTLE_DEAD_ZONE: throttle = 0 accleration = throttle * self.maxAccleration if self.currentMoveSpeed > throttle * self.maxSpeed: self.currentMoveSpeed -= dt * self.deaccleration self.currentMoveSpeed += dt * accleration # Steering # Control the cameras yaw/Headding stick_yaw = self.flightStick.findAxis(InputDevice.Axis.yaw) if abs(stick_yaw.value) > STICK_DEAD_ZONE: base.camera.setH(base.camera, 100 * dt * stick_yaw.value) # Control the cameras pitch stick_y = self.flightStick.findAxis(InputDevice.Axis.pitch) if abs(stick_y.value) > STICK_DEAD_ZONE: base.camera.setP(base.camera, 100 * dt * stick_y.value) # Control the cameras roll stick_x = self.flightStick.findAxis(InputDevice.Axis.roll) if abs(stick_x.value) > STICK_DEAD_ZONE: base.camera.setR(base.camera, 100 * dt * stick_x.value) # calculate movement base.camera.setY(base.camera, dt * self.currentMoveSpeed) # Make sure camera does not go below the ground. if base.camera.getZ() < 1: base.camera.setZ(1) return task.cont
class OnScreenInterface(): # Time users have for each level will be listed here LEVEL_1_TIME = (3,59) LEVEL_2_TIME = (6,59) ''' Constructor takes a reference of the current game, creates a direct frame that everything will be parented to and also sets the sound effect that will be used for aything on the onscreen interface class. @param game - pointer to current game ''' def __init__(self,game): self.previous = -1 self.min = 0 self.sec = 0 self.__game = game self.create_main_frame() self.set_sound() ''' Creates instance variables for all sounds effects that will be used for this instance of the class. Volume and playrate is also set. ''' def set_sound(self): self.intro = base.loader.loadMusic("sfx/not_seems.mp3") self.hover = base.loader.loadSfx("sfx/hover.mp3") self.click = base.loader.loadSfx("sfx/click.wav") self.pause = base.loader.loadSfx("sfx/pause.wav") self.blocked = base.loader.loadSfx("sfx/blocked.wav") self.blocked.setVolume(.05) self.hover.setPlayRate(5) self.hover.setVolume(.05) self.intro.setVolume(.5) self.intro.setLoop(True) ''' Creates instance variable that decides how much time user will have to complete the current level ''' def set_timer(self,level): if level == 'L1': self.min = OnScreenInterface.LEVEL_1_TIME[0] self.sec = OnScreenInterface.LEVEL_1_TIME[1] elif level == 'L2': self.min = OnScreenInterface.LEVEL_2_TIME[0] self.sec = OnScreenInterface.LEVEL_2_TIME[1] ''' Creates the initial two frames that are needed in the game before the gameplay starts ''' def load_initial_interface(self): self.create_player() self.create_start() self.create_stage_selector(button=False) ''' Creates the rest of the frames that are needed once gameplay has started ''' def load_essentials(self): self.create_health_bar() self.create_token_counter() self.create_coordinate_view() self.create_help_menu() self.create_control_guide() self.create_stage_selector() self.create_leaderboard_selector() self.create_leaderboard(self.__game.current_level) #------------------------------------------------------------------------- CREATE METHODS -----------------------------------------------------------------# ''' Creates frame that will be the parent of all the other frames created for this game. This is done so that when all gui interfaces need to be destroyed they can be destroyed with on call to destroy. ''' def create_main_frame(self): self.main_frame = DirectFrame(frameColor = (0,0,0,0),frameSize=(-2,2,-1,1), pos=(0,0,0)) ''' Creates game start frame. This frame is not hidden because it is the first thing the user sees. ''' def create_start(self): # Direct frame to hold contents of start frame self.start_frame = DirectFrame(parent = self.main_frame,frameColor = (0,0,0,1),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Onscreen image of kyklops kyklops = OnscreenImage(parent=self.start_frame,image = 'img/kyklops.png', pos = (.9, 0, .3), scale = (.3,0,.3)) kyklops.setTransparency(TransparencyAttrib.MAlpha) # Onscreen image of game title title = OnscreenImage(parent=self.start_frame,image = 'img/title.png', pos = (0, 0, 0), scale = (.8,0,.3)) title.setTransparency(TransparencyAttrib.MAlpha) # Onscreen image of eve rolling rolling_eve = OnscreenImage(parent=self.start_frame,image = 'img/rolling-eve.png', pos = (-.95, 0, -.1), scale = (.5,0,.5)) rolling_eve.setTransparency(TransparencyAttrib.MAlpha) # Create button to start game self.create_menu_button(self.start_frame,'START',LVecBase3f(0,0,-.5),self.show_input) # Play intro music self.intro.play() ''' Creates a fields so the player can input his/her name at the beginning of the game. This is used to store the name and user score at the end of each stage in the game. ''' def create_player(self): # Direct frame to hold input field self.input_frame = DirectFrame(parent=self.main_frame,frameColor = (0,0,0,1),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Instructions for user instructions = OnscreenText(parent=self.input_frame, text = 'Enter your name: ', pos = (0,.2), scale = 0.1, fg=(0,.2,.2,1),shadow=(1,1,1,.7)) # Name input field self.entry = DirectEntry(parent=self.input_frame,text = "",scale=(.1,1,.08),pos=(-.5,0,0),command=self.set_player,numLines=1,focus=1) # Hide frame self.input_frame.hide() ''' Creates help menu frame with buttons for each option in the menu. This frame is hidden. ''' def create_help_menu(self): # Direct frame to hold buttons and text self.help_frame = DirectFrame(parent=self.main_frame,frameColor = (.6,.6,.6,.7),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Title for frame title = OnscreenText(parent=self.help_frame, text = 'MENU', pos = (0, .4), scale = 0.2, fg=(0,.2,.2,1),shadow=(.5,.5,.5,1) ) # Buttons for menu frame self.create_menu_button(self.help_frame,'Controls',LVecBase3f(0,0,.1),self.show_controls) self.create_menu_button(self.help_frame,'Level Select',LVecBase3f(0,0,-.1),self.show_level_select) self.create_menu_button(self.help_frame,'Leaderboard',LVecBase3f(0,0,-.3),self.show_lb_selection) self.create_menu_button(self.help_frame,'Quit',LVecBase3f(0,0,-.5),sys.exit) # Hide frame self.help_frame.hide() ''' Creates control instruction frame. This frame hidden. ''' def create_control_guide(self): # Direct frame to hold player control instructions self.control_frame = DirectFrame(frameColor = (.9,.9,.9,.9),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Title for frame frame_title = OnscreenText(parent=self.control_frame, text = 'CONTROL KEYS', pos = (0, .5), scale = 0.1, fg=(0,.2,.2,1),shadow=(.5,.5,.5,1)) OnscreenText(parent=self.control_frame, text = 'PLAYER CONTROLS', pos = (-.5, .3), scale = 0.08, fg=(0,0,0,1),shadow=(.5,.5,.5,1)) OnscreenText(parent=self.control_frame, text = 'OTHER CONTROLS', pos = (.5, .3), scale = 0.08, fg=(0,0,0,1),shadow=(.5,.5,.5,1)) # Player control instructions OnscreenText(parent=self.control_frame, text = '[w] - Forward', pos = (-.5, .2), scale = 0.07, fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[a] - Left', pos = (-.5, .1), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[d] - Right', pos = (-.5, 0), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[s] - Back', pos = (-.5, -.1), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[space] - Jump', pos = (-.5, -.2), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[m] - Toggle Modes', pos = (-.5, -.3), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[h] - Help Menu', pos = (.5, .2), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[c] - Toggle Camera Modes', pos = (.5, .1), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[q] - Toggle Music On/Off', pos = (.5, 0), scale = 0.07,fg=(0,0,0,1)) OnscreenText(parent=self.control_frame, text = '[x] - Toggle SFX On/Off', pos = (.5, -.1), scale = 0.07,fg=(0,0,0,1)) # Create button to go back to main menu self.create_menu_button(self.control_frame,'Back',LVecBase3f(0,0,-.7),self.show_menu) # Hide frame self.control_frame.hide() ''' Creates stage selection frame. This frame is hidden. ''' def create_stage_selector(self,button=True): # Direct frame to hold stage selection buttons self.stage_select_frame = DirectFrame(parent=self.main_frame,frameColor = (.8,.8,.8,.9),frameSize=(-2,2,-1,1), pos=(0,0,0)) title = OnscreenText(parent=self.stage_select_frame, text = 'Stage Selection', pos = (0, .7), scale = .15,fg=(0,.2,.2,1)) # Stage select buttons with title for each button t1 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 1', pos = (-.9, .5), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/stage1.png','',LVecBase3f(-.9,0,.2),self.__game.clean_and_set,'L1') # Stage 2 will be unlocked when stage 2 is made t2 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 2', pos = (-.3, .5), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/stage2.png','',LVecBase3f(-.3,0,.2),self.__game.clean_and_set,'L2') t3 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 3', pos = (.3, .5), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(.3,0,.2),self.__game.clean_and_set,'L3') t4 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 4', pos = (.9, .5), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(.9,0,.2),self.__game.clean_and_set,'L4') t5 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 5', pos = (-.9, -.1), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(-.9,0,-.4),self.__game.clean_and_set,'L5') t6 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 6', pos = (-.3, -.1), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(-.3,0,-.4),self.__game.clean_and_set,'L6') t7 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 7', pos = (.3, -.1), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(.3,0,-.4),self.__game.clean_and_set,'L7') t8 = OnscreenText(parent=self.stage_select_frame, text = 'STAGE 8', pos = (.9, -.1), scale = 0.07,fg=(0,.2,.2,1)) self.create_stage_button(self.stage_select_frame,'img/locked.jpg','',LVecBase3f(.9,0,-.4),self.__game.clean_and_set,'L8') if button is True: # Create button to go back to main menu self.create_menu_button(self.stage_select_frame,'Back',LVecBase3f(0,0,-.8),self.show_menu) # Hide frame self.stage_select_frame.hide() ''' Creates leaderboard selection frame which will contain links to the leaderboard for the different game stages. This frame is hidden. ''' def create_leaderboard_selector(self): # Direct frame to hold links to the leaderboards for different levels self.leaderboard_selection_frame = DirectFrame(parent=self.main_frame,frameColor = (.8,.8,.8,.9),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Frame title title = OnscreenText(parent=self.leaderboard_selection_frame, text = 'LEADERBOARD SELECTION', pos = (0, .6), scale = 0.15, fg=(0,.2,.2,1),shadow=(.5,.5,.5,1)) # Links to leaderboards for the stages that are currently made self.link(self.leaderboard_selection_frame,'STAGE 1',LVecBase3f(0,0,.0),self.show_leaderboard,'L1') self.link(self.leaderboard_selection_frame,'STAGE 2',LVecBase3f(0,0,-.1),self.show_leaderboard,'L2') # Create button to go back to main menu self.create_menu_button(self.leaderboard_selection_frame,'Back',LVecBase3f(0,0,-.4),self.show_menu) # Hide frame self.leaderboard_selection_frame.hide() ''' Leaderboard is created based on the level that was clicked on the leaderboard selector frame. This information is gathered from the stored information in .leaderboard.txt. This method will look for the correct section in the file and output the information for the stage choosen onto a direct frame. ''' def create_leaderboard(self,level): # Direct frame to hold all contents of the leaderboard self.leaderboard_frame = DirectFrame(parent=self.main_frame,frameColor = (.8,.8,.8,.9),frameSize=(-2,2,-1,1), pos=(0,0,0)) # Create a scroll_frame to hold contents of leaderboard file scroll_frame = DirectScrolledFrame(parent = self.leaderboard_frame, canvasSize=(-1,1,-4,4), frameColor = (1,1,1,.9), frameSize=(-1,1,-.5,.5), pos=(0,0,0), manageScrollBars=True, scrollBarWidth = .04, autoHideScrollBars = True) # Frame title title = OnscreenText(parent=self.leaderboard_frame, text = 'LEADERBOARD', pos = (0, .6), scale = 0.15, fg=(0,.2,.2,1),shadow=(.5,.5,.5,1)) # Open .leaderboard.txt file as read only leaderboard_file = open('files/.leaderboard.txt','r') start_read = False # Boolean that will used to notify loop when to start generating text on the scroll canvas start = leaderboard_file.read(1) # Reads only the first byte of the file, equivalent to a character # Guide for leaderboard name = OnscreenText(parent=scroll_frame.getCanvas(), text = 'NAME', pos = (-.1, 3.9), scale = 0.075,fg=(0,.2,.2,1)) score = OnscreenText(parent=scroll_frame.getCanvas(), text = 'SCORE', pos = (.5, 3.9), scale = 0.075,fg=(0,.2,.2,1)) index = 1 v_pos = 3.8 # Loop will iterate through the contents of the file while len(start) != 0: if start == '#': leaderboard_file.readline() # Comments in text file start with an octothorpe and are ignored elif start == '@'and start_read is False: # Line with @ signify the beginning of a set of level info if leaderboard_file.readline().split()[0] == level: # This checks if the info that follows is the information we need start_read = True elif start == '@'and start_read is True: # If this condition is true then we read through all the information we need break elif start_read is True: coord = leaderboard_file.readline().split(',') if len(coord) == 1: name = 'Unknown' score = coord[0] else: name = start + coord[0] score = coord[1] entry_text = str(index) + ".\t " + name + '\t\t' + score # Create onscreen text for each entry entry = OnscreenText(parent=scroll_frame.getCanvas(), text = entry_text, pos = (0,v_pos), scale = 0.07,fg=(0,0,0,1)) # Increase index and decrease vertical position index += 1 v_pos -= .1 # Read the first byte of the next line start = leaderboard_file.read(1) leaderboard_file.close() # Create button to go back to the leaderboard selection frame self.create_menu_button(self.leaderboard_frame,'Back',LVecBase3f(0,0,-.7),self.show_lb_selection) # Hide frame self.leaderboard_frame.hide() ''' Creates a frame in the top of the window that shows player health and timer. Frame is hidden. ''' def create_health_bar(self): # Direct frame that holds all contents such as timer and health bar self.health_frame = DirectFrame(parent=self.main_frame,frameColor=(0, 0, 0, .4),frameSize=(-2, 3, -.1, 1),pos=(-.6, 0, .9)) # Create a direct wait bar that will be used as the health gauge. self.bar = DirectWaitBar(parent=self.health_frame, text = "HEALTH", text_fg=(1,1,1,1), value = 100, range=100, pos = (.15,0,-.02), barColor=VBase4(0,.2,.2,1), scale=.6) # Onscreen image for eve face icon on health gauge eve_icon = OnscreenImage(parent=self.bar,image = 'img/eve_face.png', pos = (-1.15, 0, -.075), scale = (.25,1,.25)) eve_icon.setTransparency(TransparencyAttrib.MAlpha) # Create a node for timer timer_txt = str(self.min) + ' min ' + str(self.sec) + ' seconds' self.timer = OnscreenText(parent=self.health_frame, text = timer_txt, pos = (1.5, -.02), scale = 0.07, fg=(1,1,1,1)) # Hide frame self.health_frame.hide() ''' Creates an a token counter in the right bottom corner of screen. This image is hidden. ''' def create_token_counter(self): # Set onscreen image and set transparency self.shape = OnscreenImage(image = 'img/tire_score.png', pos = (1, 0, -.85), scale = (.3,1,.1)) self.shape.setTransparency(TransparencyAttrib.MAlpha) # Set another onscreen image and set transparency tire = OnscreenImage(parent=self.shape,image = 'img/tire.png', pos = (-1, 0, 0), scale = (.4,1,1)) tire.setTransparency(TransparencyAttrib.MAlpha) # Set text displaying the number of token collected self.score = OnscreenText(parent=self.shape, text = str(self.__game.eve.tiresCollected), pos = (0, -.1), scale = (.3,.8), fg=(255,255,255,1)) # Hide token counter self.shape.hide() ''' Creates a frame that displays the name of the stage at the beginning of every stage in the game. Only level 1 and 2 are set. ''' def create_stage_title(self,level): s_text = "" t_text = "" # The following if statement set the text that will be displayed if level == 'L1': s_text = "Stage 1:" t_text = "The Journey Begins" elif level == 'L2': s_text = "Stage 2:" t_text = "The Dark Place" # Direct frame to hold stage title self.stage_frame = DirectFrame(parent=self.main_frame,frameColor=(0, 0, 0, .6),frameSize=(-2, 3, -.1, .4),pos=(0, 0, 0)) stage_name = OnscreenText(parent=self.stage_frame, text = s_text, pos = (0, .2), scale = 0.16, fg=(1,.84,0,1),shadow=(1,1,1,.2)) stage_title = OnscreenText(parent=self.stage_frame, text = t_text, pos = (0, 0), scale = 0.12, fg=(1,.84,0,1),shadow=(1,1,1,.2)) ''' Creates onscreen text showing current position of the character ''' def create_coordinate_view(self): self.coord = OnscreenText(parent=self.main_frame,text='1', style = 1, fg= (1,1,1,1), pos=(0,-0.95), align=TextNode.A_right, scale=0.08) self.coord.hide() #------------------------------------------------------------------------- SHOW METHODS -----------------------------------------------------------------# ''' Shows input frame so user can enter his/her name. ''' def show_input(self): self.__game.accept('h', self.do_nothing) self.start_frame.destroy() self.input_frame.show() ''' Shows menu frame and hides anything else that may be showing ''' def show_menu(self): if self.control_frame.isHidden() is False: self.control_frame.hide() elif self.leaderboard_selection_frame.isHidden() is False: self.leaderboard_selection_frame.hide() elif self.stage_select_frame.isHidden() is False: self.stage_select_frame.hide() self.__game.accept('h', self.toggleHelp) self.help_frame.show() ''' Shows frame that contains the game instructions ''' def show_controls(self): self.__game.accept('h', self.do_nothing) self.help_frame.hide() self.control_frame.show() ''' Shows stage select frame ''' def show_level_select(self): self.__game.accept('h', self.do_nothing) self.help_frame.hide() self.stage_select_frame.show() ''' Shows leaderboard selector frame ''' def show_lb_selection(self): if self.leaderboard_frame.isHidden() is False: self.leaderboard_frame.hide() elif self.help_frame.isHidden() is False: self.__game.accept('h', self.do_nothing) self.help_frame.hide() self.leaderboard_selection_frame.show() ''' Shows leaderboard frame for a specific level @param level - stage whose leaderboard will be displayed ''' def show_leaderboard(self,level): self.leaderboard_selection_frame.hide() self.create_leaderboard(level) self.leaderboard_frame.show() ''' Shows in game stats, which is health gauge, timer and token counter ''' def show_game_interface(self): self.health_frame.show() self.shape.show() ''' Hides the game interface. This is used when the help menu us shown. ''' def hide_game_interface(self): self.health_frame.hide() self.shape.hide() #------------------------------------------------------------------------- CREATE BTN METHODS -----------------------------------------------------------------# ''' Creates a button with an= simple button image as the background. This is the default btn. @param parent - who the button will be parented to @param btn_text - text that will be displayed on button @param btn_pos - position of the button @param cmd - command that will be executed when button is clicked @param level - each link created is based on a stage, this is the stage this btn represents ''' def create_menu_button(self,parent,btn_text,btn_pos,cmd): start_btn = DirectButton(parent=parent, text=btn_text, pos=btn_pos, scale=(.2,1,.15), command=cmd, pressEffect=1, text_scale=(.4,.4), text_pos=(.1,.1), text_fg=(.1,.1,.1,1), text_shadow=(1,1,1,1), image='img/btn2.png', image_scale=(2.50,1,.7), image_pos=(0,1,.25), relief=None, rolloverSound = self.hover, clickSound=self.click) start_btn.setTransparency(TransparencyAttrib.MAlpha) ''' Creates a button that contains an image of a stage or if it was not yet created it contains an image of a lock @param parent - who the button will be parented to @param btn_text - text that will be displayed on button @param btn_pos - position of the button @param cmd - command that will be executed when button is clicked @param level - each link created is based on a stage, this is the stage this btn represents ''' def create_stage_button(self,parent,img,btn_text,btn_pos,cmd,level): click_sound = self.blocked hover_sound = self.blocked # This if statement sets the sound that each button will have. # Everything that is not level 1 or level 2 will have the blocked sound effect and will do nothing if level == 'L1' or level == 'L2': click_sound = self.click hover_sound = self.hover btn = DirectButton(parent=parent, text=btn_text, pos=btn_pos, scale=(.2,1,.15), command=cmd, pressEffect=1, text_scale=(.4,.4), text_pos=(.1,.1), text_fg=(.1,.1,.1,1), text_shadow=(1,1,1,1), image=img, image_scale=(1,1,1), image_pos=(0,1,.25), relief=None, rolloverSound = hover_sound, clickSound=click_sound, extraArgs=[level]) btn.setTransparency(TransparencyAttrib.MAlpha) ''' Creates a button with no relief and no background image or color. @param parent - who the button will be parented to @param btn_text - text that will be displayed on button @param btn_pos - position of the button @param cmd - command that will be executed when button is clicked @param level - each link created is based on a stage, this is the stage this btn represents ''' def link(self,parent,btn_text,btn_pos,cmd,level): btn = DirectButton(parent=parent, text=btn_text, pos=btn_pos, scale=(.2,1,.15), command=cmd, pressEffect=1, text_scale=(.4,.4), text_pos=(.1,.1), text_fg=(.1,.1,.1,1), relief=None, rolloverSound = self.hover, clickSound=self.click, extraArgs = [level]) def link2(self,parent,btn_text,btn_pos,cmd): btn = DirectButton(parent=parent, text=btn_text, pos=btn_pos, scale=(.2,1,.15), command=cmd, pressEffect=1, text_scale=(.4,.4), text_pos=(.1,.1), text_fg=(.1,.1,.1,1), relief=None, rolloverSound = self.hover, clickSound=self.click) #------------------------------------------------------------------------- TASK METHODS -----------------------------------------------------------------# ''' At the beginning of every stage the title is show. This task only runs for the first 2 seconds of each stage. It shows the stage title for 2 seconds and then destroys the frame containing the title and the task ends. ''' def show_title(self,task): if globalClock.getRealTime() - self.__game.actual_start > 2: # Wait two seconds self.stage_frame.destroy() self.show_game_interface() self.__game.eve.enable_character_controls() # Enable character controls only after the two seconds have passed self.__game.accept('h', self.toggleHelp) self.__game.accept('f1', self.__game.toggleDebug) return Task.done return Task.cont ''' This task runs continuously throughout each stage. It updates the time remaining in the current level. This task ends when the minutes and seconds reach 0. ''' def update_timer(self,task): elapsed_time = globalClock.getRealTime() - self.__game.actual_start change_time = int(elapsed_time) % 60 if change_time == 0 and self.previous != int(elapsed_time): self.min = self.min - int(elapsed_time) / 60 self.sec = 59 else: if self.previous != int(elapsed_time): self.sec = 59 - change_time self.timer['text'] = str(self.min) + ' min ' + str(self.sec) + ' seconds' self.previous = int(elapsed_time) if self.min == 0 and self.sec == 0: self.__game.game_over = True return Task.done return Task.cont ''' In debug mode the user can view the players current position in the left bottom corner. This task takes care of updating that position onscreen text. ''' def updateCoord(self, task): x = self.__game.eve.currentNP.getX() y = self.__game.eve.currentNP.getY() z = self.__game.eve.currentNP.getZ() self.coord.setText(str(x) + " , " + (str(y)) + " , " + str(z)) return Task.cont def game_over(self): self.game_over_frame = DirectFrame(parent = self.main_frame,frameColor=(1, 1, 1, .7),frameSize=(-2, 2, 1, -1),pos=(0, 0, 0)) OnscreenText(parent = self.game_over_frame,text = 'GAME OVER', pos = (0, 0), scale = .1, fg=(1,0,0,1)) OnscreenText(parent = self.game_over_frame,text = 'RETRY?', pos = (0, -.2), scale = .07, fg=(1,0,0,1)) self.link(self.game_over_frame,'YES',LVecBase3f(.3,0,-.3),self.__game.clean_and_set,self.__game.current_level) self.link2(self.game_over_frame,'NO',LVecBase3f(-.3,0,-.3),sys.exit) def level_passed(self): self.level_passed_frame = DirectFrame(parent = self.main_frame,frameColor=(1, 1, 1, .9),frameSize=(-2, 2, 1, -1),pos=(0, 0, 0)) if self.__game.current_level == 'L1': t1 = OnscreenText(parent = self.level_passed_frame,text = 'STAGE 1 COMPLETE', pos = (0, 0), scale = .1, fg=(1,0,0,1)) elif self.__game.current_level == 'L2': t1 = OnscreenText(parent = self.level_passed_frame,text = 'STAGE 2 COMPLETE', pos = (0, 0), scale = .1, fg=(1,0,0,1)) t2 = OnscreenText(parent = self.level_passed_frame,text = 'Wheels Collected : ' + str(self.__game.eve.tiresCollected) + ' / ' + str(self.__game.e.total_tokens) , pos = (0, -.2), scale = .1, fg=(1,0,0,1)) t3 = OnscreenText(parent = self.level_passed_frame,text = 'Score : ' + str(self.__game.user.score) , pos = (0, -.3), scale = .1, fg=(1,0,0,1)) OnscreenText(parent = self.level_passed_frame,text = 'CONTINUE?', pos = (0, -.5), scale = .07, fg=(1,0,0,1)) if self.__game.current_level == 'L1': self.link(self.level_passed_frame,'YES',LVecBase3f(.3,0,-.6),self.__game.clean_and_set,'L2') else: self.link(self.level_passed_frame,'YES',LVecBase3f(.3,0,-.6),self.__game.clean_and_set,'L1') self.link2(self.level_passed_frame,'NO',LVecBase3f(-.3,0,-.6),sys.exit) ''' After user inputs his/her name in the beginning of the game, this method is execute and a new user is instantiated and the game is setup. Aside from this two things are added to the task manager...the timer and the stage title. ''' def set_player(self,entry): print '\tWELCOME ' + entry + ' ...' print '\tSETTING UP USER ...' self.input_frame.destroy() # Destroy the input frame self.__game.user = User(entry) # Frame title self.stage_select_frame.show() ''' Method used to toggle between the help menu and the game. ''' def toggleHelp(self): if self.help_frame.isHidden(): # Stop update task and disable character controls when help is activated self.pause.play() self.__game.taskMgr.remove('update') self.hide_game_interface() self.__game.eve.disable_character_controls() self.help_frame.show() else: # Restart update task and enable character controls when help is deactivated self.pause.play() self.__game.taskMgr.add(self.__game.update,'update') # Add task to task manager self.show_game_interface() self.__game.eve.enable_character_controls() self.help_frame.hide() ''' Method does nothing but is important to stop the h key from working when help menu is in a sub menu or frame ''' def do_nothing(self): pass
class DeveloperConsole(InteractiveInterpreter, DirectObject): """The name says it all.""" def __init__(self): sys.stdout = PseudoFile(self.writeOut) sys.stderr = PseudoFile(self.writeErr) tpErr = TextProperties() tpErr.setTextColor(1, 0.5, 0.5, 1) TextPropertiesManager.getGlobalPtr().setProperties("err", tpErr) #font = loader.loadFont("cmss12") self.frame = DirectFrame(parent = base.a2dTopCenter, text_align = TextNode.ALeft, text_pos = (-base.getAspectRatio() + TEXT_MARGIN[0], TEXT_MARGIN[1]), text_scale = 0.05, text_fg = (1, 1, 1, 1), frameSize = (-2.0, 2.0, -0.5, 0.0), frameColor = (0, 0, 0, 0.5), text = '')#, text_font = font) self.entry = DirectEntry(parent = base.a2dTopLeft, command = self.command, scale = 0.05, width = 1000.0, pos = (-0.02, 0, -0.48), relief = None, text_pos = (1.5, 0, 0), text_fg = (1, 1, 0.5, 1), rolloverSound = None, clickSound = None)#, text_font = font) self.otext = OnscreenText(parent = self.entry, scale = 1, align = TextNode.ALeft, pos = (1, 0, 0), fg = (1, 1, 0.5, 1), text = ':')#, font = font) self.lines = [''] * 9 self.commands = [] # All previously sent commands self.cscroll = None # Index of currently navigated command, None if current self.command = '' # Currently entered command self.block = '' # Temporarily stores a block of commands self.hide() self.initialized = False def prevCommand(self): if self.hidden: return if len(self.commands) == 0: return if self.cscroll == None: self.cscroll = len(self.commands) self.command = self.entry.get() elif self.cscroll <= 0: return else: self.commands[self.cscroll] = self.entry.get() self.cscroll -= 1 self.entry.set(self.commands[self.cscroll]) self.entry.setCursorPosition(len(self.commands[self.cscroll])) def nextCommand(self): if self.hidden: return if len(self.commands) == 0: return if self.cscroll == None: return self.commands[self.cscroll] = self.entry.get() self.cscroll += 1 if self.cscroll >= len(self.commands): self.cscroll = None self.entry.set(self.command) self.entry.setCursorPosition(len(self.command)) else: self.entry.set(self.commands[self.cscroll]) self.entry.setCursorPosition(len(self.commands[self.cscroll])) def writeOut(self, line, copy = True): if copy: sys.__stdout__.write(line) lines = line.split('\n') firstline = lines.pop(0) self.lines[-1] += firstline self.lines += lines self.frame['text'] = '\n'.join(self.lines[-9:]) def writeErr(self, line, copy = True): if copy: sys.__stderr__.write(line) line = '\1err\1%s\2' % line lines = line.split('\n') firstline = lines.pop(0) self.lines[-1] += firstline self.lines += lines self.frame['text'] = '\n'.join(self.lines[-9:]) def command(self, text): if not self.hidden: self.cscroll = None self.command = '' self.entry.set('') self.entry['focus'] = True self.writeOut(self.otext['text'] + ' ' + text + '\n', False) if text != '' and (len(self.commands) == 0 or self.commands[-1] != text): self.commands.append(text) # Insert plugins into the local namespace locals = __main__.__dict__ #locals['manager'] = self.manager #for plugin in self.manager.named.keys(): # locals[plugin] = self.manager.named[plugin] locals['panda3d'] = panda3d # Run it and print the output. if not self.initialized: InteractiveInterpreter.__init__(self, locals = locals) self.initialized = True try: if self.runsource(self.block + '\n' + text) and text != '': self.otext['text'] = '.' self.block += '\n' + text else: self.otext['text'] = ':' self.block = '' except Exception: # Not just "except", it will also catch SystemExit # Whoops! Print out a traceback. self.writeErr(traceback.format_exc()) def toggle(self): if self.hidden: self.show() else: self.hide() def show(self): self.accept('arrow_up', self.prevCommand) self.accept('arrow_up-repeat', self.prevCommand) self.accept('arrow_down', self.nextCommand) self.accept('arrow_down-repeat', self.nextCommand) self.hidden = False self.entry['focus'] = True self.frame.show() self.entry.show() self.otext.show() def hide(self): self.ignoreAll() self.hidden = True self.entry['focus'] = False self.frame.hide() self.entry.hide() self.otext.hide() def destroy(self): sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ self.ignoreAll() self.frame.destroy() self.entry.destroy() self.otext.destroy()
class SocketServer(): def __init__(self, port, virtual_world, camera_mgr, sync_session): self.port = port self.virtual_world = virtual_world self.cam_mgr = camera_mgr self.task_mgr = virtual_world.taskMgr self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cReader.setRawMode(True) self.cWriter = ConnectionWriter(self.cManager, 1) self.cWriter.setRawMode(True) self.tcpSocket = self.cManager.openTCPServerRendezvous(port, BACKLOG) self.cListener.addConnection(self.tcpSocket) self.activeSessions = {} self.connection_map = {} self.set_handlers() hostname = socket.gethostname() a, b, address_list = socket.gethostbyname_ex(hostname) self.ip = address_list[0] logging.info("Addresses %s" % address_list) logging.info("Server is running on ip: %s, port: %s" %(self.ip, self.port)) self.client_counter = 0 self.read_buffer = '' self.read_state = 0 self.read_body_length = 0 self.packet = SocketPacket() controller = virtual_world.getController() self.sync = Sync(self.task_mgr, controller, camera_mgr, sync_session) self.vv_id = None if sync_session: logging.info("Waiting for Sync Client!") self.showing_info = False virtual_world.accept("i", self.toggleInfo) self.sync_session = sync_session self.createInfoLabel() atexit.register(self.exit) def createInfoLabel(self): string = self.generateInfoString() self.info_label = OST(string, pos=(-1.3, -0.5), fg=(1,1,1,1), bg=(0,0,0,0.7), scale=0.05, align=TextNode.ALeft) self.info_label.hide() def generateInfoString(self,): string = " IP:\t%s \n" % self.ip string += " PORT:\t%s \n" % self.port if self.sync_session: string += " MODE:\tSync Client\n" string += " VV ID:\t%s\n" % self.vv_id else: string += " MODE:\tAutomatic\n" cameras = self.cam_mgr.getCameras() num_cameras = len(cameras) for camera in cameras: id = camera.getId() type = camera.getTypeString() string += " Cam%s:\t%s\n" %(id, type) string += "\n" return string def set_handlers(self): self.task_mgr.add(self.connection_polling, "Poll new connections", -39) self.task_mgr.add(self.reader_polling, "Poll reader", -40) self.task_mgr.add(self.disconnection_polling, "PollDisconnections", -41) def connection_polling(self, taskdata): if self.cListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConn = PointerToConnection() if self.cListener.getNewConnection(rendezvous,netAddress, newConn): conn = newConn.p() self.cReader.addConnection(conn) # Begin reading connection conn_id = self.client_counter logging.info("New Connection from ip:%s, conn:%s" % (conn.getAddress(), conn_id)) self.connection_map[conn_id] = conn self.client_counter += 1 message = eVV_ACK_OK(self.ip, self.port, conn_id) self.sendMessage(message, conn) return Task.cont def reader_polling(self, taskdata): if self.cReader.dataAvailable(): datagram = NetDatagram() # catch the incoming data in this instance # Check the return value; if we were threaded, someone else could have # snagged this data before we did if self.cReader.getData(datagram): self.read_buffer = self.read_buffer + datagram.getMessage() while (True): if self.read_state == 0: if len(self.read_buffer) >= self.packet.header_length: bytes_consumed = self.packet.header_length self.packet.header = self.read_buffer[:bytes_consumed] self.read_body_length = self.packet.decode_header() self.read_buffer = self.read_buffer[bytes_consumed:] self.read_state = 1 else: break if self.read_state == 1: if len(self.read_buffer) >= self.read_body_length: bytes_consumed = self.read_body_length self.packet.data = self.read_buffer[:bytes_consumed] self.packet.offset = 0 self.read_body_length = 0 self.read_buffer = self.read_buffer[bytes_consumed:] self.read_state = 0 self.new_data_callback(self.packet) else: break return Task.cont def new_data_callback(self, packet): packet = copy.deepcopy(packet) message_type = packet.get_int() conn_id = packet.get_int() if message_type == VP_SESSION: conn = self.connection_map[conn_id] type = packet.get_char() pipeline = packet.get_char() req_cam_id = packet.get_int() logging.debug("Received VP_SESSION message from conn:%s, " \ "type=%s, pipeline=%s requested camera id=%d" %(conn_id, VP_TYPE[type], PIPELINE[pipeline], req_cam_id)) self.newVPSession(conn, type, pipeline, conn_id, req_cam_id) elif message_type == SYNC_SESSION: vv_id = packet.get_int() self.vv_id = vv_id string = self.generateInfoString() self.info_label.setText(string) conn = self.connection_map[conn_id] logging.debug("Received SYNC_SESSION message from conn:%s" %conn_id) self.newSyncSession(conn, conn_id, vv_id) logging.info("Sync client connected") elif message_type == VP_REQ_CAM_LIST: logging.debug("Received VP_REQ_CAM_LIST message from conn:%s" % conn_id) cameras = self.cam_mgr.getCameras() pipeline = self.activeSessions[conn_id].getPipeline() camera_type = None if pipeline == STATIC_PIPELINE: camera_type = VP_STATIC_CAMERA elif pipeline == PTZ_PIPELINE: camera_type = VP_ACTIVE_CAMERA cam_list = [] for camera in cameras: if camera_type == camera.getType() and not camera.hasSession(): cam_list.append(camera.getId()) message = eVV_CAM_LIST(self.ip, self.port, cam_list) conn = self.connection_map[conn_id] logging.debug("Sent VV_CAM_LIST message to conn:%s" % conn_id) self.sendMessage(message, conn) elif message_type == VP_REQ_IMG: cam_id = packet.get_int() frequency = packet.get_char() width = packet.get_int() height = packet.get_int() jpeg = packet.get_bool() data = (frequency, width, height, jpeg) camera = self.cam_mgr.getCameraById(cam_id) logging.debug("Received VV_REQ_IMG message from conn:%s" % conn_id) if camera and not camera.hasSession(): session = self.activeSessions[conn_id] session.addCamera(cam_id) camera.setSession(session, VP_BASIC, self.ip, self.port, data) else: if conn_id in self.activeSessions: self.activeSessions[conn_id].newMessage(message_type, packet) def newVPSession(self, conn, type, pipeline, conn_id, req_cam_id): if type == VP_ADVANCED: camera_type = -1 if pipeline == STATIC_PIPELINE: camera_type = STATIC_CAMERA ## Change this to use a different static camera class elif pipeline == PTZ_PIPELINE: camera_type = ACTIVE_CAMERA if camera_type != -1: #cam = self.cam_mgr.getAvailableCamera(camera_type) cam = self.cam_mgr.getRequestedCamera(camera_type, req_cam_id) if cam: session = VPSession(conn_id, conn, self, VP, pipeline) session.addCamera(cam.getId()) self.activeSessions[conn_id] = session message = eVV_VP_ACK_OK(self.ip, self.port, cam.getId()) logging.debug("Sent VV_VP_ACK_OK message to conn:%s" % conn_id) self.sendMessage(message, conn) cam.setSession(session, type, self.ip, self.port) else: message = eVV_VP_ACK_FAILED(self.ip, self.port) logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" % conn_id) self.sendMessage(message, conn) else: message = eVV_VP_ACK_FAILED(self.ip, self.port) logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" % conn_id) self.sendMessage(message, conn) def newSyncSession(self, conn, conn_id, vv_id): session = SyncSession(conn_id, conn, self, SYNC) self.sync.setSession(session, vv_id, self.ip, self.port) self.activeSessions[conn_id] = session message = eVV_SYNC_ACK(self.ip, self.port, vv_id) logging.debug("Sent VV_SYNC_ACK message to conn:%s" % conn_id) self.sendMessage(message, conn) def sendMessage(self, message, conn): self.cWriter.send(message, conn) def disconnection_polling(self, taskdata): if(self.cManager.resetConnectionAvailable()): connectionPointer = PointerToConnection() self.cManager.getResetConnection(connectionPointer) lostConnection = connectionPointer.p() for session in self.activeSessions.values(): if session.conn == lostConnection: logging.info("Lost Connection from ip:%s, conn:%s" %(session.client_address, session.conn_id)) conn_id = session.conn_id if session.getSessionType() == VP: cameras = session.getCameras() for cam_id in cameras: camera = self.cam_mgr.getCameraById(cam_id) camera.clearSession() del self.activeSessions[conn_id] del self.connection_map[conn_id] break self.cManager.closeConnection(lostConnection) return Task.cont def toggleInfo(self): if self.showing_info: self.info_label.hide() self.showing_info = False else: self.info_label.show() self.showing_info = True def exit(self): for connection in self.connection_map.values(): self.cReader.removeConnection(connection) self.cManager.closeConnection(self.tcpSocket) self.tcpSocket.getSocket().Close()
def __init__(self): ShowBase.__init__(self) wp = core.WindowProperties() wp.setTitle("Dorfdelf") self.win.requestProperties(wp) self.render.setAntialias(core.AntialiasAttrib.MAuto) self.setBackgroundColor(0.5, 0.5, 0.5) self.disableMouse() self.enableParticles() font = self.loader.loadFont('media/Carlito-Regular.ttf') font.setPixelsPerUnit(120) font.setPageSize(512, 1024) loading = OnscreenText(text='Loading...', scale=0.2, pos=(0.0, 0.0), fg=(1, 1, 1, 1), shadow=(0.3, 0.3, 0.3, 1.0), align=core.TextNode.ACenter, mayChange=True, font=font, parent=self.aspect2d) self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() loading.setText('Generating world') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world = world.World(128, 128, 100) self.world.generate() loading.setText('Creating world geometry') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world_geometry = geometry.WorldGeometry(self.world) self.camLens.setFocalLength(1) self.camera.setPos(0, 0, 100) self.camera.lookAt(self.world.midpoint.x, self.world.midpoint.y, 100) self.cam.setPos(0, 0, 0) self.cam.setHpr(0, -45, 0) self.cc = camera.CameraController(self.world.size, self.mouseWatcherNode, self.camera, self.cam) self.gui = gui.GUI(self.pixel2d, font) self.world_geometry.node.setPos(0, 0, 0) self.world_geometry.node.reparentTo(self.render) self.explore_mode = True self.current_slice = int(self.world.midpoint.z) self.accept_keyboard() self.accept('mouse1', self.toggle_block) self.accept('console-command', self.console_command) self.designation = designation.Designation() self.dorfs = [] self.tool = lambda w, x, y, z: None self.toolargs = () self.tools = { 'bomb': tools.bomb, 'block': tools.block, 'd': self.designation.add } self.console = console.Console(self) self.picker = block_picker.BlockPicker(self.world, self) self.zmap = zmap.ZMap(self.world, self) self.change_slice(0) arrow = LineNodePath() arrow.reparentTo(self.render) arrow.drawArrow2d(Vec3(-5, -5, self.world.midpoint.z), Vec3(15, -5, self.world.midpoint.z), 30, 3) arrow.create() loading.hide()
class StageScreen(DirectObject.DirectObject): def __init__(self, callback = None): self.stageRoot = NodePath("stageSelectRoot") self.ps = PreviewStrip("../assets/stages" ,-0.7) self.ps.getStripNP().reparentTo(self.stageRoot) self.callback = callback # name of the stage will be displayed here self.text = OnscreenText("") self.text.reparentTo(self.stageRoot) self.text.setPos(0,self.ps.height - 0.4) self.preview_size = [-0.5, 0.5, -0.5, 0.5] self.generator = CardMaker("PreviewMaker") self.generator.setFrame(*self.preview_size) self.preview = self.stageRoot.attachNewNode(self.generator.generate()) self.preview.setPos(0,0, 0.4) # keys are read so that the first in the pair is from player 1 # and second from the player 2, so that they both can decide self.keys = readKeys() self.left = [self.keys[0][1], self.keys[1][2]] self.right = [self.keys[0][3], self.keys[1][3]] self.select = [self.keys[0][4], self.keys[1][4]] self.ready = OnscreenText("ready") self.ready.reparentTo(self.stageRoot) self.ready.setPos(0,self.ps.height) # will be shown when players selected the stage self.ready.hide() # we notify ourselves to enable the key input and update text # and preview self.updateText() self.updateImg() self.disableInput() def enableInput(self): self.accept( self.left[0], self.rotateLeft ) self.accept( self.left[1], self.rotateLeft ) self.accept( self.right[0], self.rotateRight ) self.accept( self.right[1], self.rotateRight ) self.accept( self.select[0], self.callback) self.accept( self.select[1], self.callback) def disableInput(self): for key in self.left + self.right + self.select: self.ignore(key) def getNp(self): return self.stageRoot def updateText(self): t = str(self.ps.current().getTexture().getFilename()) self.text["text"] = t.split(sep)[-2] def updateImg(self): self.preview.setTexture(self.ps.current().getTexture()) def rotateRight(self): self.ps.rotateRight() self.updateText() self.updateImg() def rotateLeft(self): self.ps.rotateLeft() self.updateText() self.updateImg() def hide(self): self.stageRoot.hide() def show(self): self.stageRoot.show() def getStage(self): # return path to stage acceptable by Match class t = str(self.ps.current().getTexture().getFilename()).rstrip("icon.jpg") return t + "stage"
class Game: HUD_TEXT_SCALE = 0.1 UPDATE_RATE = 1/60.0 def __init__(self): self.LoadHUD() self.loadPhysics() self.loadLights() #self.wall = Wall(self) #self.wall.setPos( Vec3( 5, 0, 0) ) self.ship1 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.2, 0)) self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0)) self.ship2.setPos( Vec3(10, 10, 0) ) self.setKeys() self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo2.setPos( Vec3(30, 20, 0) ) base.setBackgroundColor(0,0,0.0,0) taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.25, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText.hide() def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.5, 0.9, 0.9, 0) ) render.setLight(lightNode1) def loop(self, task): self.ship1.applyForces() self.ship2.applyForces() self.physicsSpace.autoCollide() self.pallo.hitShips(self.ship1, self.ship2) self.pallo2.hitShips(self.ship1, self.ship2) # self.wall.osuminen(self.ship1) self.physicsWorld.quickStep(Game.UPDATE_RATE) self.ship1.update(Game.UPDATE_RATE) self.ship2.update(Game.UPDATE_RATE) self.pallo.update(Game.UPDATE_RATE) self.pallo2.update(Game.UPDATE_RATE) self.contactGroup.empty() return task.cont
class Game(DirectObject): def __init__(self, backend): self.backend = backend self.matchInProgress = False self.unitSelector = None self.gameui = None visitorFont = loader.loadFont("menu/visitor2.ttf") self.promptText = OnscreenText(pos=(0, 0.85), scale=0.1, fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=visitorFont, mayChange=True) self.scoreText = OnscreenText(pos=(0, 0.92), scale=0.06, fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), font=visitorFont, mayChange=True) self.errorSound = audio.FlatSound("sounds/error.ogg") self.playerLastActive = -1 # -1 means the player is currently active self.localTeam = None self.localTeamID = 0 self.unitSelector = ui.UnitSelectorScreen(self.startMatch) if isinstance(self.backend, SurvivalBackend): self.unitSelector.disableUnits() if isinstance(self.backend, ClientBackend): self.accept("client-setup", self.gameInfoCallback) self.unitSelector.hide() self.promptText.setText("Connecting...") self.scoreText.hide() self.gameui = ui.GameUI() self.gameui.hide() self.accept("space", self.handleSpacebar) self.backend.setGame(self) self.spawnedOnce = False self.spectatorController = controllers.SpectatorController() self.buyScreenDisplayed = False self.accept("p", engine.togglePause) def startMatch(self): # Must buy at least one weapon # Can't buy two of the same weapon if self.unitSelector.getPrimaryWeapon( ) is None or self.unitSelector.getPrimaryWeapon( ) == self.unitSelector.getSecondaryWeapon(): self.errorSound.play() return if not self.matchInProgress: self.backend.map.hidePlatforms() self.spawnedOnce = False self.matchInProgress = True self.gameui.show() self.unitSelector.hide() self.promptText.hide() self.scoreText.hide() weaponSelections = self.unitSelector.getUnitWeapons() specialSelections = self.unitSelector.getUnitSpecials() self.localTeam.clearUnits() for i in range(len(weaponSelections)): self.localTeam.purchaseUnit(weaponSelections[i], specialSelections[i]) self.localTeam.setPrimaryWeapon(self.unitSelector.getPrimaryWeapon()) self.localTeam.setSecondaryWeapon( self.unitSelector.getSecondaryWeapon()) self.localTeam.setSpecial(self.unitSelector.getSpecial()) def gameInfoCallback(self, iterator): engine.log.info("Processing game setup information...") info = GameInfo() # Find out which team we are on this computer info.teamId = net.Uint8.getFrom(iterator) info.mapFile = net.String.getFrom(iterator) # Map filename info.scoreLimit = net.Uint16.getFrom(iterator) # Score limit # Whether we should respawn our local player info.enableRespawn = net.Boolean.getFrom(iterator) info.type = net.Uint8.getFrom(iterator) # Game type self.localTeamID = info.teamId self.backend.loadMap(info.mapFile) self.backend.scoreLimit = info.scoreLimit self.backend.enableRespawn = info.enableRespawn self.backend.type = info.type if self.backend.type == constants.SURVIVAL: self.unitSelector.disableUnits() self.unitSelector.show() net.context.clientConnected = True def localStart(self, map): self.backend.loadMap(map) def setLocalTeamID(self, id): self.localTeamID = id self.unitSelector.reset() def reset(self): self.unitSelector.reset() self.unitSelector.show() self.matchReset() def matchReset(self): self.promptText.setText("") self.promptText.show() self.scoreText.show() if len(self.backend.map.platforms) > 0: pos = self.backend.map.platforms[0].getPosition() base.camera.setPos(pos - Vec3(3, 22, 0)) base.camera.lookAt(pos) else: base.camera.setPos(Vec3(3, 22, 15)) base.camera.lookAt(Point3(0, 0, 12)) self.gameui.hide() self.matchInProgress = False self.localTeam = None self.spawnedOnce = False self.buyScreenDisplayed = False def handleSpacebar(self): if not self.matchInProgress and self.localTeam is not None: if self.unitSelector.hidden: # Delete the player on the platform and show the buy screen player = self.localTeam.getPlayer() if player is not None and player.active: player.delete(self.backend.entityGroup) self.localTeam.setPlayer(None) self.showBuyScreen() def showBuyScreen(self): self.unitSelector.clearPurchases() if self.backend.gameOver: self.promptText.setText("Next game in 10 seconds...") else: self.promptText.hide() self.unitSelector.show() self.gameui.hide() def endMatchCallback(self, winningTeam): self.endMatch(winningTeam) # For object-oriented inheritance nonsense def endMatch(self, winningTeam): self.backend.map.showPlatforms() self.localTeam.platformSpawnPlayer(self.backend.map.platforms[ self.localTeam.lastMatchPosition].getPosition() + Vec3(0, 0, 2)) self.gameui.showUsernames() self.matchReset() self.updateScoreText() self.promptText.show() gameOverText = "" gameText = "match" if self.backend.gameOver: gameOverText = "Game over! " gameText = "game" # Find the team that won the most matches if isinstance(self.backend, PointControlBackend): winningTeam = None highScore = 0 for team in self.backend.entityGroup.teams: if team.matchScore > highScore: highScore = team.matchScore winningTeam = team self.promptText.setText(gameOverText + winningTeam.username + " wins the " + gameText + "! Spacebar to continue.") def updateScoreText(self): text = "" for team in self.backend.entityGroup.teams: text += " " + team.username + ": " + str(team.matchScore) + " " self.scoreText.setText(text) self.scoreText.show() def update(self): if engine.paused: self.spectatorController.serverUpdate(self.backend.aiWorld, self.backend.entityGroup, None) else: if self.localTeam is None: team = self.backend.entityGroup.getEntity(self.localTeamID) if team is not None: team.setLocal(True) self.localTeam = team self.localTeam.setUsername(self.backend.username) self.unitSelector.setTeam(team) self.gameui.setTeams(self.backend.entityGroup.teams, team) self.updateScoreText() else: self.localTeam.respawnUnits() player = self.localTeam.getPlayer() if player is None or not player.active: if self.playerLastActive == -1: self.playerLastActive = engine.clock.time if engine.clock.time - self.playerLastActive > 1.0: if not self.buyScreenDisplayed: self.showBuyScreen() self.buyScreenDisplayed = True elif self.unitSelector.hidden: self.spectatorController.serverUpdate( self.backend.aiWorld, self.backend.entityGroup, None) if self.unitSelector.hidden and self.matchInProgress and ( self.backend.enableRespawn or not self.spawnedOnce): self.spawnedOnce = True self.localTeam.respawnPlayer() else: self.playerLastActive = -1 self.buyScreenDisplayed = False if self.gameui is not None: self.gameui.update(self.backend.scoreLimit) self.unitSelector.update() def delete(self): if engine.paused: engine.togglePause() engine.log.info("Deleting game.") if self.unitSelector is not None: self.unitSelector.delete() if self.gameui is not None: self.gameui.delete() if not self.promptText.isEmpty(): self.promptText.destroy() if not self.scoreText.isEmpty(): self.scoreText.destroy() self.ignoreAll()
class App(ShowBase): def __init__(self): ShowBase.__init__(self) # Print all events sent through the messenger #self.messenger.toggleVerbose() # Load the graphics for the gamepad buttons and register them, so that # we can embed them in our information text. graphics = loader.loadModel("models/xbone-icons.egg") mgr = TextPropertiesManager.getGlobalPtr() for name in ["face_a", "face_b", "face_x", "face_y", "ltrigger", "rtrigger", "lstick", "rstick"]: graphic = graphics.find("**/" + name) graphic.setScale(1.5) mgr.setGraphic(name, graphic) graphic.setZ(-0.5) # Show the informational text in the corner. self.lblInfo = OnscreenText( parent = self.a2dBottomLeft, pos = (0.1, 0.3), fg = (1, 1, 1, 1), bg = (0.2, 0.2, 0.2, 0.9), align = TextNode.A_left, text = INFO_TEXT) self.lblInfo.textNode.setCardAsMargin(0.5, 0.5, 0.5, 0.2) self.lblWarning = OnscreenText( text = "No devices found", fg=(1,0,0,1), scale = .25) self.lblAction = OnscreenText( text = "Action", fg=(1,1,1,1), scale = .15) self.lblAction.hide() # Is there a gamepad connected? self.gamepad = None devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad) if devices: self.connect(devices[0]) # Accept device dis-/connection events self.accept("connect-device", self.connect) self.accept("disconnect-device", self.disconnect) self.accept("escape", exit) # Accept button events of the first connected gamepad self.accept("gamepad-back", exit) self.accept("gamepad-start", exit) self.accept("gamepad-face_x", self.reset) self.accept("gamepad-face_a", self.action, extraArgs=["face_a"]) self.accept("gamepad-face_a-up", self.actionUp) self.accept("gamepad-face_b", self.action, extraArgs=["face_b"]) self.accept("gamepad-face_b-up", self.actionUp) self.accept("gamepad-face_y", self.action, extraArgs=["face_y"]) self.accept("gamepad-face_y-up", self.actionUp) self.environment = loader.loadModel("environment") self.environment.reparentTo(render) # Disable the default mouse-camera controls since we need to handle # our own camera controls. self.disableMouse() self.reset() self.taskMgr.add(self.moveTask, "movement update task") def connect(self, device): """Event handler that is called when a device is discovered.""" # We're only interested if this is a gamepad and we don't have a # gamepad yet. if device.device_class == InputDevice.DeviceClass.gamepad and not self.gamepad: print("Found %s" % (device)) self.gamepad = device # Enable this device to ShowBase so that we can receive events. # We set up the events with a prefix of "gamepad-". self.attachInputDevice(device, prefix="gamepad") # Hide the warning that we have no devices. self.lblWarning.hide() def disconnect(self, device): """Event handler that is called when a device is removed.""" if self.gamepad != device: # We don't care since it's not our gamepad. return # Tell ShowBase that the device is no longer needed. print("Disconnected %s" % (device)) self.detachInputDevice(device) self.gamepad = None # Do we have any other gamepads? Attach the first other gamepad. devices = self.devices.getDevices(InputDevice.DeviceClass.gamepad) if devices: self.connect(devices[0]) else: # No devices. Show the warning. self.lblWarning.show() def reset(self): """Reset the camera to the initial position.""" self.camera.setPosHpr(0, -200, 10, 0, 0, 0) def action(self, button): # Just show which button has been pressed. self.lblAction.text = "Pressed \5%s\5" % button self.lblAction.show() def actionUp(self): # Hide the label showing which button is pressed. self.lblAction.hide() def moveTask(self, task): dt = globalClock.getDt() if not self.gamepad: return task.cont strafe_speed = 85 vert_speed = 50 turn_speed = 100 # If the left stick is pressed, we will go faster. lstick = self.gamepad.findButton("lstick") if lstick.pressed: strafe_speed *= 2.0 # we will use the first found gamepad # Move the camera left/right strafe = Vec3(0) left_x = self.gamepad.findAxis(InputDevice.Axis.left_x) left_y = self.gamepad.findAxis(InputDevice.Axis.left_y) strafe.x = left_x.value strafe.y = left_y.value # Apply some deadzone, since the sticks don't center exactly at 0 if strafe.lengthSquared() >= 0.01: self.camera.setPos(self.camera, strafe * strafe_speed * dt) # Use the triggers for the vertical position. trigger_l = self.gamepad.findAxis(InputDevice.Axis.left_trigger) trigger_r = self.gamepad.findAxis(InputDevice.Axis.right_trigger) lift = trigger_r.value - trigger_l.value self.camera.setZ(self.camera.getZ() + (lift * vert_speed * dt)) # Move the camera forward/backward right_x = self.gamepad.findAxis(InputDevice.Axis.right_x) right_y = self.gamepad.findAxis(InputDevice.Axis.right_y) # Again, some deadzone if abs(right_x.value) >= 0.1 or abs(right_y.value) >= 0.1: self.camera.setH(self.camera, turn_speed * dt * -right_x.value) self.camera.setP(self.camera, turn_speed * dt * right_y.value) # Reset the roll so that the camera remains upright. self.camera.setR(0) return task.cont
class Game: STATE_INITIALIZING = "Initializing" STATE_RUNNING = "Running" SHIPS_MAX_X_DISTANCE = 330.0 SHIPS_MAX_Y_DISTANCE = 250.0 NAME_SHIP_ONE = "Ship 1" NAME_SHIP_TWO = "Ship 2" NAME_PLAYER_ONE = "Player 1" NAME_PLAYER_TWO = "Player 2" START_POS_SHIP_ONE = (100, 100) START_POS_SHIP_TWO = (-100, -100) START_HEADING_SHIP_ONE = -135.0 START_HEADING_SHIP_TWO = 45.0 PLAYER_ONE_FORWARD_KEY = "arrow_up" PLAYER_ONE_ROTATE_LEFT_KEY = "arrow_left" PLAYER_ONE_ROTATE_RIGHT_KEY = "arrow_right" PLAYER_ONE_SHOOT = "rcontrol" PLAYER_TWO_FORWARD_KEY = "w" PLAYER_TWO_ROTATE_LEFT_KEY = "a" PLAYER_TWO_ROTATE_RIGHT_KEY = "d" PLAYER_TWO_SHOOT = "lcontrol" HUD_TEXT_SCALE = 0.05 HUD_PLAYER_ONE_X = -1.25 HUD_PLAYER_TWO_X = 1.05 HUD_Y_FIRST_LINE = 0.85 HUD_Y_SECOND_LINE = 0.75 HUD_Y_THIRD_LINE = 0.65 CAMERA_POS_DEFAULT = (0.0, 0.0, 250.0) CAMERA_HPR_DEFAULT = (0.0, -90.0, 0.0) CAMERA_DISTANCE_COEFFICIENT = 3.0 CAMERA_DISTANCE_MAX = 450.0 CAMERA_DISTANCE_MIN = 150.0 CAMERA_MODE_GAME = "Game" CAMERA_MODE_FPS_ONE = "Fps 1" CAMERA_MODE_FPS_TWO = "Fps 2" CAMERA_MODE_STILL = "Still" CAMERA_FPS_OFFSET_HEIGHT = 2.0 CAMERA_FPS_OFFSET_BACK = 15.0 WINNER_TEXT = "has won the round" PLANET_POSITION = (0, 0) PLANET_CAMERA_DISTANCE_MAX = 400.0 MATCH_MAX_POINTS = 5 GRAVITY_DISTANCE = 100.0 GRAVITY = 2000.0 def __init__(self): # Disable Panda's base camera mover base.disableMouse() base.setBackgroundColor(0,0,0,0) self.state = Game.STATE_INITIALIZING # contains a list of the ships in game self.ships = None self.players = None self.bullets = None self.stars = None self.planet = None self.time = 0.0 self.isListening = False getModelPath().prependDirectory( Filename('./media/') ) self.physWorld = OdeWorld() self.physWorld.setGravity(0, 0, 0) self.physWorld.initSurfaceTable(1) self.physWorld.setSurfaceEntry( 0, 0, 1.0, # u .35, # elasticity .01, # minimum threshold for physical movement .01, # .00000001, # softening .01, # .01) # dampening self.physSpace = OdeHashSpace() self.winnerText = None self.gameFrames = 0 self.lastWarp = 0 self.cameraMode = Game.CAMERA_MODE_GAME self.lastCameraPos = None self.pause = False def start(self): self.resetCamera() self.loadPlanet() self.loadShips() self.loadPlayers() self.loadStars() self.loadHUD() light = DirectionalLight('light') light.setDirection( Vec3(-1, .1, -.5) ) light.setColor( Vec4(.7, .6, .6, 0) ) light.setSpecularColor( Vec4(.3, .5, .7, 0) ) lightnode = render.attachNewNode(light) render.setLight(lightnode) render.setShaderAuto() render.setShaderInput('light', lightnode) render.setAntialias(AntialiasAttrib.MAuto) # TODO: it might be necessary here to check that the task # does not already exist in the task manager because the # unit tests at the moment call the start method # continuously. taskMgr.add(self.tick, "gameloop") self.time = self.getTime() self.registerListeners() self.state = Game.STATE_RUNNING # Load music self.music = loader.loadSfx('MVi - Ilwrath Are Watching.mp3') self.music.setLoop(True) self.music.setVolume(0.5) self.music.play() def loadHUD(self): self.winnerText = OnscreenText( text= "Insert Winner Text Here", style=1, fg=(1,1,1,1), pos=(-0.25, 0), align=TextNode.ALeft, scale = .07 ) self.winnerText.hide() self.scoreTextPlayerOne = OnscreenText( text= "Player 1:", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scorePlayerOne = OnscreenText( text= "Score: 0", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.healthPlayerOne = OnscreenText( text= "Health: " + str(Ship.HEALTH), style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scoreTextPlayerTwo = OnscreenText( text= "Player 2:", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scorePlayerTwo = OnscreenText( text= "Score: 0", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.healthPlayerTwo = OnscreenText( text= "Health: " + str(Ship.HEALTH), style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) def generateRandomPos( self ): return ( random.random() * Game.SHIPS_MAX_X_DISTANCE - Game.SHIPS_MAX_X_DISTANCE / 2., random.random() * Game.SHIPS_MAX_Y_DISTANCE - Game.SHIPS_MAX_Y_DISTANCE / 2. ) def generateRandomStartPos( self, offlimits = [] ): pos = self.generateRandomPos() while not self.checkIfStartPosValid( pos, offlimits ): pos = self.generateRandomPos() return pos def checkIfStartPosValid( self, pos, offlimits ): for o in offlimits: if tupleDistanceSquared( pos, o[0] ) < o[1]**2: return False return True def getBullets(self): ships = self.getShips() shipOne = ships[0] shipTwo = ships[1] bullets = [shipOne.bullets, shipTwo.bullets] return bullets def resetCamera(self): self.setCameraPos(Game.CAMERA_POS_DEFAULT) self.setCameraHpr(Game.CAMERA_HPR_DEFAULT) pos = Game.CAMERA_POS_DEFAULT self.lastCameraPos = ( pos[0], pos[1] ) def setCameraPos(self, pos): base.camera.setPos( tripleToVec3(pos) ) def getCameraPos(self): return vec3ToTriple( base.camera.getPos() ) def setCameraHpr(self, hpr): base.camera.setHpr( tripleToVec3(hpr) ) def getCameraHpr(self): return vec3ToTriple( base.camera.getHpr() ) def getTime(self): return globalClock.getFrameTime() def getDeltaTime(self): return globalClock.getDt() def run(self): """Call this to run the game. Untested because this method won't return.""" taskMgr.run() def loadShips(self): shipOne = Ship( Game.NAME_SHIP_ONE, Game.START_POS_SHIP_ONE, Game.START_HEADING_SHIP_ONE ) shipTwo = Ship( Game.NAME_SHIP_TWO, Game.START_POS_SHIP_TWO, Game.START_HEADING_SHIP_TWO ) offlimits = [ ( vec3ToTuple( self.planet.getPos() ), Game.GRAVITY_DISTANCE ) ] shipOne.setPos( self.generateRandomStartPos( offlimits ) ) shipOne.heading = random.random()*360 shipTwo.heading = random.random()*360 offlimits.append( ( shipOne.getPos(), 150 ) ) shipTwo.setPos( self.generateRandomStartPos( offlimits ) ) self.ships = [] self.ships.append(shipOne) self.ships.append(shipTwo) def loadPlayers(self): playerOne = Player(Game.NAME_PLAYER_ONE) playerTwo = Player(Game.NAME_PLAYER_TWO) self.players = [] self.players.append(playerOne) self.players.append(playerTwo) def loadStars(self): ambientlight = AmbientLight('alight') ambientlight.setColor( Vec4(1, 1, 1, 0) ) lightnode = render.attachNewNode(ambientlight) self.stars = loader.loadModel("stars.bam") self.stars.setLight(lightnode) self.stars.setScale(1000) self.stars.setPos(0,0,0) self.stars.reparentTo(render) self.starsRotation = self.stars.getQuat() def loadPlanet(self): self.planet = loader.loadModel('planet.bam') self.planet.setPos( tupleToVec3(Game.PLANET_POSITION) ) self.planet.setScale(20) self.planet.reparentTo(render) self.planetCollGeom = OdeSphereGeom(20) #self.planetCollGeom.setCategoryBits( BitMask32(0xffffffff) ) #self.planetCollGeom.setCollideBits( BitMask32(0xffffffff) ) def updateCamera(self): ships = self.getShips() shipOne = ships[0] shipOnePos = shipOne.getPos() shipTwo = ships[1] shipTwoPos = shipTwo.getPos() # Calculate the distance between the ships distance = tupleDistance(shipOnePos, shipTwoPos) cameraDistance = distance * Game.CAMERA_DISTANCE_COEFFICIENT if cameraDistance > Game.CAMERA_DISTANCE_MAX: cameraDistance = Game.CAMERA_DISTANCE_MAX if cameraDistance < Game.CAMERA_DISTANCE_MIN: cameraDistance = Game.CAMERA_DISTANCE_MIN # Calculate the middle point in space between the ship's positions middle = tupleMiddle(shipOnePos, shipTwoPos) cameraPos = self.getCameraPos() self.lastCameraPos = cameraPos newCameraPos = (middle[0], middle[1], cameraDistance) self.setCameraPos(newCameraPos) self.updateStars(newCameraPos) def updateStars(self, newCameraPos): # TODO: Add unit tests! self.stars.setPos(newCameraPos) cameraDeltaPos = tupleSegment( self.lastCameraPos, vec3ToTuple( newCameraPos ) ) xRotation = Quat() xRotation.setFromAxisAngle( cameraDeltaPos[0] * .1, Vec3( 0, 1, 0 ) ) yRotation = Quat() yRotation.setFromAxisAngle( -cameraDeltaPos[1] * .1, Vec3( 1, 0, 0 ) ) newRotation = xRotation.multiply( yRotation ) self.starsRotation *= newRotation self.stars.setQuat( self.starsRotation ) # With Euler angles: #self.stars.setHpr(0, -newCameraPos[1] * 0.1, newCameraPos[0] * 0.1 ) def applyGravity(self, ship, deltaTime): distance = tupleDistance( ship.getPos(), vec3ToTuple( self.planet.getPos() ) ) if distance > Game.GRAVITY_DISTANCE: return gravity = Game.GRAVITY/distance gravityVector = tupleNormalize( tupleSegment( ship.getPos(), vec3ToTuple( self.planet.getPos() ) ) ) gravityVector = scaleTuple( gravityVector, gravity * deltaTime) ship.applyForce( gravityVector ) def tick(self, task): if not self.pause: ships = self.getShips() # Check if the ships' positions need to be warped xDistance = abs(ships[0].getPos()[0] - ships[1].getPos()[0] ) if xDistance >= Game.SHIPS_MAX_X_DISTANCE: #and self.gameFrames - self.lastWarp > 10: self.warpShips('x') #self.lastWarp = self.gameFrames yDistance = abs(ships[0].getPos()[1] - ships[1].getPos()[1] ) if yDistance >= Game.SHIPS_MAX_Y_DISTANCE: self.warpShips('y') # Check if the planet's position needs to be warped planetXDistance = abs( self.getCameraPos()[0] - self.planet.getPos()[0] ) if planetXDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('x') planetYDistance = abs( self.getCameraPos()[1] - self.planet.getPos()[1] ) if planetYDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('y') # Check collisions col = OdeUtil.collide(ships[0].collisionSphere, ships[1].collisionSphere, 1) if not col.isEmpty(): ships[0].addCollision( point3ToTuple( col.getContactPoint(0) ) ) ships[1].addCollision( point3ToTuple( col.getContactPoint(0) ) ) colPlanet1 = OdeUtil.collide(ships[0].collisionSphere, self.planetCollGeom, 1) colPlanet2 = OdeUtil.collide(ships[1].collisionSphere, self.planetCollGeom, 1) if not colPlanet1.isEmpty(): ships[0].addCollision( point3ToTuple( colPlanet1.getContactPoint(0) ) ) ships[0].planetHit() if not colPlanet2.isEmpty(): ships[1].addCollision( point3ToTuple( colPlanet2.getContactPoint(0) ) ) ships[1].planetHit() # Bullet collisions ship one for bullet in ships[0].bullets: colBulletShip1 = OdeUtil.collide( bullet['physical'], ships[1].collisionSphere, 1 ) if not colBulletShip1.isEmpty(): ships[0].destroyBullet(bullet) ships[1].bulletHit() colBulletPlanet = OdeUtil.collide( bullet['physical'], self.planetCollGeom, 1 ) if not colBulletPlanet.isEmpty(): ships[0].destroyBullet(bullet) # Bullet collisions ship two for bullet in ships[1].bullets: colBulletShip2 = OdeUtil.collide( bullet['physical'], ships[0].collisionSphere, 1 ) if not colBulletShip2.isEmpty(): ships[1].destroyBullet(bullet) ships[0].bulletHit() colBulletPlanet = OdeUtil.collide( bullet['physical'], self.planetCollGeom, 1 ) if not colBulletPlanet.isEmpty(): ships[1].destroyBullet(bullet) for ship in ships: self.applyGravity( ship, self.getDeltaTime() ) ship.update( self.getDeltaTime() ) if not ships[0].isAlive: self.showWinnerText(self.players[1]) self.players[1].score += 1 self.restartGame() if not ships[1].isAlive: self.showWinnerText(self.players[0]) self.players[0].score += 1 self.restartGame() if self.cameraMode == Game.CAMERA_MODE_GAME: self.updateCamera() if self.gameFrames >= 125: self.winnerText.hide() self.gameFrames += 1 # Update health points in the HUD # TODO: These should be optimized so that they get updated only when they # change. self.healthPlayerOne.setText( "Health: " + str(self.ships[0].health) ) self.healthPlayerTwo.setText( "Health: " + str(self.ships[1].health) ) return task.cont def distanceToPlanetSquared(self, pos): return tupleDistanceSquared( pos, vec3ToTuple( self.planet.getPos() ) ) def warpShips(self, warpAxis): shipOne = self.ships[0] shipTwo = self.ships[1] shipOnePos = shipOne.getPos() shipTwoPos = shipTwo.getPos() furtherShip = None closerShip = None if shipOnePos == tupleFurthestDistance( vec3ToTuple( self.planet.getPos() ), [shipOnePos, shipTwoPos] ): furtherShip = shipOne closerShip = shipTwo else: closerShip = shipOne furtherShip = shipTwo furtherToCloser = tupleSegment( furtherShip.getPos(), closerShip.getPos() ) if warpAxis == 'x': furtherShip.setPos( ( furtherShip.getPos()[0] + furtherToCloser[0]*2, furtherShip.getPos()[1] ) ) elif warpAxis == 'y': furtherShip.setPos( ( furtherShip.getPos()[0], furtherShip.getPos()[1] + furtherToCloser[1]*2 ) ) def warpPlanet(self, warpAxis): planetPos = vec3ToTuple( self.planet.getPos() ) planetToCamera = tupleSegment( planetPos, self.getCameraPos() ) if warpAxis == 'x': self.planet.setPos( planetPos[0] + planetToCamera[0]*2, planetPos[1], 0 ) self.planetCollGeom.setPosition( planetPos[0] + planetToCamera[0]*2, planetPos[1], 0 ) elif warpAxis == 'y': self.planet.setPos( planetPos[0], planetPos[1] + planetToCamera[1]*2, 0 ) self.planetCollGeom.setPosition( planetPos[0], planetPos[1] + planetToCamera[1]*2, 0 ) def restartGame(self): self.planet.setPos( Vec3() ) self.planetCollGeom.setPosition( Vec3() ) offlimits = [ ( vec3ToTuple( self.planet.getPos() ), 102 ) ] # Reset ship one self.ships[0].setPos( self.generateRandomStartPos( offlimits ) ) self.ships[0].heading = random.random()*360 self.ships[0].setVel( Ship.VEL_DEFAULT ) self.ships[0].isAlive = True self.ships[0].health = Ship.HEALTH self.ships[0].visualNode.show() for bullet in self.ships[0].bullets: bullet['isAlive'] = False offlimits.append( ( self.ships[0].getPos(), 128 ) ) # Reset ship two self.ships[1].setPos( self.generateRandomStartPos( offlimits ) ) self.ships[1].heading = random.random()*360 self.ships[1].setVel( Ship.VEL_DEFAULT ) self.ships[1].isAlive = True self.ships[1].health = Ship.HEALTH self.ships[1].visualNode.show() for bullet in self.ships[1].bullets: bullet['isAlive'] = False for s in self.ships: s.update( 1/60. ) self.gameFrames = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score if playerOneScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[0]) self.players[0].score = 0 self.players[1].score = 0 if playerTwoScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[1]) self.players[0].score = 0 self.players[1].score = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score self.scorePlayerOne.setText( 'Score: ' + str(playerOneScore) ) self.scorePlayerTwo.setText( 'Score: ' + str(playerTwoScore) ) def showWinnerText(self, player): self.winnerText.setText( player.name + " " + Game.WINNER_TEXT ) self.winnerText.show() def showGameWinnerText(self, player): self.winnerText.setText( player.name + " wins the match!" ) self.winnerText.show() def registerListeners(self): playerOne = self.getPlayers()[0] playerTwo = self.getPlayers()[1] shipOne = self.getShips()[0] shipTwo = self.getShips()[1] # Player one events playerOneMoveForwardOn = createNamedEvent( playerOne.name, Event.PLAYER_MOVE_FORWARD_ON ) playerOneMoveForwardOff = createNamedEvent( playerOne.name, Event.PLAYER_MOVE_FORWARD_OFF ) playerOneRotateLeftOn = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_LEFT_ON ) playerOneRotateLeftOff = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_LEFT_OFF ) playerOneRotateRightOn = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_RIGHT_ON ) playerOneRotateRightOff = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_RIGHT_OFF ) playerOneShoot = createNamedEvent( playerOne.name, Event.PLAYER_SHOOT ) base.accept(playerOneMoveForwardOn, shipOne.thrustOn) base.accept(playerOneMoveForwardOff, shipOne.thrustOff) base.accept(playerOneRotateLeftOn, shipOne.rotateLeftOn) base.accept(playerOneRotateLeftOff, shipOne.rotateLeftOff) base.accept(playerOneRotateRightOn, shipOne.rotateRightOn) base.accept(playerOneRotateRightOff, shipOne.rotateRightOff) base.accept(playerOneShoot, shipOne.shoot) # Player two events playerTwoMoveForwardOn = createNamedEvent( playerTwo.name, Event.PLAYER_MOVE_FORWARD_ON ) playerTwoMoveForwardOff = createNamedEvent( playerTwo.name, Event.PLAYER_MOVE_FORWARD_OFF ) playerTwoRotateLeftOn = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_LEFT_ON ) playerTwoRotateLeftOff = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_LEFT_OFF ) playerTwoRotateRightOn = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_RIGHT_ON ) playerTwoRotateRightOff = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_RIGHT_OFF ) playerTwoShoot = createNamedEvent( playerTwo.name, Event.PLAYER_SHOOT ) base.accept(playerTwoMoveForwardOn, shipTwo.thrustOn) base.accept(playerTwoMoveForwardOff, shipTwo.thrustOff) base.accept(playerTwoRotateLeftOn, shipTwo.rotateLeftOn) base.accept(playerTwoRotateLeftOff, shipTwo.rotateLeftOff) base.accept(playerTwoRotateRightOn, shipTwo.rotateRightOn) base.accept(playerTwoRotateRightOff, shipTwo.rotateRightOff) base.accept(playerTwoShoot, shipTwo.shoot) # Player one key mapping base.accept(Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept("control-" + Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept(Game.PLAYER_ONE_FORWARD_KEY + "-up", playerOne.moveForwardOff) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY + "-up", playerOne.rotateLeftOff) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY + "-up", playerOne.rotateRightOff) base.accept(Game.PLAYER_ONE_SHOOT, playerOne.shoot) # Player two key mapping base.accept(Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept("control-" + Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept(Game.PLAYER_TWO_FORWARD_KEY + "-up", playerTwo.moveForwardOff) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY + "-up", playerTwo.rotateLeftOff) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY + "-up", playerTwo.rotateRightOff) base.accept(Game.PLAYER_TWO_SHOOT, playerTwo.shoot) # Game specific key mapping base.accept("escape", sys.exit) base.accept( "f1", self.switchCameraMode, [Game.CAMERA_MODE_FPS_ONE] ) base.accept( "f2", self.switchCameraMode, [Game.CAMERA_MODE_FPS_TWO] ) base.accept( "f3", self.switchCameraMode, [Game.CAMERA_MODE_GAME] ) base.accept( "f4", self.switchCameraMode, [Game.CAMERA_MODE_STILL] ) base.accept( "p", self.togglePause ) # The game is now listening to all the necessary events self.isListening = True def togglePause(self): self.pause = not self.pause def windowExists(self): return base.isMainWindowOpen() def getShips(self): return self.ships def getPlayers(self): return self.players def switchCameraMode(self, cameraMode): self.cameraMode = cameraMode if cameraMode == Game.CAMERA_MODE_FPS_ONE: angle = self.ships[0].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3( headingX, headingY, 0 ) pos = self.ships[0].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK ) hpr = self.ships[0].visualNode.getChildren()[0].getHpr() base.camera.setHpr( hpr[0], hpr[1] + 90, hpr[2] ) base.camera.reparentTo(self.ships[0].visualNode) if cameraMode == Game.CAMERA_MODE_FPS_TWO: angle = self.ships[1].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3( headingX, headingY, 0 ) pos = self.ships[1].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK ) hpr = self.ships[1].visualNode.getChildren()[0].getHpr() base.camera.setHpr( hpr[0], hpr[1] + 90, hpr[2] ) base.camera.reparentTo(self.ships[1].visualNode) if cameraMode == Game.CAMERA_MODE_GAME: base.camera.setHpr(Game.CAMERA_HPR_DEFAULT) base.camera.reparentTo(render) if cameraMode == Game.CAMERA_MODE_STILL: base.camera.reparentTo(render)
class GameStatePlaying(GState): VIDAS = 3 #LEVEL_TIME = 100 LEVEL_TIME = 50 def start(self): self._playing_node = render.attachNewNode("playing-node") self._playing_node2d = aspect2d.attachNewNode("playing2d-node") self.keyMap = {"left":0, "right":0, "up":0, "down":0} base.accept( "escape" , sys.exit) props = WindowProperties() props.setCursorHidden(True) base.disableMouse() props.setMouseMode(WindowProperties.MRelative) base.win.requestProperties(props) base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2) self._modulos = None self._paneles = None self._num_lvl = 1 self._num_lvls = 2 self.loadLevel() self.loadGUI() self.loadBkg() self._last_t = None self._last_t_space = 0 def stop(self): self._playing_node.removeNode() self._playing_node2d.removeNode() def loadLevel(self): self._level_time = self.LEVEL_TIME self.initBullet() self._player = Player(self.world) self.loadMap() self.setAI() def initBullet(self): self.world = BulletWorld() #self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setGravity(Vec3(0, 0, -1.62)) groundShape = BulletPlaneShape(Vec3(0, 0, 1), 0) groundNode = BulletRigidBodyNode('Ground') groundNode.addShape(groundShape) self.world.attachRigidBody(groundNode) def loadBkg(self): self.environ1 = loader.loadModel("../data/models/skydome") self.environ1.reparentTo(self._playing_node) self.environ1.setPos(0,0,0) self.environ1.setScale(1) self.environ2 = loader.loadModel("../data/models/skydome") self.environ2.reparentTo(self._playing_node) self.environ2.setP(180) self.environ2.setH(270) self.environ2.setScale(1) self.dirnlight1 = DirectionalLight("dirn_light1") self.dirnlight1.setColor(Vec4(1.0,1.0,1.0,1.0)) self.dirnlightnode1 = self._playing_node.attachNewNode(self.dirnlight1) self.dirnlightnode1.setHpr(0,317,0) self._playing_node.setLight(self.dirnlightnode1) self.alight = AmbientLight('alight') self.alight.setColor(VBase4(0.05, 0.05, 0.05, 1)) self.alight_node = self._playing_node.attachNewNode(self.alight) self._playing_node.setLight(self.alight_node) self.environ1 = loader.loadModel("../data/models/ground") self.environ1.reparentTo(self._playing_node) self.environ1.setPos(0,0,0) self.environ1.setScale(1) def loadGUI(self): self.vidas_imgs = list() w = 0.24 for i in range(self.VIDAS): image_warning = OnscreenImage(image = '../data/Texture/signal_warning.png', pos=(-1 + i*w, 0, 0.85), parent=self._playing_node2d) image_warning.setScale(0.1) image_warning.setTransparency(TransparencyAttrib.MAlpha) image_warning.hide() image_ok = OnscreenImage(image = '../data/Texture/signal_ok.png', pos=(-1 + i*w, 0, 0.85), parent=self._playing_node2d) image_ok.setScale(0.1) image_ok.setTransparency(TransparencyAttrib.MAlpha) image_ok.show() self.vidas_imgs.append((image_ok, image_warning)) self._level_time_O = OnscreenText(text = '', pos = (0, 0.85), scale = 0.14, fg=(1.0, 1.0, 1.0, 1.0), bg=(0.0, 0.0, 0.0, 1.0), parent=self._playing_node2d) def loadMap(self): if (self._modulos is not None): for m in self._modulos: m.remove() if (self._paneles is not None): for p in self._paneles: p.remove() self._tp = TiledParser("map"+str(self._num_lvl)) self._modulos, self._paneles = self._tp.load_models(self.world, self._playing_node) def setAI(self): taskMgr.add(self.update, 'Update') def update(self, task): if (task.frame > 1): self.world.doPhysics(globalClock.getDt()) self._level_time -= globalClock.getDt() self._level_time_O.setText(str(int(self._level_time))) for panel in self._paneles: contact = self.world.contactTestPair(self._player.getRBNode(), panel.getRBNode()) if contact.getNumContacts() > 0: panel.manipulate() brokens = 0 for panel in self._paneles: if panel.isBroken(): brokens += 1 #print brokens for i, vida_imgs in enumerate(self.vidas_imgs): if i < len(self.vidas_imgs) - brokens: vida_imgs[0].show() vida_imgs[1].hide() else: vida_imgs[0].hide() vida_imgs[1].show() if brokens > self.VIDAS: self.gameOver() return task.done if self._level_time <= 0: self._num_lvl += 1 if self._num_lvl <= self._num_lvls: self.nextLevel() else: self.theEnd() return task.done return task.cont def gameOver(self): taskMgr.remove('player-task') taskMgr.remove('panel-task') taskMgr.remove('panel-sound-task') self._mission_text_O = OnscreenText(text = 'Game Over', pos = (0, 0), scale = 0.5, fg=(1.0, 1.0, 1.0, 1.0), bg=(0.0, 0.0, 0.0, 1.0)) taskMgr.add(self.gameOverTransition, 'game-over-transition') #self.loadLevel() print "Game Over" def gameOverTransition(self, task): base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2) if task.time > 3.0: self._mission_text_O.hide() props = WindowProperties() props.setCursorHidden(False) base.win.requestProperties(props) self._state_context.changeState(gameStateMenu.GameStateMenu(self._state_context)) print "MENU" return task.done return task.cont def nextLevel(self): taskMgr.remove('player-task') taskMgr.remove('panel-task') taskMgr.remove('panel-sound-task') self._mission_text_O = OnscreenText(text = 'Mission\nComplete', pos = (0, 0), scale = 0.5, fg=(1.0, 1.0, 1.0, 1.0), bg=(0.0, 0.0, 0.0, 1.0)) taskMgr.add(self.nextLevelTransition, 'next-Level-transition') print "Mission Complete" def nextLevelTransition(self, task): base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2) if task.time > 3.0: print "Next Level" self._mission_text_O.hide() self.loadLevel() return task.done return task.cont def theEnd(self): taskMgr.remove('player-task') taskMgr.remove('panel-task') taskMgr.remove('panel-sound-task') self._mission_text_O = OnscreenText(text = '. The End .', pos = (0, 0), scale = 0.5, fg=(1.0, 1.0, 1.0, 1.0), bg=(0.0, 0.0, 0.0, 1.0)) taskMgr.add(self.theEndTransition, 'theEnd-transition') #self.loadLevel() print "Mission Complete" def theEndTransition(self, task): base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2) if task.time > 3.0: self._mission_text_O.hide() props = WindowProperties() props.setCursorHidden(False) base.win.requestProperties(props) self._state_context.changeState(gameStateMenu.GameStateMenu(self._state_context)) print "The End" return task.done return task.cont
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory('PartyCogActivityGui') def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = 'PartyCogActivityGui-SpamWarning' def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel('phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar') self._victoryBalanceBar = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarBG') self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin('fixed', 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarOrange') self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin('fixed', 1) self._victoryBalanceBarOrange.setPos(PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceBarPie') self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin('fixed', 2) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale(PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find('**/*tt_t_gui_pty_pieToss_balanceArrow') self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin('fixed', 2) self._victoryBalanceBarArrow.setPos(PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale(1 / PartyGlobals.CogActivityBarPieScale) def _initControlGui(self): self._attackIvalName = 'PartyCogActivityGui-attackKeys' self._moveIvalName = 'PartyCogActivityGui-moveKeys' pieTossControls = loader.loadModel('phase_13/models/parties/tt_m_gui_pty_pieToss_controls') self._attackKeys = pieTossControls.find('**/*control*') self._moveKeys = pieTossControls.find('**/*arrow*') self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar(frameSize=(-h, h, -w, w), relief=DGG.GROOVE, frameColor=(0.9, 0.9, 0.9, 1.0), borderWidth=(0.01, 0.01), barColor=PartyGlobals.CogActivityColors[0], pos=PartyGlobals.CogActivityPowerMeterPos, hpr=(0.0, 0.0, -90.0)) self._piePowerMeter.setBin('fixed', 0) self._piePowerTitle = OnscreenText(text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter) self._piePowerTitle.setBin('fixed', 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText(text='0', pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True) self._scoreTitle = OnscreenText(text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ARight) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText(text=TTLocalizer.PartyCogGuiSpamWarning, scale=0.15, fg=(1.0, 1.0, 0, 1.0), shadow=(0, 0, 0, 0.62), mayChange=False, pos=(0, 0.33)) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score = 0): self._scoreLabel['text'] = str(score) def resetPiePowerMeter(self): self._piePowerMeter['value'] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter['value'] = value def getPiePowerMeterValue(self): return self._piePowerMeter['value'] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._spamWarning, ''), Wait(PartyGlobals.CogActivitySpamWarningShowTime), Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) self._piePowerMeter['barColor'] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, 'trackCogs') def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i, cog, self.team) return task.cont def _updateVictoryBar(self): if not (hasattr(self, '_victoryBalanceBar') and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance / 6.0 self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale + teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale, 1.0, 1.0) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0] + teamDistance * 10 * PartyGlobals.CogActivityBarPieUnitMove) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance > 0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[1]) elif teamDistance < 0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0, 1.0, 1.0, 1.0)) def stopTrackingCogs(self): taskMgr.remove('trackCogs') def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._attackKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._moveKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, '_attackKeys') and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, '_moveKeys') and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class World(DirectObject): def __init__(self): # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball in Maze", style=1, fg=(1, 1, 1, 1), pos=(0.7, -0.95), scale=.07) self.instructions = OnscreenText(text="Press Esc to exit.", pos=(-1.3, .95), fg=(1, 1, 1, 1), align=TextNode.ALeft, scale=.05) base.setBackgroundColor(0, 0, 0) self.central_msg = OnscreenText(text="", pos=(0, 0), fg=(1, 1, 0, 1), scale=.1) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Most times, you want collisions to be tested against invisible geometry # rather than every polygon. This is because testing against every polygon # in the scene is usually too slow. You can have simplified or approximate # geometry for the solids and still get good results. # # Sometimes you'll want to create and position your own collision solids in # code, but it's often easier to have them built automatically. This can be # done by adding special tags into an egg file. Check maze.egg and ball.egg # and look for lines starting with <Collide>. The part is brackets tells # Panda exactly what to do. Polyset means to use the polygons in that group # as solids, while Sphere tells panda to make a collision sphere around them # Keep means to keep the polygons in the group as visable geometry (good # for the ball, not for the triggers), and descend means to make sure that # the settings are applied to any subgroups. # # Once we have the collision tags in the models, we can get to them using # NodePath's find command # Find the collision node named wall_collide self.walls = self.maze.find("**/wall_collide") # Collision objects are sorted using BitMasks. BitMasks are ordinary numbers # with extra methods for working with them as binary bits. Every collision # solid has both a from mask and an into mask. Before Panda tests two # objects, it checks to make sure that the from and into collision masks # have at least one bit in common. That way things that shouldn't interact # won't. Normal model nodes have collision masks as well. By default they # are set to bit 20. If you want to collide against actual visable polygons, # set a from collide mask to include bit 20 # # For this example, we will make everything we want the ball to collide with # include bit 0 self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # CollisionNodes are usually invisible but can be shown. Uncomment the next # line to see the collision walls # self.walls.show() # We will now find the triggers for the holes and set their masks to 0 as # well. We also set their names to make them easier to identify during # collisions self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTrigger") self.loseTriggers.append(trigger) # Uncomment this line to see the triggers # trigger.show() # Ground_collide is a single polygon on the same plane as the ground in the # maze. We will use a ray to collide with it so that we will know exactly # what height to put the ball at every frame. Since this is not something # that we want the ball itself to collide with, it has a different # bitmask. self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # Find the collison sphere for the ball which was created in the egg file # Notice that it has a from collision mask of bit 0, and an into collison # mask of no bits. This means that the ball can only cause collisions, not # be collided into self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) # No we create a ray to start above the ball and cast down. This is to # Determine the height the ball should be at and the angle the floor is # tilting. We could have used the sphere around the ball itself, but it # would not be as reliable self.ballGroundRay = CollisionRay() # Create the ray self.ballGroundRay.setOrigin(0, 0, 10) # Set its origin self.ballGroundRay.setDirection(0, 0, -1) # And its direction # Collision solids go in CollisionNode self.ballGroundCol = CollisionNode( 'groundRay') # Create and name the node self.ballGroundCol.addSolid(self.ballGroundRay) # Add the ray self.ballGroundCol.setFromCollideMask( BitMask32.bit(1)) # Set its bitmasks self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # Attach the node to the ballRoot so that the ray is relative to the ball # (it will always be 10 feet over the ball and point down) self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # Uncomment this line to see the ray # self.ballGroundColNp.show() # Finally, we create a CollisionTraverser. CollisionTraversers are what # do the job of calculating collisions self.cTrav = CollisionTraverser() # Collision traverservs tell collision handlers about collisions, and then # the handler decides what to do with the information. We are using a # CollisionHandlerQueue, which simply creates a list of all of the # collisions in a given pass. There are more sophisticated handlers like # one that sends events and another that tries to keep collided objects # apart, but the results are often better with a simple queue self.cHandler = CollisionHandlerQueue() # Now we add the collision nodes that can create a collision to the # traverser. The traverser will compare these to all others nodes in the # scene. There is a limit of 32 CollisionNodes per traverser # We add the collider, and the handler to use as a pair self.cTrav.addCollider(self.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. # self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1) # Finally, we call start for more initialization self.start() def start(self): # The maze model also has a locator in it for where to start the ball # To access it we use the find command startPos = self.maze.find("**/start").getPos() self.ballRoot.setPos(startPos) # Set the ball in the starting position self.ballV = Vec3(0, 0, 0) # Initial velocity is 0 self.accelV = Vec3(0, 0, 0) # Initial acceleration is 0 # For a traverser to actually do collisions, you need to call # traverser.traverse() on a part of the scene. Fortunatly, base has a # task that does this for the entire scene once a frame. This sets up our # traverser as the one to be called automatically base.cTrav = self.cTrav # Create the movement task, but first make sure it is not already running taskMgr.remove("rollTask") self.mainLoop = taskMgr.add(self.rollTask, "rollTask") self.mainLoop.last = 0 # This function handles the collision between the ray and the ground # Information about the interaction is passed in colEntry def groundCollideHandler(self, colEntry): # Set the ball to the appropriate Z value for it to be exactly on the ground newZ = colEntry.getSurfacePoint(render).getZ() self.ballRoot.setZ(newZ + .4) # Find the acceleration direction. First the surface normal is crossed with # the up vector to get a vector perpendicular to the slope norm = colEntry.getSurfaceNormal(render) accelSide = norm.cross(UP) # Then that vector is crossed with the surface normal to get a vector that # points down the slope. By getting the acceleration in 3D like this rather # than in 2D, we reduce the amount of error per-frame, reducing jitter self.accelV = norm.cross(accelSide) # This function handles the collision between the ball and a wall def wallCollideHandler(self, colEntry): # First we calculate some numbers we need to do a reflection norm = colEntry.getSurfaceNormal(render) * -1 # The normal of the wall curSpeed = self.ballV.length() # The current speed inVec = self.ballV / curSpeed # The direction of travel velAngle = norm.dot(inVec) # Angle of incidance hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos() hitDir.normalize() hitAngle = norm.dot( hitDir) # The angle between the ball and the normal # Ignore the collision if the ball is either moving away from the wall # already (so that we don't accidentally send it back into the wall) # and ignore it if the collision isn't dead-on (to avoid getting caught on # corners) if velAngle > 0 and hitAngle > .995: # Standard reflection equation reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec # This makes the velocity half of what it was if the hit was dead-on # and nearly exactly what it was if this is a glancing blow self.ballV = reflectVec * (curSpeed * (((1 - velAngle) * .5) + .5)) # Since we have a collision, the ball is already a little bit buried in # the wall. This calculates a vector needed to move it so that it is # exactly touching the wall disp = (colEntry.getSurfacePoint(render) - colEntry.getInteriorPoint(render)) newPos = self.ballRoot.getPos() + disp self.ballRoot.setPos(newPos) # This is the task that deals with making everything interactive def rollTask(self, task): # Standard technique for finding the amount of time since the last frame dt = task.time - task.last task.last = task.time # If dt is large, then there has been a # hiccup that could cause the ball # to leave the field if this functions runs, so ignore the frame if dt > .2: return Task.cont # The collision handler collects the collisions. We dispatch which function # to handle the collision based on the name of what was collided into for i in range(self.cHandler.getNumEntries()): entry = self.cHandler.getEntry(i) name = entry.getIntoNode().getName() if name == "wall_collide": self.wallCollideHandler(entry) elif name == "ground_collide": self.groundCollideHandler(entry) elif name == "loseTrigger": self.loseGame(entry) # Read the mouse position and tilt the maze accordingly if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() # get the mouse position self.maze.setP(mpos.getY() * -10) self.maze.setR(mpos.getX() * 10) # Finally, we move the ball # Update the velocity based on acceleration self.ballV += self.accelV * dt * ACCEL # Clamp the velocity to the maximum speed if self.ballV.lengthSquared() > MAX_SPEED_SQ: self.ballV.normalize() self.ballV *= MAX_SPEED # Update the position based on the velocity self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV * dt)) # This block of code rotates the ball. It uses something called a quaternion # to rotate the ball around an arbitrary axis. That axis perpendicular to # the balls rotation, and the amount has to do with the size of the ball # This is multiplied on the previous rotation to incrimentally turn it. prevRot = LRotationf(self.ball.getQuat()) axis = UP.cross(self.ballV) newRot = LRotationf(axis, 45.5 * dt * self.ballV.length()) self.ball.setQuat(prevRot * newRot) return Task.cont # Continue the task indefinitely def show_message(self, message=''): if message: self.central_msg.setText(message) self.central_msg.show() else: self.central_msg.hide() # If the ball hits a hole trigger, then it should fall in the hole. # This is faked rather than dealing with the actual physics of it. def loseGame(self, entry): # The triggers are set up so that the center of the ball should move to the # collision point to be in the hole toPos = entry.getInteriorPoint(render) taskMgr.remove('rollTask') # Stop the maze task # Move the ball into the hole over a short sequence of time. Then wait a # second and call start to reset the game Sequence( Parallel( LerpFunc(self.ballRoot.setX, fromData=self.ballRoot.getX(), toData=toPos.getX(), duration=.1), LerpFunc(self.ballRoot.setY, fromData=self.ballRoot.getY(), toData=toPos.getY(), duration=.1), LerpFunc(self.ballRoot.setZ, fromData=self.ballRoot.getZ(), toData=self.ballRoot.getZ() - .9, duration=.2)), Func(self.show_message, "Try Again!"), Wait(1), Func(self.show_message, ""), Func(self.start)).start()
class CharacterGUI: """Widget with the selected character info.""" def __init__(self): self.char = None # the chosen character self.rest_list_shown = False self._status_lab = None self._rest_buttons = {} self._char_desc_wids = [] self._char_desc_shown = False self._fr = DirectFrame( parent=base.a2dTopLeft, # noqa: F821 frameSize=(-0.31, 0.31, -0.1, 0.115), pos=(0.31, 0, -1.9), frameTexture=GUI_PIC + "metal1.png", state=DGG.NORMAL, ) self._fr.setTransparency(TransparencyAttrib.MAlpha) # a "?" button to open a detailed description of the character self._char_desc_but = DirectButton( parent=self._fr, pos=(0.27, 0, 0.0675), command=self._show_char_desc, clickSound=base.main_menu.click_snd, # noqa: F821 **ABOUT_BUT_PARAMS, ) DirectLabel( # Name: parent=self._fr, text=base.labels.CHARACTERS[0], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.22, 0, 0.07), ) self._char_name = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=SILVER_COL, pos=(-0.09, 0, 0.069), ) self._traits = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=(0.028, 0.028), text_fg=SILVER_COL, text_font=base.main_font, # noqa: F821 pos=(0, 0, 0.025), ) DirectLabel( # Class: parent=self._fr, text=base.labels.CHARACTERS[1], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(0.05, 0, 0.07), ) self._char_class = DirectLabel( parent=self._fr, text="", frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=SILVER_COL, pos=(0.17, 0, 0.068), ) DirectLabel( # Health parent=self._fr, text=base.labels.CHARACTERS[2], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.22, 0, -0.015), ) self._char_health = DirectWaitBar( parent=self._fr, frameSize=(-0.17, 0.17, -0.002, 0.002), frameColor=(0.35, 0.35, 0.35, 1), value=0, barColor=(0.85, 0.2, 0.28, 1), pos=(0.07, 0, -0.008), ) DirectLabel( # Energy parent=self._fr, text=base.labels.CHARACTERS[3], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.216, 0, -0.06), ) self._char_energy = DirectWaitBar( parent=self._fr, frameSize=(-0.17, 0.17, -0.002, 0.002), frameColor=(0.35, 0.35, 0.35, 1), value=0, barColor=(0.46, 0.61, 0.53, 1), pos=(0.07, 0, -0.053), ) self._tip = OnscreenText( parent=base.render2d, # noqa: F821 text="", font=base.main_font, # noqa: F821 scale=(0.021, 0.027), fg=SILVER_COL, bg=(0, 0, 0, 0.4), ) self._tip.hide() self._disease = DirectFrame( parent=self._fr, frameSize=(-0.02, 0.02, -0.02, 0.02), pos=(0.27, 0, -0.008), frameTexture=GUI_PIC + "disease.png", ) self._disease.setTransparency(TransparencyAttrib.MAlpha) self.clear_char_info() def _update_char_info(self, task): """Track the chosen character parameters in the GUI.""" if self.char.is_dead: self.clear_char_info() return task.done self._char_health["value"] = self.char.health self._char_energy["value"] = self.char.energy self._traits["text"] = ", ".join(self.char.traits) if self.char.is_diseased: self._disease.show() else: self._disease.hide() if self._char_desc_shown: self._update_desc() return task.again def _update_desc(self): """Update the chosen character description.""" to_del = [] for wid in self._char_desc_wids: if wid["text"] not in ( # Traits base.labels.CHARACTERS[5], # noqa: F821 # Status base.labels.CHARACTERS[4], # noqa: F821 "", ): wid.destroy() to_del.append(wid) for del_wid in to_del: self._char_desc_wids.remove(del_wid) self._fill_status(self._fill_traits(0.64)) def _fill_traits(self, shift): """Fill the chosen character traits. Args: shift (float): Z-coor for the new widgets. Returns: float: Z-coor including the new widgets shift. """ shift -= 0.03 for trait in self.char.traits + self.char.disabled_traits: self._char_desc_wids.append( DirectLabel( parent=self._fr, text=trait, frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_font=base.main_font, # noqa: F821 text_fg=SILVER_COL if trait in self.char.traits else (0.3, 0.3, 0.3, 1), pos=(0, 0, shift), ) ) self._char_desc_wids.append( DirectLabel( parent=self._fr, text=base.labels.TRAIT_DESC[trait], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.029, text_fg=SILVER_COL if trait in self.char.traits else (0.3, 0.3, 0.3, 1), pos=(0, 0, shift - 0.045), ) ) shift -= 0.1 return shift def _fill_status(self, shift): """Fill the chosen character status. Args: shift (float): Z-coor for the new widgets. """ shift -= 0.04 for status in self.char.statuses: self._char_desc_wids.append( DirectLabel( parent=self._fr, text=status, text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.029, text_fg=SILVER_COL, pos=(0, 0, shift), ) ) shift -= 0.045 def _show_char_desc(self): """Show detailed character description. Includes description of every character's trait and their current status. """ if self._char_desc_shown: self._fr["frameSize"] = (-0.31, 0.31, -0.1, 0.115) clear_wids(self._char_desc_wids) self._status_lab = None else: shift = 0.7 self._fr["frameSize"] = (-0.31, 0.31, -0.1, shift) shift -= 0.06 self._char_desc_wids.append( DirectLabel( parent=self._fr, # Traits text=base.labels.CHARACTERS[5], # noqa: F821, text_font=base.main_font, # noqa: F821, frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.225, 0, shift), ) ) if self.char.id in base.team.chars.keys(): # noqa: F821 traits_but = DirectButton( parent=self._fr, text="", frameSize=(-0.025, 0.025, -0.025, 0.025), frameTexture=GUI_PIC + "like.png", relief="flat", pos=(0.265, 0, shift + 0.013), command=base.traits_gui.show, # noqa: F821 ) traits_but.bind( DGG.ENTER, self._highlight_traits_but, extraArgs=[traits_but] ) traits_but.bind( DGG.EXIT, self._dehighlight_traits_but, extraArgs=[traits_but] ) self._char_desc_wids.append(traits_but) shift = self._fill_traits(shift) self._status_lab = DirectLabel( # Status parent=self._fr, # Status text=base.labels.CHARACTERS[4], # noqa: F821 text_font=base.main_font, # noqa: F821 frameSize=(0.1, 0.1, 0.1, 0.1), text_scale=0.03, text_fg=RUST_COL, pos=(-0.221, 0, shift), ) self._char_desc_wids.append(self._status_lab) self._fill_status(shift) self._char_desc_shown = not self._char_desc_shown def _dehighlight_traits_but(self, button, _): """Dehighlight traits tweaking button. Args: button (panda3d.gui.DirectGui.DirectButton): Button to dehighlight. """ button["frameTexture"] = GUI_PIC + "like.png" def _highlight_traits_but(self, button, _): """Hightlight traits tweaking button. Args: button (panda3d.gui.DirectGui.DirectButton): Button to highlight. """ button["frameTexture"] = GUI_PIC + "hover_like.png" def clear_char_info(self, clear_resting=True): """Clear the character GUI. Args: clear_resting (bool): Optional. A flag indicating if the list of the resting characters should also be closed. """ for wid in ( self._char_name, self._char_class, self._char_health, self._char_energy, self._traits, self._char_desc_but, self._disease, ): wid.hide() if self._char_desc_shown: self._show_char_desc() taskMgr.remove("track_char_info") # noqa: F821 self.char = None if clear_resting: for but in self._rest_buttons.values(): but.destroy() self.rest_list_shown = False def destroy_char_button(self, char_id): """Hide the given character button from the resting characters list. Args: char_id (str): Character id. """ if char_id in self._rest_buttons.keys(): self._rest_buttons[char_id].destroy() self._rest_buttons.pop(char_id) def hide_tip(self): """Hide the tooltip.""" self._tip.hide() def show_char_info(self, char): """Show the given character status. Args: char (units.crew.character.Character): The chosen character object. """ self._char_name["text"] = char.name self._char_class["text"] = char.class_.capitalize() self._traits["text"] = ", ".join(char.traits) self._char_health["range"] = char.class_data["health"] self._char_health["value"] = char.health self._char_energy["value"] = char.energy if char.is_diseased: self._disease.show() else: self._disease.hide() self.char = char self._char_name.show() self._char_class.show() self._char_health.show() self._char_energy.show() self._traits.show() self._char_desc_but.show() if self._char_desc_shown: self._show_char_desc() self._show_char_desc() taskMgr.doMethodLater( # noqa: F821 0.5, self._update_char_info, "track_char_info" ) def show_tooltip(self, text): """Show tooltip with the given text. Args: text (str): Text to show in the tooltip. """ if not base.mouseWatcherNode.hasMouse(): # noqa: F821 return if self.rest_list_shown and text == "Rest zone": return self._tip.setText(text) self._tip.setX(base.mouseWatcherNode.getMouseX()) # noqa: F821 self._tip.setY(base.mouseWatcherNode.getMouseY()) # noqa: F821 self._tip.show() def show_resting_chars(self, part): """Show a list of the characters resting in this part. Args: part (Train.RestPart): Rest part of the Train. """ if self.rest_list_shown: return self._tip.hide() self.rest_list_shown = True x = base.mouseWatcherNode.getMouseX() # noqa: F821 z = base.mouseWatcherNode.getMouseY() # noqa: F821 self._rest_buttons["title"] = DirectButton( pos=(x, 0, z), text=base.labels.TIPS[0], # noqa: F821 text_fg=RUST_COL, text_font=base.main_font, # noqa: F821 frameColor=(0, 0, 0, 0.6), scale=(0.04, 0, 0.03), ) shift = -0.039 for char in part.chars: if char.is_dead: continue self._rest_buttons[char.id] = DirectButton( pos=(x, 0, z + shift), text=char.name, text_fg=SILVER_COL, frameColor=(0, 0, 0, 0.6), command=base.common_ctrl.choose_char, # noqa: F821 extraArgs=[char.id], scale=(0.04, 0, 0.03), ) shift -= 0.033 def move_status_label(self, place): """Move the status label widget. Args: place (int): Place to shift the widget. """ if self._status_lab is not None: self._status_lab.setZ(self._status_lab.getZ() + place / 10) def update_resting_chars(self, part): """Update the list of the resting characters. Args: part (train.part.TrainPart): Rest train part. """ for key, but in self._rest_buttons.items(): if key != "title": but.destroy() self._rest_buttons[key] = None x, _, z = self._rest_buttons["title"].getPos() shift = -0.039 for char in part.chars: self._rest_buttons[char.id] = DirectButton( pos=(x, 0, z + shift), text=char.name, text_fg=SILVER_COL, frameColor=(0, 0, 0, 0.6), command=base.common_ctrl.choose_char, # noqa: F821 extraArgs=[char.id], scale=(0.04, 0, 0.03), ) shift -= 0.033
class TeamActivityGui: COUNTDOWN_TASK_NAME = 'updateCountdownTask' timer = None statusText = None countdownText = None exitButton = None switchButton = None def __init__(self, activity): self.activity = activity def load(self): buttonModels = loader.loadModel('phase_3.5/models/gui/inventory_gui') upButton = buttonModels.find('**//InventoryButtonUp') downButton = buttonModels.find('**/InventoryButtonDown') rolloverButton = buttonModels.find('**/InventoryButtonRollover') self.exitButton = DirectButton( relief=None, text=TTLocalizer.PartyTeamActivityExitButton, text_fg=(1, 1, 0.65, 1), text_pos=(0, -0.15), text_scale=0.5, image=(upButton, downButton, rolloverButton), image_color=(1, 0, 0, 1), image_scale=(14.5, 1, 9), pos=(0, 0, 0.8), scale=0.15, command=self.handleExitButtonClick) self.exitButton.hide() if self.activity.toonsCanSwitchTeams(): self.switchButton = DirectButton( relief=None, text=TTLocalizer.PartyTeamActivitySwitchTeamsButton, text_fg=(1, 1, 1, 1), text_pos=(0, 0.1), text_scale=0.5, image=(upButton, downButton, rolloverButton), image_color=(0, 1, 0, 1), image_scale=(15, 1, 15), pos=(0, 0, 0.5), scale=0.15, command=self.handleSwitchButtonClick) self.switchButton.hide() else: self.switchButton = None buttonModels.removeNode() self.countdownText = OnscreenText( text='', pos=(0.0, -0.2), scale=PartyGlobals.TeamActivityTextScale * 1.2, fg=(1.0, 1.0, 0.65, 1.0), align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), mayChange=True) self.countdownText.hide() self.statusText = OnscreenText( text='', pos=(0.0, 0.0), scale=PartyGlobals.TeamActivityTextScale, fg=PartyGlobals.TeamActivityStatusColor, align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), mayChange=True) self.statusText.hide() self.timer = PartyUtils.getNewToontownTimer() self.timer.hide() return def unload(self): self.hideWaitToStartCountdown() if self.exitButton is not None: self.exitButton.destroy() self.exitButton = None if self.switchButton is not None: self.switchButton.destroy() self.switchButton = None if self.countdownText is not None: self.countdownText.destroy() self.countdownText.removeNode() self.countdownText = None if self.statusText is not None: self.statusText.destroy() self.statusText.removeNode() self.statusText = None if self.timer is not None: self.timer.destroy() del self.timer return def showStatus(self, text): self.statusText.setText(text) self.statusText.show() def hideStatus(self): self.statusText.hide() def enableExitButton(self): self.exitButton.show() def disableExitButton(self): self.exitButton.hide() def handleExitButtonClick(self): self.disableExitButton() self.disableSwitchButton() self.activity.d_toonExitRequest() def enableSwitchButton(self): self.switchButton.show() def disableSwitchButton(self): if self.switchButton is not None: self.switchButton.hide() return def handleSwitchButtonClick(self): self.disableSwitchButton() self.disableExitButton() self.activity.d_toonSwitchTeamRequest() def showWaitToStartCountdown(self, duration, waitToStartTimestamp, almostDoneCallback=None): self._countdownAlmostDoneCallback = almostDoneCallback currentTime = globalClock.getRealTime() waitTimeElapsed = currentTime - waitToStartTimestamp if duration - waitTimeElapsed > 1.0: countdownTask = Task(self._updateCountdownTask) countdownTask.duration = duration - waitTimeElapsed self.countdownText.setText(str(int(countdownTask.duration))) self.countdownText.show() taskMgr.remove(TeamActivityGui.COUNTDOWN_TASK_NAME) taskMgr.add(countdownTask, TeamActivityGui.COUNTDOWN_TASK_NAME) def hideWaitToStartCountdown(self): taskMgr.remove(TeamActivityGui.COUNTDOWN_TASK_NAME) self._countdownAlmostDoneCallback = None if self.countdownText is not None: self.countdownText.hide() return def _updateCountdownTask(self, task): countdownTime = int(task.duration - task.time) seconds = str(countdownTime) if self.countdownText['text'] != seconds: self.countdownText['text'] = seconds if countdownTime == 3 and self._countdownAlmostDoneCallback is not None: self._countdownAlmostDoneCallback() self._countdownAlmostDoneCallback = None if task.time >= task.duration: return Task.done else: return Task.cont return def showTimer(self, duration): self.timer.setTime(duration) self.timer.countdown(duration, self._handleTimerExpired) self.timer.show() def hideTimer(self): self.timer.hide() self.timer.stop() def _handleTimerExpired(self): self.activity.handleGameTimerExpired()
class LabTask03(DirectObject): #define the state of the game and level gameState = 'INIT' gameLevel = 1 cameraState = 'STARTUP' count = 0 attempts = 3 posX = -200 posY = 20 posZ = 30 score = 0 contacts = 0 pause = False fire = True desiredCamPos = Vec3(-200,30,20) def __init__(self): self.imageObject = OnscreenImage(image = 'models/splashscreen.png', pos=(0,0,0), scale=(1.4,1,1)) preloader = Preloader() self.musicLoop = loader.loadSfx("music/loop/EndlessBliss.mp3") self.snowmansHit = loader.loadSfx("music/effects/snowball_hit.wav") self.candleThrow = loader.loadSfx("music/effects/snowball_throw.wav") self.presentHit = loader.loadSfx("music/effects/present_hit.wav") self.loseSound = loader.loadSfx("music/effects/Failure-WahWah.mp3") self.winSound = loader.loadSfx("music/effects/Ta Da-SoundBible.com-1884170640.mp3") self.nextLevelSound = loader.loadSfx("music/effects/button-17.wav") self.loseScreen = OnscreenImage(image = 'models/losescreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.loseScreen.hide() self.winScreen = OnscreenImage(image = 'models/winscreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.winScreen.hide() self.helpScreen = OnscreenImage(image = 'models/helpscreen.jpg', pos=(0,0,0.1), scale=(1,1,0.8)) self.helpScreen.hide() self.backBtn = DirectButton(text=("Back"), scale = 0.1, pos = (0,0,-0.8), command = self.doBack) self.retryBtn = DirectButton(text="Retry", scale = 0.1, pos = (0,0,0), command = self.doRetry) self.retryBtn.hide() self.menuBtn = DirectButton(text="Main Menu", scale = 0.1, pos = (0,0,0), command = self.doBack) self.menuBtn.hide() self.backBtn.hide() base.setBackgroundColor(0.1, 0.1, 0.8, 1) #base.setFrameRateMeter(True) # Position the camera base.cam.setPos(0, 30, 20) base.cam.lookAt(0, 30, 0) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, 1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) render.setLight(dlightNP) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('f', self.doShoot, [True]) self.accept('p', self.doPause) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') inputState.watchWithModifiers('moveLineUp', 'i') inputState.watchWithModifiers('moveLineDown','k') inputState.watchWithModifiers('moveLineRight','l') inputState.watchWithModifiers('moveLineLeft','j') self.font = loader.loadFont('models/SHOWG.TTF') self.font.setPixelsPerUnit(60) self.attemptText = OnscreenText(text='', pos = (0.9,0.8), scale = 0.07, font = self.font) self.levelText = OnscreenText(text='', pos=(-0.9,0.9), scale = 0.07, font = self.font ) self.scoreText = OnscreenText(text='', pos = (0.9,0.9), scale = 0.07, font = self.font) self.text = OnscreenText(text = '', pos = (0, 0), scale = 0.07, font = self.font) self.pauseText = OnscreenText(text='P: Pause', pos= (0.9,0.7), scale = 0.05, font = self.font) self.pauseText.hide() # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def doRetry(self): self.loseScreen.hide() self.levelText.clearText() self.scoreText.clearText() self.attemptText.clearText() self.playGame() self.retryBtn.hide() self.cleanup() self.setup() def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.attempts = 3 self.cameraState = 'STARTUP' base.cam.setPos(0,30,20) self.arrow.removeNode() self.scoreText.clearText() self.levelText.clearText() self.attemptText.clearText() self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def doShoot(self, ccd): if(self.fire and self.attempts > 0 and self.gameState == 'PLAY'): self.cameraState = 'LOOK' self.fire = False self.candleThrow.play() self.attempts -= 1 #get from/to points from mouse click ## pMouse = base.mouseWatcherNode.getMouse() ## pFrom = Point3() ## pTo = Point3() ## base.camLens.extrude(pMouse, pFrom, pTo) ## pFrom = render.getRelativePoint(base.cam, pFrom) ## pTo = render.getRelativePoint(base.cam, pTo) # calculate initial velocity v = self.pTo - self.pFrom ratio = v.length() / 40 v.normalize() v *= 70.0 * ratio torqueOffset = random.random() * 10 #create bullet shape = BulletSphereShape(0.5) shape01 = BulletSphereShape(0.5) shape02 = BulletSphereShape(0.5) shape03 = BulletSphereShape(0.5) body = BulletRigidBodyNode('Candle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape, TransformState.makePos(Point3(0,0,0))) bodyNP.node().addShape(shape01, TransformState.makePos(Point3(0,0.5,-0.5))) bodyNP.node().addShape(shape02,TransformState.makePos(Point3(0,1,-1))) bodyNP.node().addShape(shape03,TransformState.makePos(Point3(0,1.5,-1.5))) bodyNP.node().setMass(100) bodyNP.node().setFriction(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().applyTorque(v*torqueOffset) bodyNP.setPos(self.pFrom) bodyNP.setCollideMask(BitMask32.allOn()) visNP = loader.loadModel('models/projectile.X') visNP.setScale(0.7) visNP.clearModelNodes() visNP.reparentTo(bodyNP) #self.bird = bodyNP.node() if ccd: bodyNP.node().setCcdMotionThreshold(1e-7) bodyNP.node().setCcdSweptSphereRadius(0.5) self.world.attachRigidBody(bodyNP.node()) #remove the bullet again after 1 sec self.bullets = bodyNP taskMgr.doMethodLater(5, self.removeBullet, 'removeBullet', extraArgs=[bodyNP], appendTask = True) def removeBullet(self, bulletNP, task): self.cameraState = 'STAY' self.fire = True self.world.removeRigidBody(bulletNP.node()) bulletNP.removeNode() if(self.attempts <= 0 and len(self.snowmans)>0): self.gameState = 'LOSE' self.doContinue() return task.done # ____TASK___ def processInput(self, dt): force = Vec3(0, 0, 0) torque = Vec3(0, 0, 0) #print self.pTo.getY() if inputState.isSet('forward'): if(self.pTo.getZ() < 40): self.pTo.addZ(0.5) if inputState.isSet('reverse'): if(self.pTo.getZ() > 0 ): self.pTo.addZ(-0.5) if inputState.isSet('left'): if(self.pTo.getY() < 100): self.pTo.addY(0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()-0.006,self.arrow.getSz()) if inputState.isSet('right'): if(self.pTo.getY() > 60): self.pTo.addY(-0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()+0.006,self.arrow.getSz()) self.arrow.lookAt(self.pTo) def processContacts(self, dt): for box in self.boxes: for snowman in self.snowmans: result = self.world.contactTestPair(box, snowman.node()) if (result.getNumContacts() > 0): self.snowmansHit.play() self.score += 100 self.text.setPos(0,0.7) self.text.setText("HIT") self.snowmans.remove(snowman) self.world.removeRigidBody(snowman.node()) snowman.removeNode() if(len(self.snowmans) <= 0): self.gameState = "NEXT" self.text.setText('Nice! Press space to continue') for box in self.boxes: for present in self.presents: result01 = self.world.contactTestPair(box,present.node()) if(result01.getNumContacts() > 0): self.presents.remove(present) self.world.removeRigidBody(present.node()) present.removeNode() self.presentHit.play() self.score += 500 def doContinue(self): if(self.gameState == 'INIT'): self.gameState = 'MENU' self.text.clearText() self.musicLoop.setLoop(True) self.musicLoop.setVolume(0.5) self.musicLoop.play() self.startBtn = DirectButton(text=("Play"), scale = 0.1, pos = (0,0,0),command=self.playGame) self.helpBtn = DirectButton(text=("Help"), scale = 0.1, pos = (0,0,-0.2),command=self.help) self.exitBtn = DirectButton(text=("Exit"), scale = 0.1, pos = (0,0,-0.4), command = self.doExit) return if self.gameState == 'NEXT': self.nextLevelSound.play() self.fire = True self.gameLevel += 1 self.score += (self.attempts * 100) self.doReset() self.gameState = 'PLAY' return if self.gameState == 'LOSE': self.loseSound.play() self.arrow.removeNode() self.loseScreen.show() self.levelText.hide() self.attemptText.hide() self.scoreText.hide() self.text.hide() self.pauseText.hide() self.retryBtn.show() return if self.gameState == 'WIN': self.levelText.hide() self.attemptText.hide() self.scoreText.clearText() self.scoreText.setPos(0,0.6) self.scoreText.setText("%s"%self.score) self.winScreen.show() self.winSound.play() self.menuBtn.show() self.pauseText.hide() return def playGame(self): print "Play Game" self.attempts = 3 self.score = 0 self.gameLevel = 1 self.gameState = 'PLAY' self.musicLoop.setVolume(0.3) self.imageObject.hide() self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.cleanup() self.setup() def doBack(self): self.gameState = 'MENU' self.scoreText.setPos(0.9,0.9) self.scoreText.hide() self.imageObject.show() self.startBtn.show() self.exitBtn.show() self.helpBtn.show() self.helpScreen.hide() self.backBtn.hide() self.menuBtn.hide() self.winScreen.hide() def help(self): self.gameState = 'HELP' self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.backBtn.show() self.helpScreen.show() return def doPause(self): self.pause = not self.pause if(self.pause): self.text.setText("Pause") else: self.text.clearText() def update(self, task): dt = globalClock.getDt() if(not self.pause): if self.gameState == 'INIT': self.text.setPos(0,0) self.text.setText('Press space to continue') self.accept('space',self.doContinue) if self.gameState == 'PLAY': #print self.posZ #if(self.posX < -120): # self.posX += 0.03 # self.posZ -= 0.02 #elif(self.posZ < 70): # self.posZ += 0.02; #elif(self.posZ > 70 and self.posX > -120): # self.posZ -= 0.02 # self.posX -= 0.03 #base.cam.setPos(self.posX, self.posZ, self.posY) self.levelText.setText('Level: %s'%self.gameLevel) self.attemptText.setText('Tries Left: %s'%self.attempts) self.scoreText.setText('Score: %s'%self.score) self.pauseText.show() self.processContacts(dt) self.world.doPhysics(dt, 20, 1.0/180.0) #self.drawLines() self.processInput(dt) if self.cameraState == 'STARTUP': oldPos = base.cam.getPos() pos = (oldPos*0.9) + (self.desiredCamPos*0.1) base.cam.setPos(pos) base.cam.lookAt(0,30,0) elif self.cameraState == 'STAY': #oldPos = base.cam.getPos() #currPos = (oldPos*0.9) + (self.desiredCamPos*0.1) #base.cam.setPos(currPos) base.cam.lookAt(0,30,0) elif self.cameraState == 'LOOK': base.cam.lookAt(self.bullets) #base.cam.setPos(-200,self.bullets.getZ(),20) if self.gameState == 'NEXT': self.world.doPhysics(dt, 20, 1.0/180.0) ## self.raycast() return task.cont def raycast(self): # Raycast for closest hit tsFrom = TransformState.makePos(Point3(0,0,0)) tsTo = TransformState.makePos(Point3(10,0,0)) shape = BulletSphereShape(0.5) penetration = 1.0 result = self.world.sweepTestClosest(shape, tsFrom, tsTo, penetration) if result.hasHit(): torque = Vec3(10,0,0) force = Vec3(0,0,100) ## for hit in result.getHits(): ## hit.getNode().applyTorque(torque) ## hit.getNode().applyCentralForce(force) result.getNode().applyTorque(torque) result.getNode().applyCentralForce(force) ## print result.getClosestHitFraction() ## print result.getHitFraction(), \ ## result.getNode(), \ ## result.getHitPos(), \ ## result.getHitNormal() def cleanup(self): self.world = None self.worldNP.removeNode() self.arrow.removeNode() self.lines.reset() self.text.clearText() def setup(self): self.attemptText.show() self.levelText.show() self.scoreText.show() self.text.show() self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) #arrow self.scaleY = 10 self.arrow = loader.loadModel('models/arrow.X') self.arrow.setScale(0.5,0.5,0.5) self.arrow.setAlphaScale(0.5) #self.arrow.setTransparency(TransparencyAttrib.MAlpha) self.arrow.reparentTo(render) #SkyBox skybox = loader.loadModel('models/skybox.X') skybox.reparentTo(render) # Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 0) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, -1) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/ground.X') visualNP.clearModelNodes() visualNP.reparentTo(np) #some boxes self.boxes = [] self.snowmans = [] self.platforms = [] self.presents = [] #TODO: Make a table #Table Top #self.createBox(Vec3(),Vec3()) if(self.gameLevel == 1): self.createBox(Vec3(5,7,1),Vec3(0,5,10),1.0) #2 legs self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) # Pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(1.5, Vec3(0,-10,4.0),10.0) if(self.gameLevel == 2): #table01 self.createBox(Vec3(5,14,1),Vec3(0,-2,12),2.0) self.createBox(Vec3(5,7,1),Vec3(0,5,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) #table02 self.createBox(Vec3(5,7,1),Vec3(0,-9,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,-3,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-15,5),1.0) #table03 self.createBox(Vec3(1,1,1), Vec3(0,-1,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-5,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,5,14), 2.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0, Vec3(0,-9,2.0), 10.0) self.createSnowman(2.0,Vec3(0,-23,2.0),10.0) if(self.gameLevel == 3): #table01 self.createBox(Vec3(4,2,2),Vec3(0,12,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,13,5),1.0) #table02 self.createBox(Vec3(4,2,2),Vec3(0,-15,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-14,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-16,5),1.0) #table03 self.createBox(Vec3(4,10,1),Vec3(0,-1,12),1.0) self.createBox(Vec3(4,10,1),Vec3(0,-1,14),1.0) self.createBox(Vec3(4,2,4),Vec3(0,-2,5),0.1) #table04 self.createPlatform(Vec3(4,8,1),Vec3(0,7,16),1.0) self.createPlatform(Vec3(4,8,1),Vec3(0,-9,16),1.0) self.createBox(Vec3(4,1,3),Vec3(0,13,20),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-16,20),1.0) #table05 self.createBox(Vec3(4,15,1),Vec3(0,-1,24),1.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,-2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,4,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,8,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,6,20),5.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0,Vec3(0,-8.5,2.0),10.0) self.createSnowman(1.5, Vec3(0,-9,19.5), 7.0) #presents self.createPresent(Vec3(2,2,2),Vec3(0,-20,5)) if(self.gameLevel == 4): #wall self.createStoneBox(Vec3(4,1.5,10), Vec3(0,20,10),20) #table01 self.createBox(Vec3(4,1,5), Vec3(0,7,7),1) self.createBox(Vec3(4,1,5), Vec3(0,0,7),1) self.createBox(Vec3(4,1,4), Vec3(0,3,7),1) self.createPlatform(Vec3(5,8,1), Vec3(0,4,13),1) self.createBox(Vec3(4,1,3), Vec3(0,11,18),1) self.createBox(Vec3(4,1,3), Vec3(0,-3,18),1) self.createBox(Vec3(4,8,1), Vec3(0,4,25),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,4,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,7,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,29),2) #stairs self.createPlatform(Vec3(4,50,4), Vec3(0,-55,5),100) #table02 self.createBox(Vec3(4,1,5), Vec3(0,-13,15),1) self.createBox(Vec3(4,1,5), Vec3(0,-20,15),1) self.createBox(Vec3(4,1,4), Vec3(0,-17,15),1) self.createPlatform(Vec3(4,8,1), Vec3(0,-16,22),1) self.createBox(Vec3(4,1,3), Vec3(0,-9,28),1) self.createBox(Vec3(4,1,3), Vec3(0,-23,28),1) self.createBox(Vec3(4,8,1), Vec3(0,-16,33),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,-16,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-13,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,37),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-14,37),2) #snowman self.createSnowman(2.0,Vec3(0,30,5),1.0) self.createSnowman(1.5,Vec3(0,4,18),1.0) self.createSnowman(1.5,Vec3(0,-13,26),1.0) self.createSnowman(1.5,Vec3(0,-19,26),1.0) self.createSnowman(2.0,Vec3(0,12,5),1.0) self.createPresent(Vec3(2,2,2),Vec3(0,-25,13)) self.createPresent(Vec3(3,3,3),Vec3(0,-30,13)) self.createPresent(Vec3(4,4,4),Vec3(0,-36,13)) #self.createSnowman(1.5,Vec3(0,4,20),1.0) if(self.gameLevel == 5): #table01 self.createStoneBox(Vec3(4,7,3), Vec3(0,30,5),10.0) self.createStoneBox(Vec3(4,7,3), Vec3(0,-30,5),10.0) self.createBox(Vec3(4,1,3), Vec3(0,0,5), 1.0) self.createSnowman(1.5,Vec3(0,-6,5),1.0) self.createSnowman(1.5,Vec3(0,6,5),1.0) self.createBox(Vec3(4,1,3), Vec3(0,-12,5), 1.0) self.createBox(Vec3(4,1,3), Vec3(0,12,5), 1.0) self.createSnowman(1.5,Vec3(0,-18,5),1.0) self.createSnowman(1.5,Vec3(0,18,5),1.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-18,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,-6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,18,10), 0.1) self.createStoneBox(Vec3(4,1,3),Vec3(0,23,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-23,14), 1.0) self.createBox(Vec3(4,1,3),Vec3(0,18,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-18,14),1.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,13,20), 2.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,-13,20), 2.0) self.createBox(Vec3(4,1,3),Vec3(0,8,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-8,14),1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,3,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-3,14), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-5 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,5 ,20), 1.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-7.5,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,7.5,25), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-12,30), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,12,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,-5,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,5,30), 2.0) self.createBox(Vec3(4,5,1),Vec3(0,0,40), 2.0) self.createPlatform(Vec3(4,2,0.5),Vec3(0,0,42), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,-3.5,45), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,3.5,45), 2.0) self.createStoneBox(Vec3(4,4,0.5),Vec3(0,0,48), 2.0) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,22,30)) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,-22,30)) self.createPresent(Vec3(2,2,1),Vec3(0,0,44)) self.createPresent(Vec3(3,3,4),Vec3(0,0,33)) if(self.gameLevel > 5): self.gameState = 'WIN' self.doContinue() return # drawing lines between the points ## self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) ## self.pFrom = Point3(-4, 0, 0.5) ## self.pTo = Point3(4, 0, 0.5) # Aiming line self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) self.pFrom = Point3(0, 100, 0.5) self.pTo = Point3(0, 60, 10) self.arrow.setPos(self.pFrom) def drawLines(self): # Draws lines for the ray. self.lines.reset() self.lines.drawLines([(self.pFrom,self.pTo)]) self.lines.create() def createBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createStoneBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/stone.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createSnowman(self, size, pos, mass): shape = BulletBoxShape(Vec3(size,size,size)) shape01 = BulletSphereShape(size/2) body = BulletRigidBodyNode('Snowman') np = self.worldNP.attachNewNode(body) np.node().setMass(mass) np.node().addShape(shape, TransformState.makePos(Point3(0,0,-1))) np.node().addShape(shape01, TransformState.makePos(Point3(0,0,1))) np.node().setFriction(10.0) np.node().setDeactivationEnabled(False) np.setPos(pos) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/snowman.X') visualNP.setScale(size) visualNP.clearModelNodes() visualNP.reparentTo(np) self.snowmans.append(np) def createPlatform(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Platform') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.platforms.append(body) def createPresent(self,size,pos): shape = BulletBoxShape(size*0.7) body = BulletRigidBodyNode('Present') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/present.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.presents.append(bodyNP)
class KeyCodesGui(DirectObject): notify = directNotify.newCategory("KeyCodesGui") TIMEOUT_TASK = "KeyCodeGui_TIMEOUT_TASK" def __init__(self, keyCodes, yOffset=.55, keyToIndex=KEY_TO_INDEX): self._keyCodes = keyCodes # KeyCodes instance reference self._keyToIndex = keyToIndex self._arrowWidth = .18 self._arrowSpaceInBetween = .05 self._yOffset = yOffset self._danceMoveLabel = None self._arrowNodes = [] self.timeoutTask = None def load(self): """ Loads an initializes arrow nodes and dance move label. """ matchingGameGui = loader.loadModel("phase_3.5/models/gui/matching_game_gui") minnieArrow = matchingGameGui.find("**/minnieArrow") minnieArrow.setScale(0.6) minnieArrow.setZ(self._yOffset + 0.2) maxLength = self._keyCodes.getLargestPatternLength() for i in range(maxLength): arrow = minnieArrow.copyTo(hidden) self._arrowNodes.append(arrow) matchingGameGui.removeNode() self._danceMoveLabel = OnscreenText(parent = aspect2d, text = "", pos = (0, self._yOffset), scale = 0.15, align = TextNode.ACenter, font = ToontownGlobals.getSignFont(), fg = Vec4(1, 1, 1, 1), #shadow = Vec4(0, 0, 0, 1), mayChange = True, ) self._danceMoveLabel.hide() self.enable() def unload(self): self.disable() for arrow in self._arrowNodes: arrow.removeNode() arrow = None self._arrowNodes = [] if self._danceMoveLabel is not None: self._danceMoveLabel.removeNode() self._danceMoveLabel = None def enable(self): self.notify.debug("KeyCodeGui enabled.") self.accept(KeyCodes.KEY_DOWN_EVENT, self.__handleKeyDown) self.accept(KeyCodes.CLEAR_CODE_EVENT, self.hideAll) def disable(self): self.notify.debug("KeyCodeGui disabled.") self.__stopTimeout() self.ignoreAll() #=============================================================================== # Functions #=============================================================================== def hideArrows(self, startIndex=0): """ Hides arrows. Parameters: startIndex (optional): sets from what index start hiding the arrows. """ length = len(self._arrowNodes) if startIndex < length: for i in range(startIndex, length): self._arrowNodes[i].reparentTo(hidden) def hideAll(self, startIndex=0): self.hideArrows(startIndex) if self._danceMoveLabel: self._danceMoveLabel.hide() def showArrow(self, index, key): """ Shows arrow at a specific index, and hides all of the arrows after that index. """ # set rotation to the right rotation self._arrowNodes[index].setR(-(90 - 90 * self._keyToIndex[key])) self._arrowNodes[index].setColor(1, 1, 1, 1) self.__centerArrows() self._arrowNodes[index].reparentTo(aspect2d) self.hideAll(index + 1) self.__startTimeout() def showText(self, text=""): """ Shows label text. """ self.notify.debug('"Showing text "%s"' % text) self._danceMoveLabel["text"] = text self._danceMoveLabel.show() def setColor(self, r, g, b): """ Changes text and arrow color to a particular rgb value. """ for arrow in self._arrowNodes: arrow.setColor(r, g, b) self._danceMoveLabel.setColorScale(r, g, b, 1) #=============================================================================== # Helpers #=============================================================================== def __startTimeout(self): """ Starts timeout task to hide the gui elements. """ self.__stopTimeout() self.timeoutTask = taskMgr.doMethodLater(KEYCODE_TIMEOUT_SECONDS, self.__handleTimeoutTask, KeyCodesGui.TIMEOUT_TASK) def __stopTimeout(self): """ Stops a previously-set timeout from expiring. """ if self.timeoutTask is not None: taskMgr.remove(self.timeoutTask) self.timeoutTask = None def __handleTimeoutTask(self, task): """ Called after timing out. Hides all the keys and text label. """ self.hideAll() return Task.done def __centerArrows(self): """ Centers horizontally all visible arrows """ length = self._keyCodes.getCurrentInputLength() for i in range(length): x = -(length * self._arrowWidth * 0.5) + (self._arrowWidth * (i + 0.5)) self._arrowNodes[i].setX(x) def __handleKeyDown(self, key, index): """ Shows arrow when a keycode key is pressed down. """ if index >= 0: self.showArrow(index, key)
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.base = self self.font = loader.loadFont('1.ttf') self.jiechu1 = 0 self.jiechu2 = 0 self.down = 0 self.menuon = 0 # ESC退出 self.accept("escape", self.caidan) # 背景 self.beijing = OnscreenImage(image='1.jpg', pos=(0, 0, 0.02), scale=(1.4, 1, 1)) # 开始游戏碰之前图片 self.a1 = OnscreenImage(image='button3.png', pos=(-0.8, 0, 0.7), scale=(0.2, 0.1, 0.071)) # 碰到开始游戏后显示的按钮 self.zjmkaishi = DirectButton(text=('', '', '', 'disabled'), image='button2.png', frameColor=(255, 255, 255, 0), image_scale=(2, 1, 0.7), pos=(-0.8, 0, 0.7), scale=0.1, command=self.putdown) self.zjmkaishi.hide() # 点击开始游戏后图片 self.c1 = OnscreenImage(image='button1.png', pos=(-0.8, 0, 0.7), scale=(0.2, 0.1, 0.071)) self.c1.hide() # 开始游戏显示的文字 self.textObjectstart1 = OnscreenText(text='开始游戏', pos=(-0.8, 0.68, 0), scale=0.05, fg=(255, 255, 255, 1)) self.textObjectstart2 = OnscreenText(text='开始游戏', pos=(-0.8, 0.68, 0), scale=0.055, fg=(255, 255, 255, 1)) self.textObjectstart2.hide() self.textObjectstart3 = OnscreenText(text='开始游戏', pos=(-0.8, 0.68, 0), scale=0.06, fg=(255, 255, 255, 1)) self.textObjectstart3.hide() self.textObjectstart1.setFont(self.font) self.textObjectstart2.setFont(self.font) self.textObjectstart3.setFont(self.font) # 退出游戏碰之前图片 self.a2 = OnscreenImage(image='button3.png', pos=(-0.8, 0, 0.5), scale=(0.2, 0.1, 0.071)) # 碰到退出游戏后显示的按钮 self.zjmkaishi2 = DirectButton(text=('', '', '', 'disabled'), image='button2.png', frameColor=(255, 255, 255, 0), image_scale=(2, 1, 0.7), pos=(-0.8, 0, 0.5), scale=0.1, command=self.quit) self.zjmkaishi2.hide() # 点击退出游戏后图片 self.c2 = OnscreenImage(image='button1.png', pos=(-0.8, 0, 0.5), scale=(0.2, 0.1, 0.071)) self.c2.hide() # 退出游戏显示的文字 self.textObjectstart4 = OnscreenText(text='退出', pos=(-0.8, 0.48, 0), scale=0.05, fg=(255, 255, 255, 1)) self.textObjectstart5 = OnscreenText(text='退出', pos=(-0.8, 0.48, 0), scale=0.055, fg=(255, 255, 255, 1)) self.textObjectstart5.hide() self.textObjectstart6 = OnscreenText(text='退出', pos=(-0.8, 0.48, 0), scale=0.06, fg=(255, 255, 255, 1)) self.textObjectstart6.hide() self.textObjectstart4.setFont(self.font) self.textObjectstart5.setFont(self.font) self.textObjectstart6.setFont(self.font) # ESC菜单 self.caidanjiemian = OnscreenImage(image='caidan.jpg', pos=(0, 0, 0), scale=(0.5, 0.1, 0.41)) self.caidanjiemian.hide() self.bangzhu1button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, 0.23), scale=0.1, command=self.putdown1) self.bangzhu1button.hide() self.bangzhu1 = OnscreenText(text='游戏帮助', pos=(0, 0.21, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu1.setFont(self.font) self.bangzhu1.hide() self.bangzhu2button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, 0.03), scale=0.1, command=self.putdown2) self.bangzhu2button.hide() self.bangzhu2 = OnscreenText(text='继续游戏', pos=(0, 0.01, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu2.setFont(self.font) self.bangzhu2.hide() self.bangzhu3button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, -0.18), scale=0.1, command=self.putdown3) self.bangzhu3button.hide() self.bangzhu3 = OnscreenText(text='退出游戏', pos=(0, -0.2, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu3.setFont(self.font) self.bangzhu3.hide() self.bangzhujiemian = OnscreenImage(image='caidan.jpg', pos=(-0, 0, 0), scale=(1, 0.1, 0.81)) self.bangzhujiemian.hide() self.bangzhuxinxi = OnscreenText(text='coooooooooooooooool', pos=(0, 0, 0), scale=0.1) self.bangzhuxinxi.hide() self.bangzhuxinxibutton = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0.55, 0, -0.55), scale=0.1, command=self.help1) self.bangzhuxinxibutton.hide() self.bangzhuxinxi1 = OnscreenText(text='返回', pos=(0.55, -0.56, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhuxinxi1.setFont(self.font) self.bangzhuxinxi1.hide() taskMgr.add(self.example, 'MyTaskName') # 按下ESC触发 def caidan(self): if (self.menuon == 0): self.menuon = 1 self.caidanjiemian.show() self.bangzhu1button.show() self.bangzhu2button.show() self.bangzhu3button.show() self.bangzhu1.show() self.bangzhu2.show() self.bangzhu3.show() else: self.menuon = 0 self.caidanjiemian.hide() self.bangzhu1button.hide() self.bangzhu2button.hide() self.bangzhu3button.hide() self.bangzhu1.hide() self.bangzhu2.hide() self.bangzhu3.hide() self.bangzhujiemian.hide() self.bangzhuxinxi.hide() self.bangzhuxinxi1.hide() self.bangzhuxinxibutton.hide() # 无限循环 def example(self, task): mpos = base.mouseWatcherNode.getMouse() if mpos.getY() < 0.77 and mpos.getY() > 0.63 and mpos.getX( ) > -0.75 and mpos.getX() < -0.45: # print(mpos.getX()) self.jiechu1 = 1 elif mpos.getY() < 0.57 and mpos.getY() > 0.43 and mpos.getX( ) > -0.75 and mpos.getX() < -0.45: self.jiechu2 = 1 else: self.jiechu1 = 0 self.jiechu2 = 0 if (self.jiechu1 == 1 and self.down == 0): self.zjmkaishi.show() #self.textObjectstart1.hide() self.textObjectstart2.show() elif (self.jiechu2 == 1 and self.down == 0): self.zjmkaishi2.show() #self.textObjectstart4.hide() self.textObjectstart5.show() else: self.zjmkaishi.hide() self.textObjectstart2.hide() self.textObjectstart1.show() self.zjmkaishi2.hide() self.textObjectstart5.hide() self.textObjectstart4.show() return task.cont # return task.done # 按下开始游戏触发 def putdown(self): print('start') self.down = 1 self.a1.hide() self.zjmkaishi.hide() self.c1.show() self.textObjectstart1.hide() self.textObjectstart2.hide() self.textObjectstart3.show() # 按下退出游戏触发 def quit(self): print('exit') self.down = 1 self.a2.hide() self.zjmkaishi2.hide() self.c2.show() self.textObjectstart4.hide() self.textObjectstart5.hide() self.textObjectstart6.show() # 按下菜单界面按钮触发 def putdown1(self): self.caidanjiemian.hide() self.bangzhu1button.hide() self.bangzhu2button.hide() self.bangzhu3button.hide() self.bangzhu1.hide() self.bangzhu2.hide() self.bangzhu3.hide() self.bangzhujiemian.show() self.bangzhuxinxi.show() self.bangzhuxinxibutton.show() self.bangzhuxinxi1.show() def putdown2(self): print(2) def putdown3(self): print(3) # self.b.show() #按下帮助界面的返回触发 def help1(self): self.caidanjiemian.show() self.bangzhu1button.show() self.bangzhu2button.show() self.bangzhu3button.show() self.bangzhu1.show() self.bangzhu2.show() self.bangzhu3.show() self.bangzhujiemian.hide() self.bangzhuxinxi.hide() self.bangzhuxinxibutton.hide()
class SocketServer(): def __init__(self, port, virtual_world, camera_mgr, sync_session): self.port = port self.virtual_world = virtual_world self.cam_mgr = camera_mgr self.task_mgr = virtual_world.taskMgr self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cReader.setRawMode(True) self.cWriter = ConnectionWriter(self.cManager, 1) self.cWriter.setRawMode(True) self.tcpSocket = self.cManager.openTCPServerRendezvous(port, BACKLOG) self.cListener.addConnection(self.tcpSocket) self.activeSessions = {} self.connection_map = {} self.set_handlers() hostname = socket.gethostname() a, b, address_list = socket.gethostbyname_ex(hostname) self.ip = address_list[0] logging.info("Addresses %s" % address_list) logging.info("Server is running on ip: %s, port: %s" % (self.ip, self.port)) self.client_counter = 0 self.read_buffer = '' self.read_state = 0 self.read_body_length = 0 self.packet = SocketPacket() controller = virtual_world.getController() self.sync = Sync(self.task_mgr, controller, camera_mgr, sync_session) self.vv_id = None if sync_session: logging.info("Waiting for Sync Client!") self.showing_info = False virtual_world.accept("i", self.toggleInfo) self.sync_session = sync_session self.createInfoLabel() atexit.register(self.exit) def createInfoLabel(self): string = self.generateInfoString() self.info_label = OST(string, pos=(-1.3, -0.5), fg=(1, 1, 1, 1), bg=(0, 0, 0, 0.7), scale=0.05, align=TextNode.ALeft) self.info_label.hide() def generateInfoString(self, ): string = " IP:\t%s \n" % self.ip string += " PORT:\t%s \n" % self.port if self.sync_session: string += " MODE:\tSync Client\n" string += " VV ID:\t%s\n" % self.vv_id else: string += " MODE:\tAutomatic\n" cameras = self.cam_mgr.getCameras() num_cameras = len(cameras) for camera in cameras: id = camera.getId() type = camera.getTypeString() string += " Cam%s:\t%s\n" % (id, type) string += "\n" return string def set_handlers(self): self.task_mgr.add(self.connection_polling, "Poll new connections", -39) self.task_mgr.add(self.reader_polling, "Poll reader", -40) self.task_mgr.add(self.disconnection_polling, "PollDisconnections", -41) def connection_polling(self, taskdata): if self.cListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConn = PointerToConnection() if self.cListener.getNewConnection(rendezvous, netAddress, newConn): conn = newConn.p() self.cReader.addConnection(conn) # Begin reading connection conn_id = self.client_counter logging.info("New Connection from ip:%s, conn:%s" % (conn.getAddress(), conn_id)) self.connection_map[conn_id] = conn self.client_counter += 1 message = eVV_ACK_OK(self.ip, self.port, conn_id) self.sendMessage(message, conn) return Task.cont def reader_polling(self, taskdata): if self.cReader.dataAvailable(): datagram = NetDatagram( ) # catch the incoming data in this instance # Check the return value; if we were threaded, someone else could have # snagged this data before we did if self.cReader.getData(datagram): self.read_buffer = self.read_buffer + datagram.getMessage() while (True): if self.read_state == 0: if len(self.read_buffer) >= self.packet.header_length: bytes_consumed = self.packet.header_length self.packet.header = self.read_buffer[:bytes_consumed] self.read_body_length = self.packet.decode_header() self.read_buffer = self.read_buffer[bytes_consumed:] self.read_state = 1 else: break if self.read_state == 1: if len(self.read_buffer) >= self.read_body_length: bytes_consumed = self.read_body_length self.packet.data = self.read_buffer[:bytes_consumed] self.packet.offset = 0 self.read_body_length = 0 self.read_buffer = self.read_buffer[bytes_consumed:] self.read_state = 0 self.new_data_callback(self.packet) else: break return Task.cont def new_data_callback(self, packet): packet = copy.deepcopy(packet) message_type = packet.get_int() conn_id = packet.get_int() if message_type == VP_SESSION: conn = self.connection_map[conn_id] type = packet.get_char() pipeline = packet.get_char() logging.debug("Received VP_SESSION message from conn:%s, " \ "type=%s, pipeline=%s" %(conn_id, VP_TYPE[type], PIPELINE[pipeline])) self.newVPSession(conn, type, pipeline, conn_id) elif message_type == SYNC_SESSION: vv_id = packet.get_int() self.vv_id = vv_id string = self.generateInfoString() self.info_label.setText(string) conn = self.connection_map[conn_id] logging.debug("Received SYNC_SESSION message from conn:%s" % conn_id) self.newSyncSession(conn, conn_id, vv_id) logging.info("Sync client connected") elif message_type == VP_REQ_CAM_LIST: logging.debug("Received VP_REQ_CAM_LIST message from conn:%s" % conn_id) cameras = self.cam_mgr.getCameras() pipeline = self.activeSessions[conn_id].getPipeline() camera_type = None if pipeline == STATIC_PIPELINE: camera_type = VP_STATIC_CAMERA elif pipeline == PTZ_PIPELINE: camera_type = VP_ACTIVE_CAMERA cam_list = [] for camera in cameras: if camera_type == camera.getType() and not camera.hasSession(): cam_list.append(camera.getId()) message = eVV_CAM_LIST(self.ip, self.port, cam_list) conn = self.connection_map[conn_id] logging.debug("Sent VV_CAM_LIST message to conn:%s" % conn_id) self.sendMessage(message, conn) elif message_type == VP_REQ_IMG: cam_id = packet.get_int() frequency = packet.get_char() width = packet.get_int() height = packet.get_int() jpeg = packet.get_bool() data = (frequency, width, height, jpeg) camera = self.cam_mgr.getCameraById(cam_id) logging.debug("Received VV_REQ_IMG message from conn:%s" % conn_id) if camera and not camera.hasSession(): session = self.activeSessions[conn_id] session.addCamera(cam_id) camera.setSession(session, VP_BASIC, self.ip, self.port, data) else: if conn_id in self.activeSessions: self.activeSessions[conn_id].newMessage(message_type, packet) def newVPSession(self, conn, type, pipeline, conn_id): if type == VP_ADVANCED: camera_type = -1 if pipeline == STATIC_PIPELINE: camera_type = STATIC_CAMERA ## Change this to use a different static camera class elif pipeline == PTZ_PIPELINE: camera_type = ACTIVE_CAMERA if camera_type != -1: cam = self.cam_mgr.getAvailableCamera(camera_type) if cam: session = VPSession(conn_id, conn, self, VP, pipeline) session.addCamera(cam.getId()) self.activeSessions[conn_id] = session message = eVV_VP_ACK_OK(self.ip, self.port, cam.getId()) logging.debug("Sent VV_VP_ACK_OK message to conn:%s" % conn_id) self.sendMessage(message, conn) cam.setSession(session, type, self.ip, self.port) else: message = eVV_VP_ACK_FAILED(self.ip, self.port) logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" % conn_id) self.sendMessage(message, conn) else: message = eVV_VP_ACK_FAILED(self.ip, self.port) logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" % conn_id) self.sendMessage(message, conn) def newSyncSession(self, conn, conn_id, vv_id): session = SyncSession(conn_id, conn, self, SYNC) self.sync.setSession(session, vv_id, self.ip, self.port) self.activeSessions[conn_id] = session message = eVV_SYNC_ACK(self.ip, self.port, vv_id) logging.debug("Sent VV_SYNC_ACK message to conn:%s" % conn_id) self.sendMessage(message, conn) def sendMessage(self, message, conn): self.cWriter.send(message, conn) def disconnection_polling(self, taskdata): if (self.cManager.resetConnectionAvailable()): connectionPointer = PointerToConnection() self.cManager.getResetConnection(connectionPointer) lostConnection = connectionPointer.p() for session in self.activeSessions.values(): if session.conn == lostConnection: logging.info("Lost Connection from ip:%s, conn:%s" % (session.client_address, session.conn_id)) conn_id = session.conn_id if session.getSessionType() == VP: cameras = session.getCameras() for cam_id in cameras: camera = self.cam_mgr.getCameraById(cam_id) camera.clearSession() del self.activeSessions[conn_id] del self.connection_map[conn_id] break self.cManager.closeConnection(lostConnection) return Task.cont def toggleInfo(self): if self.showing_info: self.info_label.hide() self.showing_info = False else: self.info_label.show() self.showing_info = True def exit(self): for connection in self.connection_map.values(): self.cReader.removeConnection(connection) self.cManager.closeConnection(self.tcpSocket) self.tcpSocket.getSocket().Close()
frameSize=(-0.8, 0.8, -0.4, 0.8), pos=(0, 0, 0)) Education2 = OnscreenText(text='About', pos=(0, 0.6), scale=0.1) Education = OnscreenText( text= 'Valence-shell electron-pair repulsion, or VSEPR theory, utilizes the\ntendency of valence shell electron pairs to repel each other. Allowing\nfor very accurate predictions about the shape of an atom.\n\nThis projects simulates these repulsive forces in order to provide an\ninteractive model of VSEPR theory. Feel free to mess around in the \nsimulation', pos=(0, 0.5), scale=0.05) Education3 = OnscreenText(text='How to Use', pos=(0, 0), scale=0.1) Education4 = OnscreenText( text= 'Use the buttons on the top left to create and remove electron pairs\nWASD to move around\n+ and - to zoom in and out', pos=(0, -0.1), scale=0.05) myFrame.hide() Education.hide() Education2.hide() Education3.hide() Education4.hide() # Create an accumulator to track the time since the sim # has been running deltaTimeAccumulator = 0.0 # This stepSize makes the simulation run at 100 frames per second stepSize = 1.0 / 100.0 # This keeps track of the angle of the camera elevation = 0 strafe = 0 #how far the electron are from central atom distance = 9 #how fast the electrons move speed = 30
class World(DirectObject): def __init__(self): # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball in Maze", style=1, fg=(1,1,1,1), pos=(0.7,-0.95), scale = .07) self.instructions = OnscreenText(text="Press Esc to exit.", pos = (-1.3, .95), fg=(1,1,1,1), align = TextNode.ALeft, scale = .05) base.setBackgroundColor(0,0,0) self.central_msg = OnscreenText(text="", pos = (0, 0), fg=(1, 1, 0, 1), scale = .1 ) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Most times, you want collisions to be tested against invisible geometry # rather than every polygon. This is because testing against every polygon # in the scene is usually too slow. You can have simplified or approximate # geometry for the solids and still get good results. # # Sometimes you'll want to create and position your own collision solids in # code, but it's often easier to have them built automatically. This can be # done by adding special tags into an egg file. Check maze.egg and ball.egg # and look for lines starting with <Collide>. The part is brackets tells # Panda exactly what to do. Polyset means to use the polygons in that group # as solids, while Sphere tells panda to make a collision sphere around them # Keep means to keep the polygons in the group as visable geometry (good # for the ball, not for the triggers), and descend means to make sure that # the settings are applied to any subgroups. # # Once we have the collision tags in the models, we can get to them using # NodePath's find command # Find the collision node named wall_collide self.walls = self.maze.find("**/wall_collide") # Collision objects are sorted using BitMasks. BitMasks are ordinary numbers # with extra methods for working with them as binary bits. Every collision # solid has both a from mask and an into mask. Before Panda tests two # objects, it checks to make sure that the from and into collision masks # have at least one bit in common. That way things that shouldn't interact # won't. Normal model nodes have collision masks as well. By default they # are set to bit 20. If you want to collide against actual visable polygons, # set a from collide mask to include bit 20 # # For this example, we will make everything we want the ball to collide with # include bit 0 self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # CollisionNodes are usually invisible but can be shown. Uncomment the next # line to see the collision walls # self.walls.show() # We will now find the triggers for the holes and set their masks to 0 as # well. We also set their names to make them easier to identify during # collisions self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTrigger") self.loseTriggers.append(trigger) # Uncomment this line to see the triggers # trigger.show() # Ground_collide is a single polygon on the same plane as the ground in the # maze. We will use a ray to collide with it so that we will know exactly # what height to put the ball at every frame. Since this is not something # that we want the ball itself to collide with, it has a different # bitmask. self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # Find the collison sphere for the ball which was created in the egg file # Notice that it has a from collision mask of bit 0, and an into collison # mask of no bits. This means that the ball can only cause collisions, not # be collided into self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) # No we create a ray to start above the ball and cast down. This is to # Determine the height the ball should be at and the angle the floor is # tilting. We could have used the sphere around the ball itself, but it # would not be as reliable self.ballGroundRay = CollisionRay() # Create the ray self.ballGroundRay.setOrigin(0,0,10) # Set its origin self.ballGroundRay.setDirection(0,0,-1) # And its direction # Collision solids go in CollisionNode self.ballGroundCol = CollisionNode('groundRay') # Create and name the node self.ballGroundCol.addSolid(self.ballGroundRay) # Add the ray self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) # Set its bitmasks self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # Attach the node to the ballRoot so that the ray is relative to the ball # (it will always be 10 feet over the ball and point down) self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # Uncomment this line to see the ray # self.ballGroundColNp.show() # Finally, we create a CollisionTraverser. CollisionTraversers are what # do the job of calculating collisions self.cTrav = CollisionTraverser() # Collision traverservs tell collision handlers about collisions, and then # the handler decides what to do with the information. We are using a # CollisionHandlerQueue, which simply creates a list of all of the # collisions in a given pass. There are more sophisticated handlers like # one that sends events and another that tries to keep collided objects # apart, but the results are often better with a simple queue self.cHandler = CollisionHandlerQueue() # Now we add the collision nodes that can create a collision to the # traverser. The traverser will compare these to all others nodes in the # scene. There is a limit of 32 CollisionNodes per traverser # We add the collider, and the handler to use as a pair self.cTrav.addCollider(self.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. # self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1,1,1,1)) m.setShininess(96) self.ball.setMaterial(m, 1) # Finally, we call start for more initialization self.start() def start(self): # The maze model also has a locator in it for where to start the ball # To access it we use the find command startPos = self.maze.find("**/start").getPos() self.ballRoot.setPos(startPos) # Set the ball in the starting position self.ballV = Vec3(0,0,0) # Initial velocity is 0 self.accelV = Vec3(0,0,0) # Initial acceleration is 0 # For a traverser to actually do collisions, you need to call # traverser.traverse() on a part of the scene. Fortunatly, base has a # task that does this for the entire scene once a frame. This sets up our # traverser as the one to be called automatically base.cTrav = self.cTrav # Create the movement task, but first make sure it is not already running taskMgr.remove("rollTask") self.mainLoop = taskMgr.add(self.rollTask, "rollTask") self.mainLoop.last = 0 # This function handles the collision between the ray and the ground # Information about the interaction is passed in colEntry def groundCollideHandler(self, colEntry): # Set the ball to the appropriate Z value for it to be exactly on the ground newZ = colEntry.getSurfacePoint(render).getZ() self.ballRoot.setZ(newZ+.4) # Find the acceleration direction. First the surface normal is crossed with # the up vector to get a vector perpendicular to the slope norm = colEntry.getSurfaceNormal(render) accelSide = norm.cross(UP) # Then that vector is crossed with the surface normal to get a vector that # points down the slope. By getting the acceleration in 3D like this rather # than in 2D, we reduce the amount of error per-frame, reducing jitter self.accelV = norm.cross(accelSide) # This function handles the collision between the ball and a wall def wallCollideHandler(self, colEntry): # First we calculate some numbers we need to do a reflection norm = colEntry.getSurfaceNormal(render) * -1 # The normal of the wall curSpeed = self.ballV.length() # The current speed inVec = self.ballV / curSpeed # The direction of travel velAngle = norm.dot(inVec) # Angle of incidance hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos() hitDir.normalize() hitAngle = norm.dot(hitDir) # The angle between the ball and the normal # Ignore the collision if the ball is either moving away from the wall # already (so that we don't accidentally send it back into the wall) # and ignore it if the collision isn't dead-on (to avoid getting caught on # corners) if velAngle > 0 and hitAngle > .995: # Standard reflection equation reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec # This makes the velocity half of what it was if the hit was dead-on # and nearly exactly what it was if this is a glancing blow self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5)) # Since we have a collision, the ball is already a little bit buried in # the wall. This calculates a vector needed to move it so that it is # exactly touching the wall disp = (colEntry.getSurfacePoint(render) - colEntry.getInteriorPoint(render)) newPos = self.ballRoot.getPos() + disp self.ballRoot.setPos(newPos) # This is the task that deals with making everything interactive def rollTask(self, task): # Standard technique for finding the amount of time since the last frame dt = task.time - task.last task.last = task.time # If dt is large, then there has been a # hiccup that could cause the ball # to leave the field if this functions runs, so ignore the frame if dt > .2: return Task.cont # The collision handler collects the collisions. We dispatch which function # to handle the collision based on the name of what was collided into for i in range(self.cHandler.getNumEntries()): entry = self.cHandler.getEntry(i) name = entry.getIntoNode().getName() if name == "wall_collide": self.wallCollideHandler(entry) elif name == "ground_collide": self.groundCollideHandler(entry) elif name == "loseTrigger": self.loseGame(entry) # Read the mouse position and tilt the maze accordingly if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() # get the mouse position self.maze.setP(mpos.getY() * -10) self.maze.setR(mpos.getX() * 10) # Finally, we move the ball # Update the velocity based on acceleration self.ballV += self.accelV * dt * ACCEL # Clamp the velocity to the maximum speed if self.ballV.lengthSquared() > MAX_SPEED_SQ: self.ballV.normalize() self.ballV *= MAX_SPEED # Update the position based on the velocity self.ballRoot.setPos(self.ballRoot.getPos() + (self.ballV * dt)) # This block of code rotates the ball. It uses something called a quaternion # to rotate the ball around an arbitrary axis. That axis perpendicular to # the balls rotation, and the amount has to do with the size of the ball # This is multiplied on the previous rotation to incrimentally turn it. prevRot = LRotationf(self.ball.getQuat()) axis = UP.cross(self.ballV) newRot = LRotationf(axis, 45.5 * dt * self.ballV.length()) self.ball.setQuat(prevRot * newRot) return Task.cont # Continue the task indefinitely def show_message(self, message=''): if message: self.central_msg.setText(message) self.central_msg.show() else: self.central_msg.hide() # If the ball hits a hole trigger, then it should fall in the hole. # This is faked rather than dealing with the actual physics of it. def loseGame(self, entry): # The triggers are set up so that the center of the ball should move to the # collision point to be in the hole toPos = entry.getInteriorPoint(render) taskMgr.remove('rollTask') # Stop the maze task # Move the ball into the hole over a short sequence of time. Then wait a # second and call start to reset the game Sequence( Parallel( LerpFunc(self.ballRoot.setX, fromData = self.ballRoot.getX(), toData = toPos.getX(), duration = .1), LerpFunc(self.ballRoot.setY, fromData = self.ballRoot.getY(), toData = toPos.getY(), duration = .1), LerpFunc(self.ballRoot.setZ, fromData = self.ballRoot.getZ(), toData = self.ballRoot.getZ() - .9, duration = .2)), Func(self.show_message, "Try Again!"), Wait(1), Func(self.show_message, ""), Func(self.start)).start()
class DistributedToon(DistributedSmoothNode): def __init__(self, cr): self.legsAnimDict = {'right-hand-start': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_right-hand-start.bam', 'firehose': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_firehose.bam', 'rotateL-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_rotateL-putt.bam', 'slip-forward': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_slip-forward.bam', 'catch-eatnrun': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_eatnrun.bam', 'tickle': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_tickle.bam', 'water-gun': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_water-gun.bam', 'leverNeutral': 'phase_10/models/char/tt_a_chr_dgs_shorts_legs_leverNeutral.bam', 'swim': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_swim.bam', 'catch-run': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_gamerun.bam', 'sad-neutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_sad-neutral.bam', 'pet-loop': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_petloop.bam', 'jump-squat': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_jump-zstart.bam', 'wave': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_wave.bam', 'reel-neutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_reelneutral.bam', 'pole-neutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_poleneutral.bam', 'bank': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_jellybeanJar.bam', 'scientistGame': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_scientistGame.bam', 'right-hand': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_right-hand.bam', 'lookloop-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_lookloop-putt.bam', 'victory': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_victory-dance.bam', 'lose': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_lose.bam', 'cringe': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_cringe.bam', 'right': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_right.bam', 'headdown-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_headdown-putt.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_conked.bam', 'jump': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_jump.bam', 'into-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_into-putt.bam', 'fish-end': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_fishEND.bam', 'running-jump-land': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_leap_zend.bam', 'shrug': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_shrug.bam', 'sprinkle-dust': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_sprinkle-dust.bam', 'hold-bottle': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_hold-bottle.bam', 'takePhone': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_takePhone.bam', 'melt': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_melt.bam', 'pet-start': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_petin.bam', 'look-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_look-putt.bam', 'loop-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_loop-putt.bam', 'good-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_good-putt.bam', 'juggle': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_juggle.bam', 'run': 'phase_3/models/char/tt_a_chr_dgs_shorts_legs_run.bam', 'pushbutton': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_press-button.bam', 'sidestep-right': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_jump-back-right.bam', 'water': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_water.bam', 'right-point-start': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_right-point-start.bam', 'bad-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_bad-putt.bam', 'struggle': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_struggle.bam', 'running-jump': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_running-jump.bam', 'callPet': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_callPet.bam', 'throw': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_pie-throw.bam', 'catch-eatneutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_eat_neutral.bam', 'tug-o-war': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_tug-o-war.bam', 'bow': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_bow.bam', 'swing': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_swing.bam', 'climb': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_climb.bam', 'scientistWork': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_scientistWork.bam', 'think': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_think.bam', 'catch-intro-throw': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_gameThrow.bam', 'walk': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_walk.bam', 'down': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_down.bam', 'pole': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_pole.bam', 'periscope': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_periscope.bam', 'duck': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_duck.bam', 'curtsy': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_curtsy.bam', 'jump-land': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_jump-zend.bam', 'loop-dig': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_loop_dig.bam', 'angry': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_angry.bam', 'bored': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_bored.bam', 'swing-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_swing-putt.bam', 'pet-end': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_petend.bam', 'spit': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_spit.bam', 'right-point': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_right-point.bam', 'start-dig': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_into_dig.bam', 'castlong': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_castlong.bam', 'confused': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_confused.bam', 'neutral': 'phase_3/models/char/tt_a_chr_dgs_shorts_legs_neutral.bam', 'jump-idle': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_jump-zhang.bam', 'reel': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_reel.bam', 'slip-backward': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_slip-backward.bam', 'sound': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_shout.bam', 'sidestep-left': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_sidestep-left.bam', 'up': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_up.bam', 'fish-again': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_fishAGAIN.bam', 'cast': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_cast.bam', 'phoneBack': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_phoneBack.bam', 'phoneNeutral': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_phoneNeutral.bam', 'scientistJealous': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_scientistJealous.bam', 'battlecast': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_fish.bam', 'sit-start': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_intoSit.bam', 'toss': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_toss.bam', 'happy-dance': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_happy-dance.bam', 'running-jump-squat': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_leap_zstart.bam', 'teleport': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_teleport.bam', 'sit': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_sit.bam', 'sad-walk': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_losewalk.bam', 'give-props-start': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_give-props-start.bam', 'book': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_book.bam', 'running-jump-idle': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_leap_zhang.bam', 'scientistEmcee': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_scientistEmcee.bam', 'leverPull': 'phase_10/models/char/tt_a_chr_dgs_shorts_legs_leverPull.bam', 'tutorial-neutral': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_tutorial-neutral.bam', 'badloop-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_badloop-putt.bam', 'give-props': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_give-props.bam', 'hold-magnet': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_hold-magnet.bam', 'hypnotize': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_hypnotize.bam', 'left-point': 'phase_3.5/models/char/tt_a_chr_dgs_shorts_legs_left-point.bam', 'leverReach': 'phase_10/models/char/tt_a_chr_dgs_shorts_legs_leverReach.bam', 'feedPet': 'phase_5.5/models/char/tt_a_chr_dgs_shorts_legs_feedPet.bam', 'reel-H': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_reelH.bam', 'applause': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_applause.bam', 'smooch': 'phase_5/models/char/tt_a_chr_dgs_shorts_legs_smooch.bam', 'rotateR-putt': 'phase_6/models/char/tt_a_chr_dgs_shorts_legs_rotateR-putt.bam', 'fish-neutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_fishneutral.bam', 'push': 'phase_9/models/char/tt_a_chr_dgs_shorts_legs_push.bam', 'catch-neutral': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_gameneutral.bam', 'left': 'phase_4/models/char/tt_a_chr_dgs_shorts_legs_left.bam'} self.torsoAnimDict = {'right-hand-start': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_right-hand-start.bam', 'firehose': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_firehose.bam', 'rotateL-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_rotateL-putt.bam', 'slip-forward': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_slip-forward.bam', 'catch-eatnrun': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_eatnrun.bam', 'tickle': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_tickle.bam', 'water-gun': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_water-gun.bam', 'leverNeutral': 'phase_10/models/char/tt_a_chr_dgl_shorts_torso_leverNeutral.bam', 'swim': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_swim.bam', 'catch-run': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_gamerun.bam', 'sad-neutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_sad-neutral.bam', 'pet-loop': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_petloop.bam', 'jump-squat': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_jump-zstart.bam', 'wave': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_wave.bam', 'reel-neutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_reelneutral.bam', 'pole-neutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_poleneutral.bam', 'bank': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_jellybeanJar.bam', 'scientistGame': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_scientistGame.bam', 'right-hand': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_right-hand.bam', 'lookloop-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_lookloop-putt.bam', 'victory': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_victory-dance.bam', 'lose': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_lose.bam', 'cringe': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_cringe.bam', 'right': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_right.bam', 'headdown-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_headdown-putt.bam', 'conked': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_conked.bam', 'jump': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_jump.bam', 'into-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_into-putt.bam', 'fish-end': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_fishEND.bam', 'running-jump-land': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_leap_zend.bam', 'shrug': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_shrug.bam', 'sprinkle-dust': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_sprinkle-dust.bam', 'hold-bottle': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_hold-bottle.bam', 'takePhone': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_takePhone.bam', 'melt': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_melt.bam', 'pet-start': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_petin.bam', 'look-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_look-putt.bam', 'loop-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_loop-putt.bam', 'good-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_good-putt.bam', 'juggle': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_juggle.bam', 'run': 'phase_3/models/char/tt_a_chr_dgl_shorts_torso_run.bam', 'pushbutton': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_press-button.bam', 'sidestep-right': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_jump-back-right.bam', 'water': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_water.bam', 'right-point-start': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_right-point-start.bam', 'bad-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_bad-putt.bam', 'struggle': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_struggle.bam', 'running-jump': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_running-jump.bam', 'callPet': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_callPet.bam', 'throw': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_pie-throw.bam', 'catch-eatneutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_eat_neutral.bam', 'tug-o-war': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_tug-o-war.bam', 'bow': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_bow.bam', 'swing': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_swing.bam', 'climb': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_climb.bam', 'scientistWork': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_scientistWork.bam', 'think': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_think.bam', 'catch-intro-throw': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_gameThrow.bam', 'walk': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_walk.bam', 'down': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_down.bam', 'pole': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_pole.bam', 'periscope': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_periscope.bam', 'duck': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_duck.bam', 'curtsy': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_curtsy.bam', 'jump-land': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_jump-zend.bam', 'loop-dig': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_loop_dig.bam', 'angry': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_angry.bam', 'bored': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_bored.bam', 'swing-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_swing-putt.bam', 'pet-end': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_petend.bam', 'spit': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_spit.bam', 'right-point': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_right-point.bam', 'start-dig': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_into_dig.bam', 'castlong': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_castlong.bam', 'confused': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_confused.bam', 'neutral': 'phase_3/models/char/tt_a_chr_dgl_shorts_torso_neutral.bam', 'jump-idle': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_jump-zhang.bam', 'reel': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_reel.bam', 'slip-backward': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_slip-backward.bam', 'sound': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_shout.bam', 'sidestep-left': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_sidestep-left.bam', 'up': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_up.bam', 'fish-again': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_fishAGAIN.bam', 'cast': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_cast.bam', 'phoneBack': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_phoneBack.bam', 'phoneNeutral': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_phoneNeutral.bam', 'scientistJealous': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_scientistJealous.bam', 'battlecast': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_fish.bam', 'sit-start': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_intoSit.bam', 'toss': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_toss.bam', 'happy-dance': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_happy-dance.bam', 'running-jump-squat': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_leap_zstart.bam', 'teleport': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_teleport.bam', 'sit': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_sit.bam', 'sad-walk': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_losewalk.bam', 'give-props-start': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_give-props-start.bam', 'book': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_book.bam', 'running-jump-idle': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_leap_zhang.bam', 'scientistEmcee': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_scientistEmcee.bam', 'leverPull': 'phase_10/models/char/tt_a_chr_dgl_shorts_torso_leverPull.bam', 'tutorial-neutral': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_tutorial-neutral.bam', 'badloop-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_badloop-putt.bam', 'give-props': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_give-props.bam', 'hold-magnet': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_hold-magnet.bam', 'hypnotize': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_hypnotize.bam', 'left-point': 'phase_3.5/models/char/tt_a_chr_dgl_shorts_torso_left-point.bam', 'leverReach': 'phase_10/models/char/tt_a_chr_dgl_shorts_torso_leverReach.bam', 'feedPet': 'phase_5.5/models/char/tt_a_chr_dgl_shorts_torso_feedPet.bam', 'reel-H': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_reelH.bam', 'applause': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_applause.bam', 'smooch': 'phase_5/models/char/tt_a_chr_dgl_shorts_torso_smooch.bam', 'rotateR-putt': 'phase_6/models/char/tt_a_chr_dgl_shorts_torso_rotateR-putt.bam', 'fish-neutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_fishneutral.bam', 'push': 'phase_9/models/char/tt_a_chr_dgl_shorts_torso_push.bam', 'catch-neutral': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_gameneutral.bam', 'left': 'phase_4/models/char/tt_a_chr_dgl_shorts_torso_left.bam'} DistributedSmoothNode.__init__(self,cr) NodePath.__init__(self, 'avatar') self.ToonSpeedFactor = 1.25 self.ToonForwardSpeed = 16.0 * self.ToonSpeedFactor self.ToonJumpForce = 24.0 self.ToonReverseSpeed = 8.0 * self.ToonSpeedFactor self.ToonRotateSpeed = 80.0 * self.ToonSpeedFactor self.moveKeyList = [ 'arrow_left', 'arrow_right', 'arrow_up', 'arrow_down' ] self.moveKeys = {} for key in self.moveKeyList: self.moveKeys[key] = False self.accept(key, self.moveKeyStateChanged, extraArgs = [key, True]) self.accept(key + '-up', self.moveKeyStateChanged, extraArgs = [key, False]) self.access = 0 self.avColor = (1, 1, 1) self.legs = loader.loadModel('phase_3/models/char/tt_a_chr_dgs_shorts_legs_1000.bam') otherParts = self.legs.findAllMatches('**/boots*')+self.legs.findAllMatches('**/shoes') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() self.torso = loader.loadModel('phase_3/models/char/tt_a_chr_dgl_shorts_torso_1000.bam') self.headList = ['cat', 'duck', 'monkey', 'horse', 'rabbit', 'bear'] self.bear = loader.loadModel('phase_3/models/char/bear-heads-1000.bam') otherParts = self.bear.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.bear.find('**/*muzzle*neutral') otherParts = self.bear.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.rabbit = loader.loadModel('phase_3/models/char/rabbit-heads-1000.bam') otherParts = self.rabbit.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.rabbit.find('**/*muzzle*neutral') otherParts = self.rabbit.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.monkey = loader.loadModel('phase_3/models/char/monkey-heads-1000.bam') otherParts = self.monkey.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.monkey.find('**/*muzzle*neutral') otherParts = self.monkey.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.duck = loader.loadModel('phase_3/models/char/duck-heads-1000.bam') otherParts = self.duck.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.duck.find('**/*muzzle*neutral') otherParts = self.duck.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.cat = loader.loadModel('phase_3/models/char/cat-heads-1000.bam') otherParts = self.cat.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.cat.find('**/*muzzle*neutral') otherParts = self.cat.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.horse = loader.loadModel('phase_3/models/char/horse-heads-1000.bam') otherParts = self.horse.findAllMatches('**/*long*') for partNum in range(0, otherParts.getNumPaths()): otherParts.getPath(partNum).removeNode() ntrlMuzzle = self.horse.find('**/*muzzle*neutral') otherParts = self.horse.findAllMatches('**/*muzzle*') for partNum in range(0, otherParts.getNumPaths()): part = otherParts.getPath(partNum) if part != ntrlMuzzle: otherParts.getPath(partNum).removeNode() self.model = Actor({'torso':self.torso, 'legs':self.legs}, {'torso':self.torsoAnimDict, 'legs':self.legsAnimDict}) self.head_np = self.model.find('**/def_head') self.bear.reparentTo(self.head_np) self.rabbit.reparentTo(self.head_np) self.monkey.reparentTo(self.head_np) self.duck.reparentTo(self.head_np) self.cat.reparentTo(self.head_np) self.horse.reparentTo(self.head_np) self.cat.hide() self.bear.hide() self.rabbit.hide() self.monkey.hide() self.duck.hide() self.horse.hide() self.model.attach('torso', 'legs', 'joint_hips') self.model.reparentTo(self) cs = CollisionSphere(0, 0, 0, 1) cnode = CollisionNode('cnode') cnode.addSolid(cs) self.cnp = self.attachNewNode(cnode) self.still = True self.isMoving = False self.standing = 1 self.standTime = 0 self.previousPos = 0 self.previousHpr = 0 self.tag = OnscreenText(scale=.30,font=loader.loadFont('phase_3/models/fonts/ImpressBT.ttf'),pos=(0,3.25),text='Toon',bg=(.9,.9,.9,.3),fg=(0,0,1,1),wordwrap=7,decal=True,parent=self.model) self.tag.setBillboardAxis(2) self.playground = loader.loadModel('phase_6/models/golf/golf_outdoor_zone.bam') self.playground.reparentTo(render) def moveKeyStateChanged(self, key, newState): self.moveKeys[key] = newState def setupLocalAvatar(self): self.cnp.setCollideMask(BitMask32(0)) self.cnp.node().setFromCollideMask(BitMask32(1)) pusher = CollisionHandlerPusher() pusher.setInPattern("%in") pusher.addCollider(self.cnp, self) base.cTrav.addCollider(self.cnp, pusher) self.b_pose("walk",5) self.ButtonImage = loader.loadModel("phase_3/models/gui/quit_button.bam") self.ImgBtn22 = DirectButton(frameSize=None, text='Sit', image=(self.ButtonImage.find('**/QuitBtn_UP'), \ self.ButtonImage.find('**/QuitBtn_DN'), self.ButtonImage.find('**/QuitBtn_RLVR')), relief=None, command=self.b_setSit, text_pos=(0, -0.015), \ geom=None, pad=(0.01, 0.01), suppressKeys=0, pos = (-.05,-0,.95), text_scale=0.059, borderWidth=(0.13, 0.01), scale=.7) self.ImgBtn22.bind(DGG.B3PRESS, self.ImgBtn22.editStart) self.ImgBtn22.bind(DGG.B3RELEASE, self.ImgBtn22.editStop) """self.ImgBtn22 = DirectButton(frameSize=None, text='Create Bot', image=(self.ButtonImage.find('**/QuitBtn_UP'), \ self.ButtonImage.find('**/QuitBtn_DN'), self.ButtonImage.find('**/QuitBtn_RLVR')), relief=None, command=self.b_makeBot, text_pos=(0, -0.015), \ geom=None, pad=(0.01, 0.01), suppressKeys=0, pos = (-.95,-0,.95), text_scale=0.059, borderWidth=(0.13, 0.01), scale=.7) self.ImgBtn22.bind(DGG.B3PRESS, self.ImgBtn22.editStart) self.ImgBtn22.bind(DGG.B3RELEASE, self.ImgBtn22.editStop)""" self.b_setSpecies('cat') self.offset = 3.2375 self.b = DirectEntry(text = "" ,scale=.05,command=self.b_sendMsg, initialText="Chatstuff", numLines = 2,focus=1,focusInCommand=self.clearText) self.headRNG = random.choice(self.headList) self.ImgBtn22 = DirectButton(frameSize=None, text='Random Species', image=(self.ButtonImage.find('**/QuitBtn_UP'), \ self.ButtonImage.find('**/QuitBtn_DN'), self.ButtonImage.find('**/QuitBtn_RLVR')), relief=None, command=self.b_setSpecies, extraArgs=[self.headRNG], text_pos=(0, -0.015), \ geom=None, pad=(0.01, 0.01), suppressKeys=0, pos = (-.05,-0,-.95), text_scale=0.059, borderWidth=(0.13, 0.01), scale=.7) self.ImgBtn22.bind(DGG.B3PRESS, self.ImgBtn22.editStart) self.ImgBtn22.bind(DGG.B3RELEASE, self.ImgBtn22.editStop) base.camera.reparentTo(base.w.av) base.camera.setPos(0, -10.0 - self.offset, self.offset) base.camera.hide() self.moveTask = taskMgr.add(self.moveAvatar, 'moveAvatar') base.w.av.startPosHprBroadcast() def clearText(self): self.b.enterText('') def sendMsg(self, textEntered): self.chatbubble = loader.loadModel('phase_3/models/props/chatbox.bam') self.chatbubble.reparentTo(self.model) self.chatbubble.setPos(0,0,3.5) self.chatbubble.setBillboardAxis(1) self.chatbubble.setScale(0.3) self.chatbubble.find('**/chatBalloon').setPos(0,0.05,0) self.chatbubble.find('**/chatBalloon').setSx(0.8) self.talk = OnscreenText(scale=.70,font=loader.loadFont('phase_3/models/fonts/ImpressBT.ttf'),pos=(0.9,3),text=textEntered,wordwrap=10,decal=True,parent=self.chatbubble,align=TextNode.ALeft) self.tag.hide() Sequence(Wait(5),Func(self.chatbubble.removeNode),Func(self.tag.show)).start() if textEntered == 'horse': self.b_setSpecies('horse') if textEntered == 'cat': self.b_setSpecies('cat') if textEntered == 'duck': self.b_setSpecies('duck') if textEntered == 'rabbit': self.b_setSpecies('rabbit') if textEntered == 'bear': self.b_setSpecies('bear') if textEntered == 'monkey': self.b_setSpecies('monkey') if textEntered == 'ssnow': #Server Snow print "Let it snow-- Later." if textEntered == 'gibAdmin': #gib admin pls base.w.access = 9999999 self.straccess = str(base.w.access) print "Your access is now "+ self.straccess +"." self.chatbubble.removeNode() self.tag.show() if textEntered == 'ceo' and base.w.access >= 699: self.b_spawnBoss('ceo') if textEntered == 'devroom' and base.w.access >= 100: base.w.changeAvZone(999) print "In Developer Room." try: room = int(textEntered) base.w.changeAvZone(room) roomStr = str(room) print "Went to room "+ roomStr +"" except ValueError: print "k" def d_sendMsg(self, msg): self.sendUpdate('sendMsg', [msg]) def b_sendMsg(self, msg): self.sendMsg(msg) self.d_sendMsg(msg) def spawnBoss(self, boss): print "Trying to spawn "+ boss +"" if boss == 'vp': vp = 'swag' print('placeholder') if boss == 'ceo': self.ceo = Actor({"head":"phase_12/models/char/bossbotBoss-head-zero.bam", \ "torso":"phase_12/models/char/bossbotBoss-torso-zero.bam", \ "legs":"phase_9/models/char/bossCog-legs-zero.bam"}, \ {"head":{"walk":"phase_9/models/char/bossCog-head-Bb_neutral.bam", \ "run":"phase_9/models/char/bossCog-head-Bb_neutral.bam"}, \ "torso":{"walk":"phase_9/models/char/bossCog-torso-Bb_neutral.bam", \ "run":"phase_9/models/char/bossCog-torso-Bb_neutral.bam"}, \ "legs":{"walk":"phase_9/models/char/bossCog-legs-Bb_neutral.bam", \ "run":"phase_9/models/char/bossCog-legs-Bb_neutral.bam"} \ }) self.ceo.attach("head", "torso", "joint34") self.ceo.attach("torso", "legs", "joint_legs") self.ceo.reparentTo(render) self.ceo.loop("run") self.mypos = self.model.getPos() self.ceo.setPos(self.mypos) def d_spawnBoss(self, boss): self.sendUpdate('spawnBoss', [boss]) def b_spawnBoss(self, boss): self.d_spawnBoss(boss) self.spawnBoss(boss) def makeBot(self): self.bot = self.model.copyTo(render) self.myPos = self.model.getPos() self.bot.setPos(self.myPos) def d_makeBot(self): self.sendUpdate('makeBot') def b_makeBot(self): self.makeBot() self.d_makeBot() def setSit(self): self.model.loop("sit") def d_setSit(self): self.sendUpdate('setSit') def b_setSit(self): self.d_setSit() self.setSit() def setSpecies(self, spcs): if spcs == 'horse': self.bear.hide() self.cat.hide() self.duck.hide() self.rabbit.hide() self.monkey.hide() self.horse.show() elif spcs == 'bear': self.horse.hide() self.cat.hide() self.duck.hide() self.rabbit.hide() self.monkey.hide() self.bear.show() elif spcs == 'cat': self.horse.hide() self.duck.hide() self.rabbit.hide() self.bear.hide() self.monkey.hide() self.cat.show() elif spcs == 'monkey': self.horse.hide() self.cat.hide() self.duck.hide() self.rabbit.hide() self.bear.hide() self.monkey.show() elif spcs == 'rabbit': self.horse.hide() self.cat.hide() self.duck.hide() self.monkey.hide() self.bear.hide() self.rabbit.show() elif spcs == 'duck': self.horse.hide() self.cat.hide() self.rabbit.hide() self.monkey.hide() self.bear.hide() self.duck.show() else: print "Invalid species" print "Now a "+ spcs +"" def d_setSpecies(self, spcs): self.sendUpdate('setSpecies', [spcs]) print "Now a "+ spcs +"" def b_setSpecies(self, spcs): self.setSpecies(spcs) self.d_setSpecies(spcs) def updateName(self, textEntered): self.tag.setText(textEntered) def d_updateName(self, textEntered): self.sendUpdate('updateName', [textEntered]) def b_updateName(self, textEntered): self.updateName(textEntered) self.d_updateName(textEntered) def setStanding(self, stand): self.standing = stand if self.standing == 1: self.still = 0 def d_setStanding(self, stand): self.sendUpdate('setStanding', [stand]) def b_setStanding(self, stand): self.setStanding(stand) self.d_setStanding(stand) def getStanding(self): return self.standing def doSmoothTask(self, task): now = globalClock.getFrameTime() if(self.standing == 0): if (self.getPos() == self.previousPos) and (self.getHpr() == self.previousHpr): if (self.still == True): if (now > self.standTime + 0.3): self.b_stop() self.b_pose("walk",5) self.b_setStanding(1) else: self.standTime = now self.still = True else: self.still = False self.previousPos = self.getPos() self.previousHpr = self.getHpr() self.smoothPosition() return cont def loop(self, animName): self.model.loop(animName) def d_loop(self, animName): self.sendUpdate('loop', [animName]) def b_loop(self, animName): self.model.loop(animName) self.d_loop(animName) def stop(self): self.model.stop() def d_stop(self): self.sendUpdate('stop',[]) def b_stop(self): self.stop() self.d_stop() def pose(self, animName, frame=1): self.model.pose(animName, frame) def d_pose(self, animName, frame=1): self.sendUpdate('pose',[animName,frame]) def b_pose(self, animName, frame=1): self.pose(animName,frame) self.d_pose(animName,frame) def generate(self): DistributedSmoothNode.generate(self) self.activateSmoothing(True, False) self.startSmooth() def announceGenerate(self): DistributedSmoothNode.announceGenerate(self) self.reparentTo(render) self.model.pose("walk",5) if(self.getStanding() == 0): self.b_loop("run") def disable(self): self.stopSmooth() self.detachNode() DistributedSmoothNode.disable(self) def delete(self): self.model = None DistributedSmoothNode.delete(self) def moveAvatar(self, task): wallBitmask = BitMask32(1) floorBitmask = BitMask32(2) base.cTrav = CollisionTraverser() def getAirborneHeight(): return offset + 0.025000000000000001 walkControls = GravityWalker(legacyLifter=True) walkControls.setWallBitMask(wallBitmask) walkControls.setFloorBitMask(floorBitmask) walkControls.setWalkSpeed(self.ToonForwardSpeed, self.ToonJumpForce, self.ToonReverseSpeed, self.ToonRotateSpeed) walkControls.initializeCollisions(base.cTrav, self.model, floorOffset=0.025, reach=4.0) walkControls.setAirborneHeightFunc(getAirborneHeight) walkControls.enableAvatarControls() self.model.physControls = walkControls dt = globalClock.getDt() if self.moveKeys['arrow_left']: base.w.av.setH(base.w.av, dt * self.ToonRotateSpeed) elif self.moveKeys['arrow_right']: base.w.av.setH(base.w.av, -dt * self.ToonRotateSpeed) if self.moveKeys['arrow_up']: base.w.av.setY(base.w.av, dt * self.ToonForwardSpeed) elif self.moveKeys['arrow_down']: base.w.av.setY(base.w.av, -dt * self.ToonReverseSpeed) return task.cont
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory('PartyCogActivityGui') def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = 'PartyCogActivityGui-SpamWarning' return def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None return def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel( 'phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar') self._victoryBalanceBar = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarBG') self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin('fixed', 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarOrange') self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin('fixed', 1) self._victoryBalanceBarOrange.setPos( PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale( PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceBarPie') self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin('fixed', 2) self._victoryBalanceBarPie.setX( PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY( PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ( PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale( PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find( '**/*tt_t_gui_pty_pieToss_balanceArrow') self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin('fixed', 2) self._victoryBalanceBarArrow.setPos( PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale( 1 / PartyGlobals.CogActivityBarPieScale) def _initControlGui(self): self._attackIvalName = 'PartyCogActivityGui-attackKeys' self._moveIvalName = 'PartyCogActivityGui-moveKeys' pieTossControls = loader.loadModel( 'phase_13/models/parties/tt_m_gui_pty_pieToss_controls') self._attackKeys = pieTossControls.find('**/*control*') self._moveKeys = pieTossControls.find('**/*arrow*') self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar( frameSize=(-h, h, -w, w), relief=DGG.GROOVE, frameColor=(0.9, 0.9, 0.9, 1.0), borderWidth=(0.01, 0.01), barColor=PartyGlobals.CogActivityColors[0], pos=PartyGlobals.CogActivityPowerMeterPos, hpr=(0.0, 0.0, -90.0)) self._piePowerMeter.setBin('fixed', 0) self._piePowerTitle = OnscreenText( text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter) self._piePowerTitle.setBin('fixed', 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText( text='0', pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True) self._scoreTitle = OnscreenText(text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ARight) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText( text=TTLocalizer.PartyCogGuiSpamWarning, scale=0.15, fg=(1.0, 1.0, 0, 1.0), shadow=(0, 0, 0, 0.62), mayChange=False, pos=(0, 0.33)) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score=0): self._scoreLabel['text'] = str(score) def resetPiePowerMeter(self): self._piePowerMeter['value'] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter['value'] = value def getPiePowerMeterValue(self): return self._piePowerMeter['value'] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence(ToontownIntervals.getPulseLargerIval( self._spamWarning, ''), Wait(PartyGlobals.CogActivitySpamWarningShowTime), Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsActive(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsActive(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) self._piePowerMeter['barColor'] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, 'trackCogs') def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i, cog, self.team) return task.cont def _updateVictoryBar(self): if not (hasattr(self, '_victoryBalanceBar') and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance / 6.0 self._victoryBalanceBarOrange.setScale( PartyGlobals.CogActivityBarStartScale + teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale, 1.0, 1.0) self._victoryBalanceBarPie.setX( PartyGlobals.CogActivityVictoryBarPiePos[0] + teamDistance * 10 * PartyGlobals.CogActivityBarPieUnitMove) self._victoryBalanceBarPie.setY( PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ( PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance > 0.0: self._victoryBalanceBarArrow.setColor( PartyGlobals.CogActivityColors[1]) elif teamDistance < 0.0: self._victoryBalanceBarArrow.setColor( PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0, 1.0, 1.0, 1.0)) def stopTrackingCogs(self): taskMgr.remove('trackCogs') def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._attackKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence(ToontownIntervals.getPulseLargerIval(self._moveKeys, '', scale=0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, '_attackKeys') and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, '_moveKeys') and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) self.base = self self.font = loader.loadFont('1.ttf') self.buttonget= base.loader.loadSfx("buttonget.mp3") self.buttondown= base.loader.loadSfx("buttondown.mp3") self.victorymusic= base.loader.loadSfx("victory.mp3") self.falsemusic= base.loader.loadSfx("false.mp3") self.jiechu1 = 0 self.jiechu2 = 0 self.down = 0 self.menuon = 0 # ESC退出 self.accept("escape", self.caidan) self.accept("q", self.victory) self.accept("w", self.false) # 背景 self.beijing = OnscreenImage( image='1.jpg', pos=(0, 0, 0.02), scale=(1.4, 1, 1.02)) # 开始游戏碰之前图片 self.a1 = OnscreenImage(image='buttontemp2.png', pos=(0.8, 0, -0.5), scale=(0.2, 0.1, 0.065)) self.a1.setTransparency(TransparencyAttrib.MAlpha) # 碰到开始游戏后显示的按钮 self.zjmkaishi = DirectButton(text=('', '', '', 'disabled'), image='button2.png', frameColor=(255, 255, 255, 0), image_scale=(1.8, 1, 0.6), pos=(0.8, 0, -0.5), scale=0.1, rolloverSound=self.buttonget,clickSound=self.buttondown, command=self.putdown) #(2, 1, 0.7) self.zjmkaishi.hide() self.b1 = OnscreenImage(image='buttontemp1.png', pos=(0.8, 0, -0.5), scale=(0.25, 0.1, 0.13)) self.b1.setTransparency(TransparencyAttrib.MAlpha) self.b1.hide() # 点击开始游戏后图片 self.c1 = OnscreenImage(image='buttontemp3.png', pos=(0.8, 0, -0.5), scale=(0.2, 0.1, 0.065)) self.c1.setTransparency(TransparencyAttrib.MAlpha) self.c1.hide() # 开始游戏显示的文字 self.textObjectstart1 = OnscreenText( text='开始游戏', pos=(0.8, -0.51, 0), scale=0.05, fg=(255, 255, 255, 1)) self.textObjectstart2 = OnscreenText( text='开始游戏', pos=(0.8, -0.51, 0), scale=0.055, fg=(255, 255, 255, 1)) self.textObjectstart2.hide() self.textObjectstart3 = OnscreenText( text='开始游戏', pos=(0.8, -0.51, 0), scale=0.06, fg=(255, 255, 255, 1)) self.textObjectstart3.hide() self.textObjectstart1.setFont(self.font) self.textObjectstart2.setFont(self.font) self.textObjectstart3.setFont(self.font) # 退出游戏碰之前图片 self.a2 = OnscreenImage(image='buttontemp2.png', pos=(0.8, 0, -0.7), scale=(0.2, 0.1, 0.065)) self.a2.setTransparency(TransparencyAttrib.MAlpha) # 碰到退出游戏后显示的按钮 self.zjmkaishi2 = DirectButton(text=('', '', '', 'disabled'), image='button2.png', frameColor=(255, 255, 255, 0), image_scale=(1.8, 1, 0.6), pos=(0.8, 0, -0.7), scale=0.1, command=self.quit, rolloverSound=self.buttonget,clickSound=self.buttondown) self.zjmkaishi2.hide() self.b2 = OnscreenImage(image='buttontemp1.png', pos=(0.8, 0, -0.7), scale=(0.25, 0.1, 0.13)) self.b2.setTransparency(TransparencyAttrib.MAlpha) self.b2.hide() # 点击退出游戏后图片 self.c2 = OnscreenImage(image='buttontemp3.png', pos=(0.8, 0, -0.7), scale=(0.2, 0.1, 0.071)) self.c2.setTransparency(TransparencyAttrib.MAlpha) self.c2.hide() # 退出游戏显示的文字 self.textObjectstart4 = OnscreenText( text='退出', pos=(0.8, -0.71, 0), scale=0.05, fg=(255, 255, 255, 1)) self.textObjectstart5 = OnscreenText( text='退出', pos=(0.8, -0.71, 0), scale=0.055, fg=(255, 255, 255, 1)) self.textObjectstart5.hide() self.textObjectstart6 = OnscreenText( text='退出', pos=(0.8, -0.71, 0), scale=0.06, fg=(255, 255, 255, 1)) self.textObjectstart6.hide() self.textObjectstart4.setFont(self.font) self.textObjectstart5.setFont(self.font) self.textObjectstart6.setFont(self.font) # ESC菜单 self.caidanjiemian = OnscreenImage( image='caidan.jpg', pos=(0, 0, 0), scale=(0.5, 0.1, 0.41)) self.caidanjiemian.hide() self.bangzhu1button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, 0.23), scale=0.1, command=self.putdown1, rolloverSound=self.buttonget,clickSound=self.buttondown) self.bangzhu1button.hide() self.bangzhu1 = OnscreenText(text='游戏帮助', pos=( 0, 0.21, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu1.setFont(self.font) self.bangzhu1.hide() self.bangzhu2button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, 0.03), scale=0.1, command=self.putdown2, rolloverSound=self.buttonget,clickSound=self.buttondown) self.bangzhu2button.hide() self.bangzhu2 = OnscreenText(text='继续游戏', pos=( 0, 0.01, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu2.setFont(self.font) self.bangzhu2.hide() self.bangzhu3button = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0, 0, -0.18), scale=0.1, command=self.putdown3, rolloverSound=self.buttonget,clickSound=self.buttondown) self.bangzhu3button.hide() self.bangzhu3 = OnscreenText(text='退出游戏', pos=( 0, -0.2, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhu3.setFont(self.font) self.bangzhu3.hide() self.bangzhujiemian = OnscreenImage( image='caidan.jpg', pos=(-0, 0, 0), scale=(1, 0.1, 0.81)) self.bangzhujiemian.hide() self.bangzhuxinxi = OnscreenText( text='coooooooooooooooool', pos=(0, 0, 0), scale=0.1) self.bangzhuxinxi.hide() self.bangzhuxinxibutton = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0.55, 0, -0.55), scale=0.1, command=self.help1, rolloverSound=self.buttonget,clickSound=self.buttondown) self.bangzhuxinxibutton.hide() self.bangzhuxinxi1 = OnscreenText( text='返回', pos=(0.55, -0.56, 0), scale=0.05, fg=(255, 255, 255, 1)) self.bangzhuxinxi1.setFont(self.font) self.bangzhuxinxi1.hide() # 游戏胜利 self.victorypic = OnscreenImage( image='victory.jpg', pos=(0, 0, 0.02), scale=(1.4, 1, 1.02)) self.victorypic.hide() # 游戏失败 self.falsepic = OnscreenImage( image='false.jpg', pos=(0, 0, 0.02), scale=(1.4, 1, 1.02)) self.falsepic.hide() self.rebornbutton = DirectButton(text=('', '', '', 'disabled'), image='button1.png', frameColor=(255, 255, 255, 0), image_scale=(2.2, 1, 0.7), pos=(0.75, 0, -0.75), scale=0.1, command=self.reborn, rolloverSound=self.buttonget,clickSound=self.buttondown) self.rebornbutton.hide() self.reborntext = OnscreenText( text='返回主菜单', pos=(0.75, -0.76, 0), scale=0.05, fg=(255, 255, 255, 1)) self.reborntext.setFont(self.font) self.reborntext.hide() #事件队列 taskMgr.add(self.example, 'MyTaskName') # 按下ESC触发 def caidan(self): if(self.menuon == 0): self.menuon = 1 self.caidanjiemian.show() self.bangzhu1button.show() self.bangzhu2button.show() self.bangzhu3button.show() self.bangzhu1.show() self.bangzhu2.show() self.bangzhu3.show() else: self.menuon = 0 self.caidanjiemian.hide() self.bangzhu1button.hide() self.bangzhu2button.hide() self.bangzhu3button.hide() self.bangzhu1.hide() self.bangzhu2.hide() self.bangzhu3.hide() self.bangzhujiemian.hide() self.bangzhuxinxi.hide() self.bangzhuxinxi1.hide() self.bangzhuxinxibutton.hide() # 无限循环 def example(self, task): mpos = base.mouseWatcherNode.getMouse() if mpos.getY() < -0.42 and mpos.getY() > -0.55 and mpos.getX() > 0.45 and mpos.getX() < 0.75: #print(mpos.getY()) self.jiechu1 = 1 elif mpos.getY() < -0.62 and mpos.getY() > -0.75 and mpos.getX() > 0.45 and mpos.getX() < 0.75: # print(mpos.getY()) self.jiechu2 = 1 else: self.jiechu1 = 0 self.jiechu2 = 0 if(self.jiechu1 == 1 and self.down == 0): self.zjmkaishi.show() # self.textObjectstart1.hide() self.textObjectstart2.show() self.b1.show() elif(self.jiechu2 == 1 and self.down == 0): self.zjmkaishi2.show() # self.textObjectstart4.hide() self.textObjectstart5.show() self.b2.show() elif(self.down == 0): self.c1.hide() self.c2.hide() self.b1.hide() self.b2.hide() self.a1.show() self.a2.show() self.zjmkaishi.hide() self.textObjectstart3.hide() self.textObjectstart2.hide() self.textObjectstart1.show() self.zjmkaishi2.hide() self.textObjectstart6.hide() self.textObjectstart5.hide() self.textObjectstart4.show() else: self.b1.hide() self.b2.hide() self.zjmkaishi.hide() self.textObjectstart2.hide() self.zjmkaishi2.hide() self.textObjectstart5.hide() return task.cont # return task.done # 按下开始游戏触发 def putdown(self): print('start') self.down = 1 self.a1.hide() self.b1.hide() self.zjmkaishi.hide() self.c1.show() self.textObjectstart1.hide() self.textObjectstart2.hide() self.textObjectstart3.show() self.beijing.hide() self.textObjectstart1.hide() self.textObjectstart2.hide() self.textObjectstart3.hide() self.textObjectstart4.hide() self.textObjectstart5.hide() self.textObjectstart6.hide() self.a1.hide() self.a2.hide() self.b1.hide() self.b2.hide() self.c1.hide() self.c2.hide() # 按下退出游戏触发 def quit(self): print('exit') self.down = 1 self.a2.hide() self.zjmkaishi2.hide() self.c2.show() self.textObjectstart4.hide() self.textObjectstart5.hide() self.textObjectstart6.show() sys.exit() # 按下菜单界面按钮触发 def putdown1(self): self.caidanjiemian.hide() self.bangzhu1button.hide() self.bangzhu2button.hide() self.bangzhu3button.hide() self.bangzhu1.hide() self.bangzhu2.hide() self.bangzhu3.hide() self.bangzhujiemian.show() self.bangzhuxinxi.show() self.bangzhuxinxibutton.show() self.bangzhuxinxi1.show() def putdown2(self): self.menuon = 0 self.caidanjiemian.hide() self.bangzhu1button.hide() self.bangzhu2button.hide() self.bangzhu3button.hide() self.bangzhu1.hide() self.bangzhu2.hide() self.bangzhu3.hide() self.bangzhujiemian.hide() self.bangzhuxinxi.hide() self.bangzhuxinxi1.hide() self.bangzhuxinxibutton.hide() def putdown3(self): sys.exit() # self.b.show() # 按下帮助界面的返回触发 def help1(self): self.caidanjiemian.show() self.bangzhu1button.show() self.bangzhu2button.show() self.bangzhu3button.show() self.bangzhu1.show() self.bangzhu2.show() self.bangzhu3.show() self.bangzhujiemian.hide() self.bangzhuxinxi.hide() self.bangzhuxinxibutton.hide() self.bangzhuxinxi1.hide() # 胜利和失败触发 def victory(self): self.victorypic.show() self.rebornbutton.show() self.reborntext.show() self.victorymusic.play() def false(self): self.falsepic.show() self.rebornbutton.show() self.reborntext.show() self.falsemusic.play() def reborn(self): print("reborn") self.rebornbutton.hide() self.reborntext.hide() self.victorypic.hide() self.falsepic.hide() self.down=0 self.beijing.show()
class MainMenu(): def __init__(self, showbase): self.showbase = showbase self.status = OnscreenText(text = "", pos = Vec3(0, -0.35, 0), scale = 0.05, fg = (1, 0, 0, 1), align = TextNode.ACenter, mayChange = True) self.background = DirectFrame( frameSize = (-1, 1, -1, 1), frameTexture = 'media/gui/mainmenu/menu.png', parent = self.showbase.render2d, ) self.title = OnscreenText( text = 'Main Menu', fg = (1, 1, 1, 1), parent = self.background, pos = (-0.6, 0.1), scale = 0.06 ) self.ip = '127.0.0.1' # Should make this write to file... so that the user can save ip's... # yep thats a good idea, there will be a few things i guess that need to be done like this # like settings and keys and whatnot # Buttons self.buttons = [] serverButtons = Vec3(-0.60, 0, -0.79) # Host self.params = ['3', '8'] p = serverButtons + Vec3(-0.25, 0, 0) self.hostButton = DirectButton(text = 'Host', pos = p, scale = 0.048, relief = DGG.GROOVE, command = self.showbase.hostGame, extraArgs = [self.params]) self.buttons.append(self.hostButton) # Join p = serverButtons + Vec3(0.0, 0.0, 0.0) self.joinButton = DirectButton(text = 'Join', pos = p, scale = 0.048, relief = DGG.GROOVE, command = self.joinServer) self.buttons.append(self.joinButton) # Refresh if self.showbase.online: p = serverButtons + Vec3(0.25, 0, 0) self.refreshButton = DirectButton(text = "Refresh", pos = p, scale = 0.048, relief = DGG.GROOVE, command = self.refreshStart) self.buttons.append(self.refreshButton) self.refreshStart() chatFrameCenter = (0.0, 0.325) chatFrameSize = (2.5, 1.2) self.chat = DirectFrame( frameColor = (0, 0, 0, 1), frameSize = (chatFrameSize[0] / 2, -chatFrameSize[0] / 2, chatFrameSize[1] / 2, -chatFrameSize[1] / 2), pos = (chatFrameCenter[0], 0, chatFrameCenter[1]) ) channelFrameSize = (chatFrameSize[0] / 4, chatFrameSize[1]) channelFrameCenter = (- chatFrameSize[0] / 2 + channelFrameSize[0] / 2, 0) numItemsVisible = 8 itemHeight = channelFrameSize[1] / (numItemsVisible + 1) self.channels = DirectScrolledList( parent = self.chat, pos = (channelFrameCenter[0], 0, channelFrameCenter[1]), frameSize = (-channelFrameSize[0] / 2, channelFrameSize[0] / 2, channelFrameSize[1] / 2, -channelFrameSize[1] / 2), frameColor = (1, 0, 0, 0.5), numItemsVisible = numItemsVisible, forceHeight = itemHeight, #itemFrame_frameSize = (-channelFrameSize[0] / 2.1, channelFrameSize[0] / 2.1, itemHeight, -channelFrameSize[1] + itemHeight), itemFrame_pos = (0, 0, channelFrameSize[1] / 2 - itemHeight), decButton_pos = (-0.2, 0, channelFrameCenter[1] - channelFrameSize[1] / 2 + itemHeight / 4), decButton_text = 'Prev', decButton_text_scale = 0.05, decButton_borderWidth = (0.005, 0.005), incButton_pos = (0.2, 0, channelFrameCenter[1] - channelFrameSize[1] / 2 + itemHeight / 4), incButton_text = 'Next', incButton_text_scale = 0.05, incButton_borderWidth = (0.005, 0.005), ) b1 = DirectButton(text = ("Button1", "click!", "roll", "disabled"), text_scale = 0.1, borderWidth = (0.01, 0.01), relief = 2) b2 = DirectButton(text = ("Button2", "click!", "roll", "disabled"), text_scale = 0.1, borderWidth = (0.01, 0.01), relief = 2) l1 = DirectLabel(text = "Test1", text_scale = 0.1) l2 = DirectLabel(text = "Test2", text_scale = 0.1) l3 = DirectLabel(text = "Test3", text_scale = 0.1) self.channels.addItem(b1) self.channels.addItem(b2) self.channels.addItem(l1) self.channels.addItem(l2) self.channels.addItem(l3) for fruit in ['apple', 'pear', 'banana', 'orange', 'cake', 'chocolate']: l = DirectLabel(text = fruit, text_scale = 0.1) self.channels.addItem(l) # need to add the chat stuff # i guess have like a chat manager which will hold an array of 'chat_instances' # and the chat manager can sort out which is displayed and which channel the text is sent from/received to # a bit more thinking needs to be done i guess # can discuss sometime (not really that important now :P) # also i guess the layout and shit will need to be sorted (for whoever is doing the designing) # current games list (need to implement this) # it should send a query to the master server to get the current list (just ip's atmo i guess) # options shit aswell needs to be sorted # maybe just an overlay or something # functionality for the host button (popup an overlay that will be able to set options and then 'start_game' button # then should auto connect and go to lobby (will be same as for all clients, except have a couple of different buttons i guess) # close game instead of disconnect, start game instead of ready (greyed until all others are ready), kick button i suppose # once the options are set the 'server_inst' should be started on the local computer (which will broadcast to master server, once host can successfully connect) # then game client will move to pregame state (connect to the server, and wait for others and ready) else: self.entry = DirectEntry( focusInCommand = self.clearText, frameSize = (-3, 3, -.5, 1), initialText = self.ip, parent = self.buttons[0], pos = (0, -0.6, -1.5), text_align = TextNode.ACenter, ) self.hide() def refreshStart(self): self.refreshButton["state"] = DGG.DISABLED if self.showbase.authCon.getConnected(): self.servers = [] self.showbase.authCon.sendData('serverQuery') self.showbase.taskMgr.doMethodLater(0.25, self.queryServers, 'Server Query') def queryServers(self, task): finished = False temp = self.showbase.authCon.getData() for package in temp: if len(package) == 2: # Handle Server Query if package[0] == 'server': self.servers.append(package[1]) print package[1] elif package[0] == 'final': self.refreshButton["state"] = DGG.NORMAL finished = True else: self.showbase.authCon.passData(package) if finished: return task.done return task.cont def joinChat(self): pass # Let the client mini auth with the lobby server(lobby_loop) by "Logging into the chat" # Since everything will be in the main menu? like a main chat window.. something similar to HoN i guess? # When the player opens the Join game by button, a list will be send from the lobby server telling it what games are active. # Then the player picks one and it connects via the host name/ip or whatever. # While this is busy happening the client stays connected to the lobby server. def joinServer(self): if self.showbase.online: self.ip = '127.0.0.1' else: self.ip = self.entry.get() self.status.setText('Attempting to join server @ ' + self.ip + '...') # attempt to connect to the game server self.showbase.client = Client(self.showbase, self.ip, 9099, compress = True) if self.showbase.client.getConnected(): print 'Connected to server, Awaiting authentication...' self.showbase.client.sendData(('username', self.showbase.username)) self.showbase.taskMgr.add(self.authorizationListener, 'Authorization Listener') else: self.status.setText('Could not Connect...') def authorizationListener(self, task): temp = self.showbase.client.getData() auth = False if temp != []: for package in temp: if len(package) == 2: if package[0] == 'auth': print 'Authentication Successful' auth = True elif package[0] == 'fail': self.status.setText('Authentication failed on server...') return task.done else: self.showbase.client.passData(package) if auth: self.showbase.startPregame() return task.done return task.again def clearText(self): self.entry.enterText('') def hide(self): self.showbase.taskMgr.remove('Server Query Timeout') self.background.hide() for b in self.buttons: b.hide() self.status.hide() if self.showbase.online: self.chat.hide() self.channels.hide() else: self.entry.hide() def show(self): self.background.show() for b in self.buttons: b.show() self.status.show() if self.showbase.online: self.chat.show() self.channels.show() else: self.entry.show()
class KeyCodesGui(DirectObject): __module__ = __name__ notify = directNotify.newCategory('KeyCodesGui') TIMEOUT_TASK = 'KeyCodeGui_TIMEOUT_TASK' def __init__(self, keyCodes, yOffset=0.55, keyToIndex=KEY_TO_INDEX): self._keyCodes = keyCodes self._keyToIndex = keyToIndex self._arrowWidth = 0.18 self._arrowSpaceInBetween = 0.05 self._yOffset = yOffset self._danceMoveLabel = None self._arrowNodes = [] self.timeoutTask = None return def load(self): matchingGameGui = loader.loadModel( 'phase_3.5/models/gui/matching_game_gui') minnieArrow = matchingGameGui.find('**/minnieArrow') minnieArrow.setScale(0.6) minnieArrow.setZ(self._yOffset + 0.2) maxLength = self._keyCodes.getLargestPatternLength() for i in range(maxLength): arrow = minnieArrow.copyTo(hidden) self._arrowNodes.append(arrow) matchingGameGui.removeNode() self._danceMoveLabel = OnscreenText(parent=aspect2d, text='', pos=(0, self._yOffset), scale=0.15, align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), fg=Vec4(1, 1, 1, 1), mayChange=True) self._danceMoveLabel.hide() self.enable() def unload(self): self.disable() for arrow in self._arrowNodes: arrow.removeNode() arrow = None self._arrowNodes = [] if self._danceMoveLabel is not None: self._danceMoveLabel.removeNode() self._danceMoveLabel = None return def enable(self): self.notify.debug('KeyCodeGui enabled.') self.accept(KeyCodes.KEY_DOWN_EVENT, self.__handleKeyDown) self.accept(KeyCodes.CLEAR_CODE_EVENT, self.hideAll) def disable(self): self.notify.debug('KeyCodeGui disabled.') self.__stopTimeout() self.ignoreAll() def hideArrows(self, startIndex=0): length = len(self._arrowNodes) if startIndex < length: for i in range(startIndex, length): self._arrowNodes[i].reparentTo(hidden) def hideAll(self, startIndex=0): self.hideArrows(startIndex) if self._danceMoveLabel: self._danceMoveLabel.hide() def showArrow(self, index, key): self._arrowNodes[index].setR(-(90 - 90 * self._keyToIndex[key])) self._arrowNodes[index].setColor(1, 1, 1, 1) self.__centerArrows() self._arrowNodes[index].reparentTo(aspect2d) self.hideAll(index + 1) self.__startTimeout() def showText(self, text=''): self.notify.debug('"Showing text "%s"' % text) self._danceMoveLabel['text'] = text self._danceMoveLabel.show() def setColor(self, r, g, b): for arrow in self._arrowNodes: arrow.setColor(r, g, b) self._danceMoveLabel.setColorScale(r, g, b, 1) def __startTimeout(self): self.__stopTimeout() self.timeoutTask = taskMgr.doMethodLater(KEYCODE_TIMEOUT_SECONDS, self.__handleTimeoutTask, KeyCodesGui.TIMEOUT_TASK) def __stopTimeout(self): if self.timeoutTask is not None: taskMgr.remove(self.timeoutTask) self.timeoutTask = None return def __handleTimeoutTask(self, task): self.hideAll() return Task.done def __centerArrows(self): length = self._keyCodes.getCurrentInputLength() for i in range(length): x = -(length * self._arrowWidth * 0.5) + self._arrowWidth * (i + 0.5) self._arrowNodes[i].setX(x) def __handleKeyDown(self, key, index): if index >= 0: self.showArrow(index, key)
class PartyCogActivityGui(DirectObject): notify = directNotify.newCategory("PartyCogActivityGui") def __init__(self): DirectObject.__init__(self) self._piePowerMeter = None self._victoryBalanceBar = None self._scoreLabel = None self._cogTracker = None self._piePowerTitle = None self._victoryBalanceTitle = None self._scoreTitle = None self._spamWarning = None self._spamWarningIvalName = "PartyCogActivityGui-SpamWarning" def load(self): self._initPiePowerMeter() self._initScore() self._initCogTracker() self._initSpamWarning() self._initControlGui() self._initVictoryBalanceBar() def unload(self): if self._cogTracker is not None: self._cogTracker.destory() self._cogTracker = None if self._piePowerMeter is not None: self._piePowerMeter.destroy() self._piePowerMeter = None if self._piePowerTitle is not None: self._piePowerTitle.destroy() self._piePowerTitle = None if self._scoreLabel is not None: self._scoreLabel.destroy() self._scoreLabel = None if self._scoreTitle is not None: self._scoreTitle.destroy() self._scoreTitle = None taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.destroy() self._spamWarning = None if hasattr(self, '_attackKeys'): self._attackKeys.detachNode() del self._attackKeys if hasattr(self, '_moveKeys'): self._moveKeys.detachNode() del self._moveKeys if self._victoryBalanceBar: self._victoryBalanceBar.detachNode() self._victoryBalanceBar = None if self._victoryBalanceBarOrange: self._victoryBalanceBarOrange.detachNode() self._victoryBalanceBarOrange = None if self._victoryBalanceBarPie: self._victoryBalanceBarPie.detachNode() self._victoryBalanceBarPie = None if self._victoryBalanceBarArrow: self._victoryBalanceBarArrow.detachNode() self._victoryBalanceBarArrow = None def _initVictoryBalanceBar(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 victoryBalanceBar = loader.loadModel("phase_13/models/parties/tt_m_gui_pty_pieToss_balanceBar") self._victoryBalanceBar = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarBG") self._victoryBalanceBar.reparentTo(aspect2d) self._victoryBalanceBar.setBin("fixed", 0) self._victoryBalanceBar.setPos(PartyGlobals.CogActivityVictoryBarPos) self._victoryBalanceBar.setScale(1) self._victoryBalanceBarOrange = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarOrange") self._victoryBalanceBarOrange.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarOrange.setBin("fixed", 1) self._victoryBalanceBarOrange.setPos(PartyGlobals.CogActivityVictoryBarOrangePos) self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale, 1.0, 1.0) self._victoryBalanceBarPie = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceBarPie") self._victoryBalanceBarPie.reparentTo(self._victoryBalanceBar) self._victoryBalanceBarPie.setBin("fixed", 2) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0]) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) self._victoryBalanceBarPie.setScale(PartyGlobals.CogActivityBarPieScale) self._victoryBalanceBarArrow = victoryBalanceBar.find("**/*tt_t_gui_pty_pieToss_balanceArrow") self._victoryBalanceBarArrow.reparentTo(self._victoryBalanceBarPie) self._victoryBalanceBarArrow.setBin("fixed", 2) self._victoryBalanceBarArrow.setPos(PartyGlobals.CogActivityVictoryBarArrow) self._victoryBalanceBarArrow.setScale(1/PartyGlobals.CogActivityBarPieScale) # self._victoryBalanceBar = DirectWaitBar( # frameSize = (-h, h, -w, w), # relief = DGG.SUNKEN, # frameColor = PartyGlobals.CogActivityColors[0], # borderWidth = (0.0, 0.0), # barColor = PartyGlobals.CogActivityColors[1], # pos = PartyGlobals.CogActivityVictoryBarPos, # hpr = (0.0, 0.0, -90.0), # ) # self._victoryBalanceBar.setBin("fixed", 0) # self._victoryBalanceBar["value"] = 50 def _initControlGui(self): self._attackIvalName = "PartyCogActivityGui-attackKeys" self._moveIvalName = "PartyCogActivityGui-moveKeys" pieTossControls = loader.loadModel("phase_13/models/parties/tt_m_gui_pty_pieToss_controls") self._attackKeys = pieTossControls.find("**/*control*") self._moveKeys = pieTossControls.find("**/*arrow*") self._moveKeys.reparentTo(aspect2d) self._moveKeys.setPos(1.0, 0.0, -0.435) self._moveKeys.setScale(0.15) self._attackKeys.reparentTo(aspect2d) self._attackKeys.setPos(0.85, 0.0, -0.45) self._attackKeys.setScale(0.15) self._moveKeys.hide() self._attackKeys.hide() def _initPiePowerMeter(self): h = PartyGlobals.CogActivityPowerMeterHeight / 2.0 w = PartyGlobals.CogActivityPowerMeterWidth / 2.0 self._piePowerMeter = DirectWaitBar( frameSize = (-h, h, -w, w), relief = DGG.GROOVE, frameColor = (0.9, 0.9, 0.9, 1.0), borderWidth = (0.01, 0.01), barColor = PartyGlobals.CogActivityColors[0], pos = PartyGlobals.CogActivityPowerMeterPos, hpr = (0.0, 0.0, -90.0), ) self._piePowerMeter.setBin("fixed", 0) self._piePowerTitle = OnscreenText( text=TTLocalizer.PartyCogGuiPowerLabel, pos=PartyGlobals.CogActivityPowerMeterTextPos, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), align=TextNode.ACenter, ) self._piePowerTitle.setBin("fixed", 0) self._piePowerMeter.hide() self._piePowerTitle.hide() def _initScore(self): self._scoreLabel = OnscreenText( text="0", pos=PartyGlobals.CogActivityScorePos, scale=PartyGlobals.TugOfWarTextWordScale, #fg=base.localAvatar.style.getHeadColor(), #fg=PartyGlobals.TeamActivityStatusColor, fg=(1.0, 1.0, 0.0, 1.0), align=TextNode.ARight, font=ToontownGlobals.getSignFont(), mayChange=True, ) self._scoreTitle = OnscreenText( text=TTLocalizer.PartyCogGuiScoreLabel, pos=PartyGlobals.CogActivityScoreTitle, scale=0.05, fg=(1.0, 1.0, 1.0, 1.0), #fg=(0.0, 0.0, 0.0, 1.0), align=TextNode.ARight, ) self._scoreLabel.hide() self._scoreTitle.hide() def _initCogTracker(self): self._cogTracker = PartyCogTrackerGui() def _initSpamWarning(self): self._spamWarning = OnscreenText( text = TTLocalizer.PartyCogGuiSpamWarning, scale = 0.15, fg = (1.0, 1.0, 0, 1.0), shadow = (0, 0, 0, 0.62), mayChange = False, pos = (0, 0.33) ) self._spamWarning.hide() def showScore(self): self._scoreLabel.show() self._scoreTitle.show() def hideScore(self): self._scoreLabel.hide() self._scoreTitle.hide() def setScore(self, score=0): self._scoreLabel["text"] = str(score) def resetPiePowerMeter(self): self._piePowerMeter["value"] = 0 def showPiePowerMeter(self): self._piePowerMeter.show() self._piePowerTitle.show() def hidePiePowerMeter(self): self._piePowerMeter.hide() self._piePowerTitle.hide() def updatePiePowerMeter(self, value): self._piePowerMeter["value"] = value # Uncomment this part if you want the bar to by a psychedelic change of colors. # self._piePowerMeter["barColor"] = ( # min(value * 2, 100) / 100.0, # min((100 - value) * 2, 100) / 100.0, # 0.0, # 1.0 # ) def getPiePowerMeterValue(self): return self._piePowerMeter["value"] def hideSpamWarning(self): taskMgr.remove(self._spamWarningIvalName) if self._spamWarning: self._spamWarning.hide() def showSpamWarning(self): if self._spamWarning.isHidden(): self._spamWarning.show() taskMgr.remove(self._spamWarningIvalName) Sequence( # Boing it in to grab attention. ToontownIntervals.getPulseLargerIval(self._spamWarning, ""), # Let it sit on-screen for a while. Wait(PartyGlobals.CogActivitySpamWarningShowTime), # Then get rid of it. Func(self.hideSpamWarning), name=self._spamWarningIvalName, autoFinish=1 ).start() def hide(self): self.hidePiePowerMeter() self.hideScore() self.hideSpamWarning() self.hideControls() def disableToontownHUD(self): base.localAvatar.hideName() base.localAvatar.laffMeter.hide() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], False) def enableToontownHUD(self): base.localAvatar.showName() base.localAvatar.laffMeter.show() base.setCellsAvailable(base.bottomCells + [base.rightCells[1]], True) def setTeam(self, team): self.team = team if team == 0: self._cogTracker.frame.setR(180) # The old default power bar color was blue, but that was confusing because there's a blue team. # So the idea here is to make the color the same as the player's team. self._piePowerMeter["barColor"] = PartyGlobals.CogActivityColors[team] def startTrackingCogs(self, cogs): self.cogs = cogs taskMgr.add(self.trackCogs, "trackCogs") def trackCogs(self, task): if self.cogs is None: return self._updateVictoryBar() for i, cog in enumerate(self.cogs): self._cogTracker.updateCog(i,cog,self.team) return task.cont def _updateVictoryBar(self): if not ( hasattr(self, "_victoryBalanceBar") and self._victoryBalanceBar): return netDistance = 0 for cog in self.cogs: netDistance = netDistance + cog.targetDistance teamDistance = netDistance/6.0 self._victoryBalanceBarOrange.setScale(PartyGlobals.CogActivityBarStartScale + \ (teamDistance * 10 * PartyGlobals.CogActivityBarUnitScale),1.0,1.0) #self._victoryBalanceBar["value"] = 50 + (netDistance/6 * 100) self._victoryBalanceBarPie.setX(PartyGlobals.CogActivityVictoryBarPiePos[0] + \ (teamDistance * 10 *PartyGlobals.CogActivityBarPieUnitMove)) self._victoryBalanceBarPie.setY(PartyGlobals.CogActivityVictoryBarPiePos[1]) self._victoryBalanceBarPie.setZ(PartyGlobals.CogActivityVictoryBarPiePos[2]) if teamDistance>0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[1]) elif teamDistance<0.0: self._victoryBalanceBarArrow.setColor(PartyGlobals.CogActivityColors[0]) else: self._victoryBalanceBarArrow.setColor(VBase4(1.0,1.0,1.0,1.0)) def stopTrackingCogs(self): taskMgr.remove("trackCogs") def showAttackControls(self): if self._attackKeys.isHidden(): self._attackKeys.show() taskMgr.remove(self._attackIvalName) Sequence( ToontownIntervals.getPulseLargerIval(self._attackKeys, "", scale = 0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideAttackControls), name=self._attackIvalName, autoFinish=1 ).start() def showMoveControls(self): if self._moveKeys.isHidden() and not self._attackKeys.isHidden(): self._moveKeys.show() taskMgr.remove(self._moveIvalName) Sequence( ToontownIntervals.getPulseLargerIval(self._moveKeys, "", scale = 0.15), Wait(PartyGlobals.CogActivityControlsShowTime), Func(self.hideMoveControls), name=self._moveIvalName, autoFinish=1 ).start() def hideAttackControls(self): taskMgr.remove(self._attackIvalName) if hasattr(self, "_attackKeys") and self._attackKeys: self._attackKeys.hide() def hideMoveControls(self): taskMgr.remove(self._moveIvalName) if hasattr(self, "_moveKeys") and self._moveKeys: self._moveKeys.hide() def hideControls(self): self.hideMoveControls() self.hideAttackControls()
class KeyCodesGui(DirectObject): __module__ = __name__ notify = directNotify.newCategory('KeyCodesGui') TIMEOUT_TASK = 'KeyCodeGui_TIMEOUT_TASK' def __init__(self, keyCodes, yOffset = 0.55, keyToIndex = KEY_TO_INDEX): self._keyCodes = keyCodes self._keyToIndex = keyToIndex self._arrowWidth = 0.18 self._arrowSpaceInBetween = 0.05 self._yOffset = yOffset self._danceMoveLabel = None self._arrowNodes = [] self.timeoutTask = None return def load(self): matchingGameGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui') minnieArrow = matchingGameGui.find('**/minnieArrow') minnieArrow.setScale(0.6) minnieArrow.setZ(self._yOffset + 0.2) maxLength = self._keyCodes.getLargestPatternLength() for i in range(maxLength): arrow = minnieArrow.copyTo(hidden) self._arrowNodes.append(arrow) matchingGameGui.removeNode() self._danceMoveLabel = OnscreenText(parent=aspect2d, text='', pos=(0, self._yOffset), scale=0.15, align=TextNode.ACenter, font=ToontownGlobals.getSignFont(), fg=Vec4(1, 1, 1, 1), mayChange=True) self._danceMoveLabel.hide() self.enable() def unload(self): self.disable() for arrow in self._arrowNodes: arrow.removeNode() arrow = None self._arrowNodes = [] if self._danceMoveLabel is not None: self._danceMoveLabel.removeNode() self._danceMoveLabel = None return def enable(self): self.notify.debug('KeyCodeGui enabled.') self.accept(KeyCodes.KEY_DOWN_EVENT, self.__handleKeyDown) self.accept(KeyCodes.CLEAR_CODE_EVENT, self.hideAll) def disable(self): self.notify.debug('KeyCodeGui disabled.') self.__stopTimeout() self.ignoreAll() def hideArrows(self, startIndex = 0): length = len(self._arrowNodes) if startIndex < length: for i in range(startIndex, length): self._arrowNodes[i].reparentTo(hidden) def hideAll(self, startIndex = 0): self.hideArrows(startIndex) if self._danceMoveLabel: self._danceMoveLabel.hide() def showArrow(self, index, key): self._arrowNodes[index].setR(-(90 - 90 * self._keyToIndex[key])) self._arrowNodes[index].setColor(1, 1, 1, 1) self.__centerArrows() self._arrowNodes[index].reparentTo(aspect2d) self.hideAll(index + 1) self.__startTimeout() def showText(self, text = ''): self.notify.debug('"Showing text "%s"' % text) self._danceMoveLabel['text'] = text self._danceMoveLabel.show() def setColor(self, r, g, b): for arrow in self._arrowNodes: arrow.setColor(r, g, b) self._danceMoveLabel.setColorScale(r, g, b, 1) def __startTimeout(self): self.__stopTimeout() self.timeoutTask = taskMgr.doMethodLater(KEYCODE_TIMEOUT_SECONDS, self.__handleTimeoutTask, KeyCodesGui.TIMEOUT_TASK) def __stopTimeout(self): if self.timeoutTask is not None: taskMgr.remove(self.timeoutTask) self.timeoutTask = None return def __handleTimeoutTask(self, task): self.hideAll() return Task.done def __centerArrows(self): length = self._keyCodes.getCurrentInputLength() for i in range(length): x = -(length * self._arrowWidth * 0.5) + self._arrowWidth * (i + 0.5) self._arrowNodes[i].setX(x) def __handleKeyDown(self, key, index): if index >= 0: self.showArrow(index, key)
class SimWorldBase(ShowBase): def __init__(self, width, height, isFullscreen, title): ShowBase.__init__(self) #======================================================================= # Set window properties. #======================================================================= win_props = WindowProperties(self.win.getProperties()) win_props.setTitle(title) win_props.setFullscreen(isFullscreen) win_props.setSize(width, height) self.win.requestProperties(win_props) # Apply the property changes. self.graphicsEngine.openWindows() #======================================================================= # Scene related fields. #======================================================================= self.sceneNP = None ''' Main scene node path. There can be only one scene at any given time. ''' #======================================================================= # Actor related fields. #======================================================================= self.actorNP = {} ''' Dictionary of actor node paths keyed with the actor name.Internal use only. ''' self.actorOINP = None ''' Actor of interest node path. There can be only one actor of interest at any given time. ''' self.actorOIName = None ''' Actor of interest name. There can be only one actor of interest at any given time. ''' self.actorOIMoveDir = 0 ''' Actor of interest movement direction indicator. Forward is 1, reverse is -1, and stop is 0. ''' self.actorOITurnDir = 0 ''' Actor of interest turn direction indicator. Left is 1, right is -1, and no turn is 0. ''' self.actorOIMoveSpeed = 3 ''' Actor of interest translational speed. Distance units per second. ''' self.actorOITurnSpeed = 30 ''' Actor of interest rotational speed. Degrees per second. ''' self.actorOILocation = Vec3D.zero() ''' Actor of interest's location coordinates after the last frame. ''' self.actorOIVelocity = Vec3D.zero() ''' Actor of interest's velocity vector after the last frame. ''' #======================================================================= # Camera related fields. #======================================================================= self.cameraNP = {} ''' Dictionary of camera node paths keyed with the camera name. ''' # Add the showbase camera as 'default'. self.cameraNP['default'] = self.cam #======================================================================= # Illumination related fields #======================================================================= self.lightNP = {} ''' Dictionary of light node paths keyed with the light name. ''' self.goalNP = {} ''' Dictionary of goal node paths keyed with the goal name. ''' #======================================================================= # Display region related fields. #======================================================================= self.displayRegion = {} ''' Dictionary of display regions keyed with the display region name. ''' self.displayRegionOI = None ''' Display region of interest. Any action related to display regions will be applied to the current display region of interest. ''' self.displayRegionOIName = None ''' Display region of interest name. Any action related to display regions will be applied to the current display region of interest. ''' # Add the display region associated with the default showbase camera. self.displayRegion['default'] = self.camNode.getDisplayRegion(0) self.displayRegion['default'].setSort(1) self.accept('control-`', self.setDisplayRegionOfInterest, ['default']) # Current display region of interest is the 'default' one. self.displayRegionOI = self.displayRegion['default'] self.displayRegionOIName = 'default' #======================================================================= # AI related fields. #======================================================================= self.AIWorld = AIWorld(self.render) self.AICharacter = {} #======================================================================= # Trace file related fields. #======================================================================= self.traceFile = None '''Handle to the trace file.''' self.traceMessage = '' '''Message to be written to the trace file.''' self.onScreenHelpNP = None '''Text node path holding the on screen help information.''' #======================================================================= # Other fields. #======================================================================= self.clock = globalClock '''Exposes Panda3D's GlobalClock.''' self.userDialog = OnscreenText(text='', bg=(0,0,0,.6), fg=(.8,0,0,1), mayChange=True) self.userDialogTask = None self.isNotifyUser = True # We do not need the default mouse controls. self.disableMouse() # We do not need the default camera. self.cam.node().setActive(False) # Make sure a clean exit from the application when requested. atexit.register(self.exitfunc) # Default collision traverser. self.cTrav = CollisionTraverser() #======================================================================= # On screen help setup. #======================================================================= OSHelp_str = '\nHELP\n' text_font = self.loader.loadFont('cmtt12', spaceAdvance=.52) self.onScreenHelpNP = OnscreenText(text=OSHelp_str, font=text_font, style=1, fg=(1,1,1,1), bg=(0,0,0,.6), align=TextNode.ALeft, scale=.05, mayChange=True) self.onScreenHelpNP.reparentTo(self.a2dTopLeft) self.onScreenHelpNP.hide() #======================================================================= # Keyboard control related fields and default settings. #======================================================================= self.keyMap = {} '''Dictionary of keyboard controls keyed with the action name.''' self.setActorOIActionKey('forward', 'arrow_up') self.setActorOIActionKey('reverse', 'arrow_down') self.setActorOIActionKey('turn left', 'arrow_left') self.setActorOIActionKey('turn right', 'arrow_right') self.addHotKey('t', 'toggle pip', self.toggleDisplayRegion, []) self.addHotKey('f1', 'help', self.toggleOnScreenHelp, []) self.addHotKey('escape', 'quit', self.shutDown, []) def setTracing(self, fileName, flag=True): if flag and self.traceFile is None: self.traceFile = open(fileName, 'w') self.taskMgr.add(self.traceUpdateTask, 'traceUpdate', sort=100) else: self.taskMgr.remove('traceUpdate') self.traceFile.close() self.traceFile = None def getTracing(self): return self.taskMgr.hasTaskNamed('traceUpdate') def setupScene(self, modelName, position=(0,0,0), orientation=(0,0,0), scale=(1,1,1)): base_path = os.path.dirname(__file__) model_path = os.path.join(base_path, 'models', modelName) model_path = Filename.fromOsSpecific(model_path) self.sceneNP = self.loader.loadModel(model_path) self.sceneNP.setPosHprScale(position, orientation, scale) self.sceneNP.reparentTo(self.render) base.setBackgroundColor((.1, .1, .1, 0)) def getObject(self, name): return self.render.findAllMatches('**/'+name) def setObjectSolid(self, name, flag): if flag: self.getObject(name).setCollideMask(BitMask32(0x001), BitMask32(0x001)) else: self.getObject(name).setCollideMask(BitMask32.allOff(), BitMask32(0x001)) def setObjectGoal(self, name, flag): if flag: self.getObject(name).setCollideMask(BitMask32(0x002), BitMask32(0x002)) else: self.getObject(name).setCollideMask(BitMask32.allOff(), BitMask32(0x002)) def addHotKey(self, hotkey, action, callback, args): self.keyMap[action] = hotkey self.accept(hotkey, callback, args) def addActor(self, name, position=(0,0,0), orientation=(0,0,0), scale=(1,1,1), collisionSphere=None): # Create the scene node path. actor_np = NodePath(ActorNode(name)) actor_np.setPosHpr(position, orientation) actor_np.reparentTo(self.render) # Attach model to the node path. base_path = os.path.dirname(__file__) model_path = os.path.join(base_path, 'models', name) model_path = Filename.fromOsSpecific(model_path) model_np = self.loader.loadModel(model_path) model_np.setScale(scale) model_np.reparentTo(actor_np) #======================================================================= # Make actor physics collidible. #======================================================================= # Attach collision solid to the node path. cn = CollisionNode(name+'PhysicsCollisionNode') cn.setIntoCollideMask(BitMask32.allOff()) cn.setFromCollideMask(BitMask32.bit(0)) cs = CollisionSphere(collisionSphere[0:3], collisionSphere[3]) cn.addSolid(cs) actor_cnp = actor_np.attachNewNode(cn) # Add actor to the physics collision detection system. handler = PhysicsCollisionHandler() handler.addCollider(actor_cnp, actor_np) # self.cTrav.addCollider(actor_cnp, handler) #======================================================================= # Make actor AI compatible. #======================================================================= ai_character = AICharacter(name, actor_np, mass=50, movt_force=10, max_force=30) self.AICharacter[name] = ai_character self.AIWorld.addAiChar(ai_character) #======================================================================= # Make actor events collidible. #======================================================================= # Attach collision solid to the node path. cn = CollisionNode(name+'EventCollisionNode') cn.setIntoCollideMask(BitMask32.allOff()) cn.setFromCollideMask(BitMask32.bit(1)) cs = CollisionSphere(collisionSphere[0:3], collisionSphere[3]) cn.addSolid(cs) actor_cnp = actor_np.attachNewNode(cn) actor_cnp.show() # Add actor to the collision event detection system. handler = CollisionHandlerEvent() handler.addInPattern('%fn-enters') handler.addOutPattern('%fn-exits') self.cTrav.addCollider(actor_cnp, handler) self.accept(name+'EventCollisionNode'+'-enters', self.onActorEnterEventFunc) self.accept(name+'EventCollisionNode'+'-exits', self.onActorExitEventFunc) self.actorNP[name] = actor_np # The most recently added actor becomes actor of interest. self.setActorOfInterest(name) self.taskMgr.add(self.actorOIStateUpdateTask,'actorStateUpdate',sort=50) def activateActorOIControl(self, flag): if flag: self.taskMgr.add(self.actorOIControlTask,'actorControl',sort=10) else: self.taskMgr.remove('actorControl') def setActorOfInterest(self, name): self.actorOINP = self.actorNP[name] self.actorOIName = name self.actorOILocation = self.actorOINP.getPos() def setActorOIActionKey(self, action, key): self.keyMap[action] = key self.accept(key, self.setActorOIAction, [action]) self.accept(key+'-up', self.setActorOIAction, [action+' stop']) self.keyMap[action] = key def setActorOIAction(self, action): if action == 'forward': self.actorOIMoveDir = 1; elif action == 'reverse': self.actorOIMoveDir = -1; elif action == 'forward stop' or action == 'reverse stop': self.actorOIMoveDir = 0; elif action == 'turn right': self.actorOITurnDir = -1; elif action == 'turn left': self.actorOITurnDir = 1; elif action == 'turn right stop' or action == 'turn left stop': self.actorOITurnDir = 0; def addLight(self, name, hotkey, type, color=(1,1,1,1), position=(0,0,0), orientation=(0,0,0)): if type == 'ambient': light_np = AmbientLight(name) light_np.setColor(color) elif type == 'point': light_np = PointLight(name) light_np.setColor(color) light_np.setPoint(position) elif type == 'directional': light_np = DirectionalLight(name) light_np.setColor(color) light_np.setPoint(position) light_np.setDirection(orientation) else: return self.keyMap[name] = hotkey self.accept(hotkey, self.toggleLight, [name]) self.lightNP[name] = self.render.attachNewNode(light_np) def toggleLight(self, name): light_np = self.lightNP[name] if self.render.hasLight(light_np): self.render.setLightOff(light_np) msg = '''Light [{0}] turned off.'''.format(name) else: self.render.setLight(light_np) msg = '''Light [{0}] turned on.'''.format(name) self.notifyUser(msg, 2) def activateLight(self, name, flag): if flag: self.render.setLight(self.lightNP[name]) else: self.render.setLightOff(self.lightNP[name]) def addCamera(self, name, hotkey, parent, lens, position=(0,0,0), orientation=(0,0,0)): camera_n = Camera(name, lens) camera_np = NodePath(camera_n) camera_np.setPosHpr(position, orientation) camera_np.reparentTo(parent) self.keyMap[name] = hotkey self.accept(hotkey, self.activateCamera, [name]) self.cameraNP[name] = camera_np def activateCamera(self, name): dr = self.displayRegionOI ar = float(dr.getPixelWidth()) / dr.getPixelHeight() self.cameraNP[name].node().getLens().setAspectRatio(ar) self.displayRegionOI.setCamera(self.cameraNP[name]) self.cameraNP[name].node().setActive(True) msg = '''Camera [{0}] active on display region [{1}].''' self.notifyUser(msg.format(name, self.displayRegionOIName), 2) def addDisplayRegion(self, name, hotkey, lrbt): dr = self.win.makeDisplayRegion(lrbt[0],lrbt[1],lrbt[2],lrbt[3]) dr.setSort(99) dr.setActive(False) self.keyMap[name] = hotkey self.accept(hotkey, self.setDisplayRegionOfInterest, [name]) self.displayRegion[name] = dr def setDisplayRegionOfInterest(self, name): self.displayRegionOI = self.displayRegion[name] self.displayRegionOIName = name self.displayRegionOI.setActive(True) msg = '''Display region [{0}] selected.''' self.notifyUser(msg.format(self.displayRegionOIName), 2) def activateDisplayRegion(self, name, flag): self.displayRegion[name].setActive(flag) def toggleDisplayRegion(self, name=None): if name is not None: dr = self.displayRegion[name] else: dr = self.displayRegionOI dr.setActive(not dr.isActive()) def startAITask(self): taskMgr.add(self.AIUpdateTask, "AIUpdate") def stopAITask(self): taskMgr.remove("AIUpdate") def shutDown(self): if self.traceFile: self.traceFile.close() sys.exit() def toggleOnScreenHelp(self): str = '\n'.join([n.title().ljust(10)+' : '+k.title() for n,k in self.keyMap.iteritems()]) self.onScreenHelpNP.setText('\n'+str) if self.onScreenHelpNP.isHidden(): self.onScreenHelpNP.show() else: self.onScreenHelpNP.hide() def notifyUser(self, msg, delay): if self.isNotifyUser: self.userDialog.setText(msg) self.userDialog.show() if self.userDialogTask is not None: self.userDialogTask.remove() self.userDialogTask = self.taskMgr.doMethodLater(delay, self.userDialog.hide, 'destroyMessage', extraArgs=[]) def AIUpdateTask(self, task): self.AIWorld.update() return task.cont def traceUpdateFunc(self): pass def traceUpdateTask(self, task): self.traceUpdateFunc() message = 'timestamp:{0:.4f},{1}\n'.format(self.clock.getFrameTime(), self.traceMessage) self.traceFile.write(message) return task.cont def onActorEnterEventFunc(self, collisionEntry): pass def onActorExitEventFunc(self, collisionEntry): pass def actorOIControlTask(self, task): dt = self.clock.getDt() rotation = self.actorOITurnSpeed * self.actorOITurnDir * dt self.actorOINP.setH(self.actorOINP, rotation) translation = self.actorOIMoveSpeed * self.actorOIMoveDir * dt self.actorOINP.setY(self.actorOINP, translation) return task.cont def actorOIStateUpdateFunc(self): pass def actorOIStateUpdateTask(self, task): self.actorOIStateUpdateFunc() return task.cont
class InterfaceMenuPrincipal(ShowBase): def __init__(self): #Image d'arrière plan self.background = OnscreenImage( parent=render2d, image="../asset/Menu/menuPrincipal.jpg") #On dit à la caméra que le dernier modèle doit s'afficher toujours en arrière self.baseSort = base.cam.node().getDisplayRegion(0).getSort() base.cam.node().getDisplayRegion(0).setSort(20) #Titre du jeu self.textTitre = OnscreenText(text="Tankem!", pos=(0, 0.6), scale=0.32, fg=(0.8, 0.9, 0.7, 1), align=TextNode.ACenter) #Boutons btnScale = (0.18, 0.18) text_scale = 0.12 borderW = (0.04, 0.04) couleurBack = (0.243, 0.325, 0.121, 1) separation = 0.5 hauteur = -0.6 self.b1 = DirectButton(text=("Jouer", "!", "!", "disabled"), text_scale=btnScale, borderWidth=borderW, text_bg=couleurBack, frameColor=couleurBack, relief=2, command=self.chargeJeu, pos=(-separation, 0, hauteur)) self.b2 = DirectButton(text=("Quitter", "Bye!", ":-(", "disabled"), text_scale=btnScale, borderWidth=borderW, text_bg=couleurBack, frameColor=couleurBack, relief=2, command=lambda: sys.exit(), pos=(separation, 0, hauteur)) #Initialisation de l'effet de transition curtain = loader.loadTexture("../asset/Menu/loading.jpg") self.transition = Transitions(loader) self.transition.setFadeColor(0, 0, 0) self.transition.setFadeModel(curtain) self.sound = loader.loadSfx("../asset/Menu/demarrage.mp3") def cacher(self): #Est esssentiellement un code de "loading" #On remet la caméra comme avant base.cam.node().getDisplayRegion(0).setSort(self.baseSort) #On cache les menus self.background.hide() self.b1.hide() self.b2.hide() self.textTitre.hide() def chargeJeu(self): #On démarre! Sequence( Func(lambda: self.transition.irisOut(0.2)), SoundInterval(self.sound), Func(self.cacher), Func(lambda: messenger.send("DemarrerMenuNiveau")), Wait( 0.2 ), #Bug étrange quand on met pas ça. L'effet de transition doit lagger Func(lambda: self.transition.irisIn(0.2))).start()
class App(ShowBase): def __init__(self): ShowBase.__init__(self) # Print all events sent through the messenger #self.messenger.toggleVerbose() self.lblWarning = OnscreenText(text="No devices found", fg=(1, 0, 0, 1), scale=.25) self.lblAction = OnscreenText(text="Action", fg=(1, 1, 1, 1), scale=.15) self.lblAction.hide() # Is there a gamepad connected? self.flightStick = None devices = self.devices.getDevices(InputDevice.DeviceClass.flight_stick) if devices: self.connect(devices[0]) self.currentMoveSpeed = 0.0 self.maxAccleration = 28.0 self.deaccleration = 10.0 self.deaclerationBreak = 37.0 self.maxSpeed = 80.0 # Accept device dis-/connection events self.accept("connect-device", self.connect) self.accept("disconnect-device", self.disconnect) self.accept("escape", exit) self.accept("flight_stick0-start", exit) # Accept button events of the first connected flight stick self.accept("flight_stick0-trigger", self.action, extraArgs=["Trigger"]) self.accept("flight_stick0-trigger-up", self.actionUp) self.environment = loader.loadModel("environment") self.environment.reparentTo(render) # disable pandas default mouse-camera controls so we can handle the camera # movements by ourself self.disableMouse() self.reset() self.taskMgr.add(self.moveTask, "movement update task") def connect(self, device): """Event handler that is called when a device is discovered.""" # We're only interested if this is a flight stick and we don't have a # flight stick yet. if device.device_class == InputDevice.DeviceClass.flight_stick and not self.flightStick: print("Found %s" % (device)) self.flightStick = device # Enable this device to ShowBase so that we can receive events. # We set up the events with a prefix of "flight_stick0-". self.attachInputDevice(device, prefix="flight_stick0") # Hide the warning that we have no devices. self.lblWarning.hide() def disconnect(self, device): """Event handler that is called when a device is removed.""" if self.flightStick != device: # We don't care since it's not our gamepad. return # Tell ShowBase that the device is no longer needed. print("Disconnected %s" % (device)) self.detachInputDevice(device) self.flightStick = None # Do we have any other gamepads? Attach the first other gamepad. devices = self.devices.getDevices(InputDevice.DeviceClass.flight_stick) if devices: self.connect(devices[0]) else: # No devices. Show the warning. self.lblWarning.show() def reset(self): """Reset the camera to the initial position.""" self.camera.setPosHpr(0, -200, 10, 0, 0, 0) def action(self, button): # Just show which button has been pressed. self.lblAction.text = "Pressed %s" % button self.lblAction.show() def actionUp(self): # Hide the label showing which button is pressed. self.lblAction.hide() def moveTask(self, task): dt = globalClock.getDt() if not self.flightStick: return task.cont if self.currentMoveSpeed > 0: self.currentMoveSpeed -= dt * self.deaccleration if self.currentMoveSpeed < 0: self.currentMoveSpeed = 0 # Accelerate using the throttle. Apply deadzone of 0.01. throttle = self.flightStick.findAxis(InputDevice.Axis.throttle).value if abs(throttle) < THROTTLE_DEAD_ZONE: throttle = 0 accleration = throttle * self.maxAccleration if self.currentMoveSpeed > throttle * self.maxSpeed: self.currentMoveSpeed -= dt * self.deaccleration self.currentMoveSpeed += dt * accleration # Steering # Control the cameras yaw/Headding stick_yaw = self.flightStick.findAxis(InputDevice.Axis.yaw) if abs(stick_yaw.value) > STICK_DEAD_ZONE: base.camera.setH(base.camera, 100 * dt * stick_yaw.value) # Control the cameras pitch stick_y = self.flightStick.findAxis(InputDevice.Axis.pitch) if abs(stick_y.value) > STICK_DEAD_ZONE: base.camera.setP(base.camera, 100 * dt * stick_y.value) # Control the cameras roll stick_x = self.flightStick.findAxis(InputDevice.Axis.roll) if abs(stick_x.value) > STICK_DEAD_ZONE: base.camera.setR(base.camera, 100 * dt * stick_x.value) # calculate movement base.camera.setY(base.camera, dt * self.currentMoveSpeed) # Make sure camera does not go below the ground. if base.camera.getZ() < 1: base.camera.setZ(1) return task.cont
class Game(): HUD_TEXT_SCALE = 0.04 UPDATE_RATE = 1/60.0 def __init__(self): base.disableMouse() base.camera.setPos(0,0,640) base.camera.lookAt(0,0,0) self.loadPhysics() self.loadLights() #map x boundary, map y boundary, amount of pylons self.map = Map(self, 160.0, 160.0, 7) # self.Base1 = Base(self) # self.Base1.setPos( Vec3( 0, 50, 0)) # self.Base2 = Base(self) # self.Base2.setPos( Vec3( 0, -50, 0)) #self.Base2 = Base(self) # self.wall1 = StaticObject.bigWall(self) # self.wall1.setPos( Vec3( 50, (-50), 0) ) # self.wall1.setRotation( 90 ) # # self.wall2 = StaticObject.bigWall(self) # self.wall2.setPos( Vec3( 50, 0, 0) ) # self.wall2.setRotation( 90 ) #alustaa tyhjan listan self.shipList = [] self.ship1 = ShipTypes.Ship_2(self, Vec4(1.0, 1.0, 1.0, 0)) self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0)) self.LoadHUD() #lisataan alukset listaan self.ship1.addToShipList(self.shipList) self.ship2.addToShipList(self.shipList) ##katsotaan saako toimimaan listana gamelooppiin -- saa ##self.shipList = [self.ship1, self.ship2] self.ship2.setPos( Vec3(10, 10, 0) ) self.setKeys() self.collectibleList = [] self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo.addToCollectibleList(self.collectibleList) self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo2.setPos( Vec3(30, 20, 0) ) self.pallo2.addToCollectibleList(self.collectibleList) #self.collectibleList = [self.pallo, self.pallo2] # self.pylonList = [] # self.pylon1 = Pylon(self, 100) # self.pylon1.setPos( Vec3(-30, 20, 0) ) # self.pylon1.addToPylonList(self.pylonList) # self.pylon2 = Pylon(self, -100) # self.pylon2.setPos( Vec3(-30, -20, 0) ) # self.pylon2.addToPylonList(self.pylonList) # self.makeBoundaryWalls( 50.0, 50.0, 50.0) base.setBackgroundColor(0,0,0.0,0) taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('rshift', self.ship1.releaseBall) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) base.accept('q', self.ship2.releaseBall) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsWorld.setGravity(0, 0, 0) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): # self.player1HUD = OnscreenText( # text = "Player 1: " + str( self.ship1.getPoints() ), # fg = (1,1,1,1), # #pos = ( x, y ) # pos = (0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) # self.player2HUD = OnscreenText( # text = "Player 2: " + str( self.ship2.getPoints() ), # fg = (1,1,1,1), # pos = (-0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.25, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText.hide() # def updateHUD(self): # self.player1HUD = OnscreenText( # text = "Player 1: " + str( self.ship1.getPoints() ), # fg = (1,1,1,1), # pos = (0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) # self.player2HUD = OnscreenText( # text = "Player 2: " + str( self.ship2.getPoints() ), # fg = (1,1,1,1), # pos = (-0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.5, 0.9, 0.9, 0) ) render.setLight(lightNode1) #checks all collectibles for possible collisions with ships def checkAllCollectibles(self): for collectible in self.collectibleList: collectible.hitShips(self.shipList) #updates all collectible positions def updateAllCollectibles(self): for collectible in self.collectibleList: collectible.update(Game.UPDATE_RATE) #apply forces to all collectibles ## def applyForceAllCollectibles(self): ## for collectible in self.collectibleList: ## collectible.applyForces() def applyForceAllShips(self): for ship in self.shipList: ship.applyForces() #updates all ship positions def updateAllShips(self): for ship in self.shipList: ship.update(Game.UPDATE_RATE) #checks all pylons for possible collisions with ships def checkAllPylons(self): for pylon in self.map.getPylonList(): pylon.checkCollisionList(self.shipList) def loop(self, task): self.applyForceAllShips() self.physicsSpace.autoCollide() self.checkAllCollectibles() self.map.getBase1().checkCollision(self.ship1) self.map.getBase2().checkCollision(self.ship2) self.checkAllPylons() self.physicsWorld.quickStep(Game.UPDATE_RATE) self.updateAllShips() self.updateAllCollectibles() self.contactGroup.empty() return task.cont
class HUD(DirectObject): #TODO: Preload all images def __init__(self, base, player): self.base = base self.player = player self.heartmax = 160 self.heartmin = 80 self.heartbpm = self.heartmin self.heartaccum = 0 self.last = 0 self.heartbasis = 'assets/images/heartbeat2-%d.png' self.heartframe = 0 self.heartimage = OnscreenImage(self.heartbasis % (1,), scale=(0.1,0.1,0.1), pos=(-1,0, 0.8)) self.keyimage = OnscreenImage('assets/images/key.png', scale=(0.08,0.08,0.08), pos=(-1,0,0.60)) self.keyimage.setTransparency(TransparencyAttrib.MAlpha) self.text = OnscreenText('', pos=(-0.8, 0.8), scale=0.05, fg=(0,1,0,1), bg=(0,0,0,0)) self.hasKey = False self.base.taskMgr.add(self.update, 'hud') def __del__(self): self.base = None self.player = None self.heartimage.destroy() self.text.destroy() def update(self, task): if self.player.isAlive(): elapsed = task.time - self.last self.last = task.time # After a certain point, it should be cleared # Fear must also increase heartbeat f, b = self.player.fear, self.player.breath bpm = 80 + 200 * (0.75 + 0.25 * f) * (1 - b) + 40 * f self.heartaccum += elapsed * (bpm + self.heartbpm) / 2.0 self.heartbpm = bpm self.heartframe = int(8 * self.heartaccum / 60) % 8 self.heartimage.setImage(self.heartbasis % (self.heartframe + 1,)) self.heartimage.setTransparency(TransparencyAttrib.MAlpha) #TODO: Update parameters heartampl = self.heartmax - self.heartmin if self.heartbpm < self.heartmax: s = float(self.heartbpm - self.heartmin) / heartampl self.text.setFg((s,1,0,1)) else: s = float(self.heartbpm - self.heartmax) / heartampl self.text.setFg((1,1-s,0,1)) self.text.setText('%d BPM' % (self.heartbpm,)) else: self.text.setFg((1,1,1,1)) self.text.setText('0 BPM') #TODO: send a 'death' event and, possibly, play back a nice heart stopping animation #return task.done if (self.hasKey): self.keyimage.show() else: self.keyimage.hide() self.heartimage.show() self.text.show() return task.cont def hide(self): self.heartimage.hide() self.text.hide() def setKey(self, key): self.hasKey = key