Exemple #1
0
    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()
Exemple #4
0
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)
Exemple #5
0
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()
Exemple #6
0
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)
Exemple #7
0
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)
Exemple #9
0
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()
Exemple #10
0
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)
Exemple #11
0
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()
Exemple #12
0
    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
Exemple #13
0
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()
Exemple #14
0
    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()
Exemple #15
0
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()
Exemple #16
0
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()
Exemple #17
0
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
Exemple #18
0
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()
Exemple #19
0
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
Exemple #20
0
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
Exemple #21
0
### 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)
Exemple #22
0
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()
Exemple #24
0
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
Exemple #26
0
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()
Exemple #28
0
    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()
Exemple #29
0
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"
Exemple #30
0
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
Exemple #31
0
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()
Exemple #32
0
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
Exemple #33
0
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()
Exemple #36
0
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()
Exemple #37
0
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
Exemple #38
0
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)
Exemple #40
0
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)
Exemple #41
0
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()
Exemple #43
0
                      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()
Exemple #45
0
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
Exemple #46
0
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()
Exemple #47
0
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()
Exemple #48
0
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()
Exemple #49
0
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()
Exemple #51
0
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)
Exemple #52
0
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
Exemple #55
0
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