def setupCollisions(self):
        #make a collision traverser, set it to default
        base.cTrav = CollisionTraverser()
        
        
        #self.cHandler = CollisionHandlerEvent()
        self.cHandler = CollisionHandlerPusher()
        
        #set the pattern for the event sent on collision
        # "%in" is substituted with the name of the into object
        #self.cHandler.setInPattern("hit-%in")
        
        cSphere = CollisionSphere((0,0,0), 10) #panda is scaled way down!
        cNode = CollisionNode("vtol")
        cNode.addSolid(cSphere)
        #panda is *only* a from object
        cNode.setFromCollideMask(BitMask32.bit(0))
        cNode.setIntoCollideMask(BitMask32.allOff())
        cNodePath = self.vtol.attachNewNode(cNode)
#        cNodePath.show()
        base.cTrav.addCollider(cNodePath, self.cHandler)
        self.cHandler.addCollider(cNodePath, self.vtol)
        #for b1 in self.house2:
        cTube1 = CollisionTube((-0.4,3,3), (-0.4,3,20), 6.8)
        cTube2 = CollisionTube((-0.4,-3,3), (-0.4,-3,20), 6.8)
        cNode = CollisionNode("models/houses/building")
        cNode.addSolid(cTube1)
        cNode.addSolid(cTube2)
        cNodePath = self.house2.attachNewNode(cNode)
        cTube1 = CollisionTube((-0.4,3,3), (-0.4,3,20), 6.8)
        cTube2 = CollisionTube((-0.4,-3,3), (-0.4,-3,20), 6.8)
        cNode = CollisionNode("models/houses/church")
        cNode.addSolid(cTube1)
        cNode.addSolid(cTube2)
        cNodePath = self.house1.attachNewNode(cNode)
示例#2
0
 def __init__( self, name, camera=None, rootNp=None, fromCollideMask=None, pickTag=None ):
     gizmo_core.Object.__init__( self, name, camera, rootNp )
     
     self.fromCollideMask = fromCollideMask
     self.pickTag = pickTag
     
     self.selection = []
     self.node = None
     self.collEntry = None
     
     # Create a marquee
     self.marquee = gizmo_core.Marquee( '%sMarquee' % self.name )
     
     # Create collision nodes
     self.collTrav = CollisionTraverser()
     #self.collTrav.showCollisions( render )
     self.collHandler = CollisionHandlerQueue()
     self.pickerRay = CollisionRay()
     
     # Create collision ray
     pickerNode = CollisionNode( self.name )
     pickerNode.addSolid( self.pickerRay )
     pickerNode.setIntoCollideMask( BitMask32.allOff() )
     pickerNp = camera.attachNewNode( pickerNode )
     self.collTrav.addCollider( pickerNp, self.collHandler )
     
     # Create collision mask for the ray if one is specified
     if self.fromCollideMask is not None:
         pickerNode.setFromCollideMask( self.fromCollideMask )
     
     # Bind mouse button events
     eventNames = ['mouse1', 'control-mouse1', 'mouse1-up']
     for eventName in eventNames:
         self.accept( eventName, self.FireEvent, [eventName] )
示例#3
0
    def leftClick(self):
        self.mouse1Down = True

        #Collision traversal
        pickerNode = CollisionNode('mouseRay')
        pickerNP = base.camera.attachNewNode(pickerNode)
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        pickerRay = CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue()
        myTraverser.addCollider(pickerNP, myHandler)

        if base.mouseWatcherNode.hasMouse():

            mpos = base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
 
            myTraverser.traverse(render)
            # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
            if myHandler.getNumEntries() > 0:
            # This is so we get the closest object
                myHandler.sortEntries()
                pickedObj = myHandler.getEntry(0).getIntoNodePath()
                objTag = pickedObj.findNetTag('mouseCollisionTag').getTag('mouseCollisionTag')
                if objTag and len(objTag)>0:
                    messenger.send('object_click',[objTag])
        pickerNP.remove()
示例#4
0
文件: mousePicker.py 项目: LBdN/labs
 def __init__( self, name, camera=None, rootNp=None, fromCollideMask=None, pickTag=None, gizmos=None ):
     p3d.Object.__init__( self, name, camera, rootNp )
     self.fromCollideMask = fromCollideMask
     self.pickTag         = pickTag
     self.selection       = set([])
     self.node            = None
     self.np              = None
     self.collEntry       = None
     self.gizmos          = gizmos
     assert self.gizmos is not None
     # Create a marquee
     self.marquee = marquee.Marquee( '%sMarquee' % self.name )
     # Create collision ray
     self.pickerRay   = CollisionRay()
     # Create collision node
     pickerNode = CollisionNode( self.name )
     pickerNode.addSolid( self.pickerRay )
     pickerNode.setFromCollideMask( self.fromCollideMask )
     self.pickerNp = camera.attachNewNode( pickerNode )
     #pickerNp.setCollideMask(AXIS_COLLISION_MASK)
     self.collHandler = CollisionHandlerQueue()
     self.collTrav = CollisionTraverser()
     self.collTrav.showCollisions( render )
     self.collTrav.addCollider( self.pickerNp, self.collHandler )
     # Bind mouse button events
     eventNames = ['mouse1', 'control-mouse1', 'mouse1-up']
     for eventName in eventNames:
         self.accept( eventName, self.FireEvent, [eventName] )
     #==
     self.selectionCol = None
 def __init__( self, *args, **kwargs ):
     p3d.SingleTask.__init__( self, *args, **kwargs )
     
     self.fromCollideMask = kwargs.pop( 'fromCollideMask', None )
     
     self.node = None
     self.collEntry = None
     
     # Create collision nodes
     self.collTrav = CollisionTraverser()
     #self.collTrav.showCollisions( render )
     self.collHandler = CollisionHandlerQueue()
     self.pickerRay = CollisionRay()
     
     # Create collision ray
     pickerNode = CollisionNode( self.name )
     pickerNode.addSolid( self.pickerRay )
     pickerNode.setIntoCollideMask( BitMask32.allOff() )
     pickerNp = self.camera.attachNewNode( pickerNode )
     self.collTrav.addCollider( pickerNp, self.collHandler )
     
     # Create collision mask for the ray if one is specified
     if self.fromCollideMask is not None:
         pickerNode.setFromCollideMask( self.fromCollideMask )
     
     # Bind mouse button events
     eventNames = ['mouse1', 'control-mouse1', 'mouse1-up']
     for eventName in eventNames:
         self.accept( eventName, self.FireEvent, [eventName] )
示例#6
0
class ControleMouse():
    def __init__(self, render, camera):
        #Since we are using collision detection to do picking, we set it up like any other collision detection system with a traverser and a handler 
        self.picker = CollisionTraverser()            #Make a traverser 
        self.pq     = CollisionHandlerQueue()         #Make a handler 
        #Make a collision node for our picker ray 
        self.pickerNode = CollisionNode('mouseRay') 
        #Attach that node to the camera since the ray will need to be positioned relative to it 
        self.pickerNP = camera.attachNewNode(self.pickerNode) 
        #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it 
        self.pickerNode.setFromCollideMask(BitMask32.bit(1)) 
        self.pickerRay = CollisionRay()               #Make our ray 
        self.pickerNode.addSolid(self.pickerRay)      #Add it to the collision node 
        #Register the ray as something that can cause collisions 
        self.picker.addCollider(self.pickerNP, self.pq) 
        #self.picker.showCollisions(render) 
        
        self.pst = CollisionTraverser()            #Make a traverser 
        self.hqp     = CollisionHandlerQueue()         #Make a handler 
        #Make a collision node for our picker ray 
        
        self.pstNode = CollisionNode('mouseRaytoObj') 
        #Attach that node to the camera since the ray will need to be positioned relative to it 
        self.pstNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pstNode2 = camera.attachNewNode(self.pstNode) 
        self.pickerRayObj = CollisionRay()   
        #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it 
        #self.pstNode.setFromCollideMask(BitMask32.bit(1)) 
        self.pstNode.addSolid(self.pickerRayObj)      #Add it to the collision node 
        #Register the ray as something that can cause collisions 
        self.pst.addCollider(self.pstNode2, self.hqp) 
        #self.pst.showCollisions(render) 
示例#7
0
    def setupCollisions(self):

        #player sphere
        cPlayerSphere = CollisionSphere(Point3(0, 0, .5), 10)
        cPlayerNode = CollisionNode("Player")
        cPlayerNode.addSolid(cPlayerSphere)
        
        cPlayerNode.setFromCollideMask(BitMask32.bit(4))
        cPlayerNode.setIntoCollideMask(BitMask32(20))
        
        cPlayerNP = self.player.attachNewNode(cPlayerNode)
        self.cTrav.addCollider(cPlayerNP, self.playerGroundHandler)
        #self.cTrav.addCollider(cPlayerNP, self.cRocketHandler)
        #cPlayerNP.show()
        
        
        #enemy sphere
        cEnemySphere = CollisionSphere(Point3(0, 0, .5), 10)
        cEnemyNode = CollisionNode("Enemy")
        cEnemyNode.addSolid(cEnemySphere)
        
        cEnemyNode.setFromCollideMask(BitMask32.bit(4))
        cEnemyNode.setIntoCollideMask(BitMask32(18))
        
        cEnemyNP = self.enemy.attachNewNode(cEnemyNode)
        self.cTrav.addCollider(cEnemyNP, self.enemyGroundHandler)
    def pieThrow(self, avId, timestamp, heading, pos, power):
        toon = self.activity.getAvatar(avId)
        if toon is None:
            return
        tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, power)
        if avId == base.localAvatar.doId:
            flyPie.setTag('throwerId', str(avId))
            collSphere = CollisionSphere(0, 0, 0, 0.5)
            collSphere.setTangible(0)
            name = 'PieSphere-%d' % avId
            collSphereName = self.activity.uniqueName(name)
            collNode = CollisionNode(collSphereName)
            collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
            collNode.addSolid(collSphere)
            collNP = flyPie.attachNewNode(collNode)
            base.cTrav.addCollider(collNP, self.pieHandler)
            self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName
            self.accept(self.toonPieEventNames[collNP], self.handlePieCollision)
        else:
            player = self.players.get(avId)
            if player is not None:
                player.faceForward()

        def matchRunningAnim(toon = toon):
            toon.playingAnim = None
            toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed)

        newTossTrack = Sequence(tossTrack, Func(matchRunningAnim))
        pieTrack = Parallel(newTossTrack, pieTrack, name='PartyCogActivity.pieTrack-%d-%s' % (avId, timestamp))
        elapsedTime = globalClockDelta.localElapsedTime(timestamp)
        if elapsedTime < 16.0 / 24.0:
            elapsedTime = 16.0 / 24.0
        pieTrack.start(elapsedTime)
        self.pieIvals.append(pieTrack)
        self.toonPieTracks[avId] = pieTrack
示例#9
0
    def leftClick(self):
        self.mouse1Down = True

        #Collision traversal
        pickerNode = CollisionNode('mouseRay')
        pickerNP = base.camera.attachNewNode(pickerNode)
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        pickerRay = CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue()
        myTraverser.addCollider(pickerNP, myHandler)

        if base.mouseWatcherNode.hasMouse():

            mpos = base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            myTraverser.traverse(render)
            # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
            if myHandler.getNumEntries() > 0:
                # This is so we get the closest object
                myHandler.sortEntries()
                pickedObj = myHandler.getEntry(0).getIntoNodePath()
                objTag = pickedObj.findNetTag('mouseCollisionTag').getTag(
                    'mouseCollisionTag')
                if objTag and len(objTag) > 0:
                    messenger.send('object_click', [objTag])
        pickerNP.remove()
示例#10
0
    def __init__(self, *args, **kwargs):
        p3d.SingleTask.__init__(self, *args, **kwargs)

        self.fromCollideMask = kwargs.pop('fromCollideMask', None)

        self.node = None
        self.collEntry = None

        # Create collision nodes
        self.collTrav = CollisionTraverser()
        #self.collTrav.showCollisions( render )
        self.collHandler = CollisionHandlerQueue()
        self.pickerRay = CollisionRay()

        # Create collision ray
        pickerNode = CollisionNode(self.name)
        pickerNode.addSolid(self.pickerRay)
        pickerNode.setIntoCollideMask(BitMask32.allOff())
        pickerNp = self.camera.attachNewNode(pickerNode)
        self.collTrav.addCollider(pickerNp, self.collHandler)

        # Create collision mask for the ray if one is specified
        if self.fromCollideMask is not None:
            pickerNode.setFromCollideMask(self.fromCollideMask)

        # Bind mouse button events
        eventNames = ['mouse1', 'control-mouse1', 'mouse1-up']
        for eventName in eventNames:
            self.accept(eventName, self.FireEvent, [eventName])
示例#11
0
class Agent:
    def __init__(self, model, run, walk, startPos, scale, select,ralph,saysome):

        self.actor = Actor(model, {"run":run, "walk":walk})
        self.actor.reparentTo(render)
        self.actor.setScale(scale)
        self.actor.setPos(startPos)
        self.actor.setHpr(90,0,0)
        self.playerGUI = saysome
        self.myralph = ralph
        self.setAI()

        self.cTrav = CollisionTraverser()

        self.groundRay = CollisionRay(0,0,1000,0,0,-1)  
        self.groundCol = CollisionNode('dinoRay')
        self.groundCol.addSolid(self.groundRay)
        self.groundCol.setFromCollideMask(BitMask32.bit(1))
        self.groundCol.setIntoCollideMask(BitMask32.allOff())
        self.groundColNp = self.actor.attachNewNode(self.groundCol)
        self.groundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.groundColNp, self.groundHandler)

        self.sphere = CollisionSphere(0,0,5,13)
        self.spherecol = CollisionNode('dinoSphere')
        self.spherecol.addSolid(self.sphere)
        self.spherecol.setCollideMask(BitMask32.bit(1))
        self.dinocolhs = self.actor.attachNewNode(self.spherecol)

        #self.dinocolhs.show()
        #self.groundColNp.show()
        #self.cTrav.showCollisions(render)

    def setAI(self):
        #Creating AI World
        self.AIworld = AIWorld(render)
 
        self.AIchar = AICharacter("seeker",self.actor, 380, 50, 250)
        self.AIworld.addAiChar(self.AIchar)
        self.AIbehaviors = self.AIchar.getAiBehaviors()  
        self.AIbehaviors.pursue(self.myralph)

        self.actor.loop('run')
        
        #AI World update        
        taskMgr.add(self.AIUpdate,"AIUpdate")
        
    #to update the AIWorld    
    def AIUpdate(self,task):
        if self.playerGUI.getpausevalue():
            self.AIworld.update()            
        return Task.cont

    def setControl(self, control, value):
        self.controlMap[control] = value

    def getactor(self):
        return self.actor
示例#12
0
    def makeNodeLocator(self, environment):
        meshNode = CollisionNode("NavMeshNodeLocator")
        meshNode.setFromCollideMask(BitMask32.allOff())
        meshNode.setIntoCollideMask(OTPGlobals.PathFindingBitmask)

        self.polyHashToPID = {}

        for pId in self.polyToAngles:
            vertCount = 0
            corners = []
            for angle in self.polyToAngles[pId]:
                if angle != 180:
                    # It's a corner
                    corners.append(vertCount)
                vertCount += 1

            # XXX this code only works for square nodes at present
            # Unfortunately we can only make triangle or square CollisionPolygons on the fly
            assert len(corners) == 4

            #import pdb
            #pdb.set_trace()

            verts = []

            for vert in corners:
                verts.append(
                    (self.vertexCoords[self.polyToVerts[pId][vert]][0],
                     self.vertexCoords[self.polyToVerts[pId][vert]][1], 0))

            #import pdb
            #pdb.set_trace()

            poly = CollisionPolygon(verts[0], verts[1], verts[2], verts[3])

            assert poly not in self.polyHashToPID

            self.polyHashToPID[poly] = pId

            meshNode.addSolid(poly)

        ray = CollisionRay()
        ray.setDirection(0, 0, -1)
        ray.setOrigin(0, 0, 0)

        rayNode = CollisionNode("NavMeshRay")
        rayNode.setFromCollideMask(OTPGlobals.PathFindingBitmask)
        rayNode.setIntoCollideMask(BitMask32.allOff())
        rayNode.addSolid(ray)

        self.meshNodePath = environment.attachNewNode(meshNode)
        self.rayNodePath = environment.attachNewNode(rayNode)

        self.meshNodePath.setTwoSided(True)

        self.chq = CollisionHandlerQueue()
        self.traverser = CollisionTraverser()
        self.traverser.addCollider(self.rayNodePath, self.chq)
class RepairMousePicker:
    
    def __init__(self):
        self.pickerNode = CollisionNode('RepairMousePicker.pickerNode')
        self.pickerNP = base.cam2d.attachNewNode(self.pickerNode)
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.collisionTraverser = CollisionTraverser()
        self.collisionHandler = CollisionHandlerQueue()
        self.collisionTraverser.addCollider(self.pickerNP, self.collisionHandler)
        self.clearCollisionMask()
        self.orthographic = True

    
    def destroy(self):
        del self.pickerNode
        self.pickerNP.removeNode()
        del self.pickerNP
        del self.pickerRay
        del self.collisionTraverser
        del self.collisionHandler

    
    def setOrthographic(self, ortho):
        self.orthographic = ortho

    
    def setCollisionMask(self, mask):
        self.pickerNode.setFromCollideMask(mask)

    
    def clearCollisionMask(self):
        self.pickerNode.setFromCollideMask(BitMask32.allOff())

    
    def getCollisions(self, traverseRoot, useIntoNodePaths = False):
        if not base.mouseWatcherNode.hasMouse():
            return []
        
        mpos = base.mouseWatcherNode.getMouse()
        if self.orthographic:
            self.pickerRay.setFromLens(base.cam2d.node(), 0, 0)
            self.pickerNP.setPos(mpos.getX(), 0.0, mpos.getY())
        else:
            self.pickerRay.setFromLens(base.cam2d.node(), mpos.getX(), mpos.getY())
            self.pickerNP.setPos(0.0, 0.0, 0.0)
        self.collisionTraverser.traverse(traverseRoot)
        pickedObjects = []
        if useIntoNodePaths:
            for i in range(self.collisionHandler.getNumEntries()):
                pickedObjects.append(self.collisionHandler.getEntry(i).getIntoNodePath())
            
        else:
            for i in range(self.collisionHandler.getNumEntries()):
                pickedObjects.append(self.collisionHandler.getEntry(i))
            
        return pickedObjects
示例#14
0
    def _initCollisions(self):
        name = "CogdoMazeLock-%d" % self.id
        collSphere = CollisionSphere(0, 0, 0.0, 0.25)
        collSphere.setTangible(0)
        collNode = CollisionNode(name)
        collNode.setFromCollideMask(ToontownGlobals.CatchGameBitmask)
        collNode.addSolid(collSphere)
        self.model.attachNewNode(collNode)

        self.enterCollisionEventName = "enter" + name
示例#15
0
 def __init__(self):
     self.picker         = CollisionTraverser()            
     self.pickerQ        = CollisionHandlerQueue()         
     pickerCollN         = CollisionNode('heightChecker')       
     self.pickerNode     = render.attachNewNode(pickerCollN) 
     pickerCollN.setFromCollideMask(BitMask32.bit(1))         
     pickerCollN.setIntoCollideMask(BitMask32.allOff())         
     self.pickerRay      = CollisionRay(0,0,300,0,0,-1)                
     pickerCollN.addSolid(self.pickerRay)      
     self.picker.addCollider(self.pickerNode, self.pickerQ)
示例#16
0
 def __init__(self):
     self.picker         = CollisionTraverser()            
     self.pickerQ        = CollisionHandlerQueue()         
     pickerCollN         = CollisionNode('mouseRay')       
     pickerCamN          = base.camera.attachNewNode(pickerCollN) 
     pickerCollN.setFromCollideMask(BitMask32.bit(1))         
     pickerCollN.setIntoCollideMask(BitMask32.allOff())         
     self.pickerRay      = CollisionRay()                
     pickerCollN.addSolid(self.pickerRay)      
     self.picker.addCollider(pickerCamN, self.pickerQ) 
     self.accept('mouse1',self.pick)                
示例#17
0
    def pieThrow(self, avId, timestamp, heading, pos, power):
        """Show local or remote toon throwing a pie."""
        
        toon = self.activity.getAvatar(avId)
        
        if toon is None:
            return
        
        tossTrack, pieTrack, flyPie = self.getTossPieInterval(toon, pos[0], pos[1], pos[2] ,
                                                    heading, 0, 0, power)

        if avId == base.localAvatar.doId:
            flyPie.setTag('throwerId', str(avId))

            collSphere = CollisionSphere(0, 0, 0, 0.5)
            # Make the sphere intangible
            collSphere.setTangible(0)
            name = "PieSphere-%d" % avId
            collSphereName = self.activity.uniqueName(name)
            collNode = CollisionNode(collSphereName)
            collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
            collNode.addSolid(collSphere)
            collNP = flyPie.attachNewNode(collNode)

            base.cTrav.addCollider(collNP, self.pieHandler)
            
            self.toonPieEventNames[collNP] = 'pieHit-' + collSphereName
            self.accept(self.toonPieEventNames[collNP], self.handlePieCollision)
        else:
            player = self.players.get(avId)
            if player is not None:
                player.faceForward()
        
        def matchRunningAnim(toon=toon):
            toon.playingAnim = None
            toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed)
            
        newTossTrack = Sequence(tossTrack, Func(matchRunningAnim))
                                
        pieTrack = Parallel(
            newTossTrack,
            pieTrack,
            name="PartyCogActivity.pieTrack-%d-%s" % (avId, timestamp)
            )

        elapsedTime = globalClockDelta.localElapsedTime(timestamp)
        
        if elapsedTime < 16. / 24.:
            elapsedTime = 16. / 24. # make the pie fly immediately
            
        pieTrack.start(elapsedTime)
        
        self.pieIvals.append(pieTrack)
        self.toonPieTracks[avId] = pieTrack
 def createThrowGag(self, gag):
     throwGag = CogdoMazePlayer.createThrowGag(self, gag)
     collSphere = CollisionSphere(0, 0, 0, 0.5)
     collSphere.setTangible(0)
     name = Globals.GagCollisionName
     collNode = CollisionNode(name)
     collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
     collNode.addSolid(collSphere)
     colNp = throwGag.attachNewNode(collNode)
     base.cTrav.addCollider(colNp, self.gagHandler)
     return throwGag
示例#19
0
class RepairMousePicker:
    def __init__(self):
        self.pickerNode = CollisionNode('RepairMousePicker.pickerNode')
        self.pickerNP = base.cam2d.attachNewNode(self.pickerNode)
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.collisionTraverser = CollisionTraverser()
        self.collisionHandler = CollisionHandlerQueue()
        self.collisionTraverser.addCollider(self.pickerNP,
                                            self.collisionHandler)
        self.clearCollisionMask()
        self.orthographic = True

    def destroy(self):
        del self.pickerNode
        self.pickerNP.removeNode()
        del self.pickerNP
        del self.pickerRay
        del self.collisionTraverser
        del self.collisionHandler

    def setOrthographic(self, ortho):
        self.orthographic = ortho

    def setCollisionMask(self, mask):
        self.pickerNode.setFromCollideMask(mask)

    def clearCollisionMask(self):
        self.pickerNode.setFromCollideMask(BitMask32.allOff())

    def getCollisions(self, traverseRoot, useIntoNodePaths=False):
        if not base.mouseWatcherNode.hasMouse():
            return []

        mpos = base.mouseWatcherNode.getMouse()
        if self.orthographic:
            self.pickerRay.setFromLens(base.cam2d.node(), 0, 0)
            self.pickerNP.setPos(mpos.getX(), 0.0, mpos.getY())
        else:
            self.pickerRay.setFromLens(base.cam2d.node(), mpos.getX(),
                                       mpos.getY())
            self.pickerNP.setPos(0.0, 0.0, 0.0)
        self.collisionTraverser.traverse(traverseRoot)
        pickedObjects = []
        if useIntoNodePaths:
            for i in range(self.collisionHandler.getNumEntries()):
                pickedObjects.append(
                    self.collisionHandler.getEntry(i).getIntoNodePath())

        else:
            for i in range(self.collisionHandler.getNumEntries()):
                pickedObjects.append(self.collisionHandler.getEntry(i))

        return pickedObjects
 def getFlyBallBubble(self):
     if self.__flyBallBubble == None:
         bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS)
         node = CollisionNode('flyBallBubble')
         node.addSolid(bubble)
         node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask)
         node.setIntoCollideMask(BitMask32.allOff())
         self.__flyBallBubble = NodePath(node)
         self.flyBallHandler = CollisionHandlerEvent()
         self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index)
     return self.__flyBallBubble
示例#21
0
 def getFlyBallBubble(self):
     if self.__flyBallBubble == None:
         bubble = CollisionSphere(0, 0, 0, GolfGlobals.GOLF_BALL_RADIUS)
         node = CollisionNode('flyBallBubble')
         node.addSolid(bubble)
         node.setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask)
         node.setIntoCollideMask(BitMask32.allOff())
         self.__flyBallBubble = NodePath(node)
         self.flyBallHandler = CollisionHandlerEvent()
         self.flyBallHandler.addInPattern('flyBallHit-%d' % self.index)
     return self.__flyBallBubble
 def createThrowGag(self, gag):
     throwGag = CogdoMazePlayer.createThrowGag(self, gag)
     collSphere = CollisionSphere(0, 0, 0, 0.5)
     collSphere.setTangible(0)
     name = Globals.GagCollisionName
     collNode = CollisionNode(name)
     collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
     collNode.addSolid(collSphere)
     colNp = throwGag.attachNewNode(collNode)
     base.cTrav.addCollider(colNp, self.gagHandler)
     return throwGag
示例#23
0
文件: Controller.py 项目: crempp/psg
class Selector(object):
    '''A Selector listens for mouse clicks and then runs select. Select then
       broadcasts the selected tag (if there is one)'''
    def __init__(self):
        ''' Should the traverser be shared? '''

        LOG.debug("[Selector] Initializing")

        # The collision traverser does the checking of solids for collisions
        self.cTrav = CollisionTraverser()

        # The collision handler queue is a simple handler that records all
        # detected collisions during traversal
        self.cHandler = CollisionHandlerQueue()

        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.cTrav.addCollider(self.pickerNP, self.cHandler)

        # Start listening to clicks
        self.resume()

    def select(self, event):
        LOG.debug("[Selector] Selecting ")
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.cTrav.traverse(render)  # TODO - change this to a lower node
            if self.cHandler.getNumEntries() > 0:
                #LOG.debug("[Selector] Entries=%d"%self.cHandler.getNumEntries())
                self.cHandler.sortEntries()
                selectionNP = self.cHandler.getEntry(0).getIntoNodePath()
                selection = selectionNP.findNetTag('SelectorTag').getTag(
                    'SelectorTag')
                if selection is not '':
                    LOG.debug("[Selector] Collision with %s" % selection)
                    Event.Dispatcher().broadcast(
                        Event.Event('E_EntitySelect', src=self,
                                    data=selection))
                else:
                    LOG.debug("[Selector] No collision")
                    #Event.Dispatcher().broadcast(Event.Event('E_EntityUnSelect', src=self, data=selection))

    def pause(self):
        Event.Dispatcher().unregister(self, 'E_Mouse_1')

    def resume(self):
        print("unpausing selector")
        Event.Dispatcher().register(self, 'E_Mouse_1', self.select)
 def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius):
     cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75)
     cSphereNode = CollisionNode('Flyer.cFloorEventSphere')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     self.floorCollisionEvent = CollisionHandlerEvent()
     self.floorCollisionEvent.addInPattern('%fn-enter-%in')
     self.floorCollisionEvent.addAgainPattern('%fn-again-%in')
     self.floorCollisionEvent.addOutPattern('%fn-exit-%in')
     base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent)
     self.cFloorEventSphereNodePath = cSphereNodePath
 def setupEventSphere(self, bitmask, avatarRadius):
     self.avatarRadius = avatarRadius
     cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04)
     cSphere.setTangible(0)
     cSphereNode = CollisionNode('Flyer.cEventSphereNode')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     self.event = CollisionHandlerEvent()
     self.event.addInPattern('enter%in')
     self.event.addOutPattern('exit%in')
     self.cEventSphereNodePath = cSphereNodePath
 def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius):
     cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75)
     cSphereNode = CollisionNode('Flyer.cFloorEventSphere')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     self.floorCollisionEvent = CollisionHandlerEvent()
     self.floorCollisionEvent.addInPattern('%fn-enter-%in')
     self.floorCollisionEvent.addAgainPattern('%fn-again-%in')
     self.floorCollisionEvent.addOutPattern('%fn-exit-%in')
     base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent)
     self.cFloorEventSphereNodePath = cSphereNodePath
 def setupHeadSphere(self, avatarNodePath):
     collSphere = CollisionSphere(0, 0, 0, 1)
     collSphere.setTangible(1)
     collNode = CollisionNode('Flyer.cHeadCollSphere')
     collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask)
     collNode.setIntoCollideMask(BitMask32.allOff())
     collNode.addSolid(collSphere)
     self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode)
     self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0)
     self.headCollisionEvent = CollisionHandlerEvent()
     self.headCollisionEvent.addInPattern('%fn-enter-%in')
     self.headCollisionEvent.addOutPattern('%fn-exit-%in')
     base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent)
 def setupHeadSphere(self, avatarNodePath):
     collSphere = CollisionSphere(0, 0, 0, 1)
     collSphere.setTangible(1)
     collNode = CollisionNode('Flyer.cHeadCollSphere')
     collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask)
     collNode.setIntoCollideMask(BitMask32.allOff())
     collNode.addSolid(collSphere)
     self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode)
     self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0)
     self.headCollisionEvent = CollisionHandlerEvent()
     self.headCollisionEvent.addInPattern('%fn-enter-%in')
     self.headCollisionEvent.addOutPattern('%fn-exit-%in')
     base.cTrav.addCollider(self.cHeadSphereNodePath,
                            self.headCollisionEvent)
 def setupEventSphere(self, bitmask, avatarRadius):
     self.avatarRadius = avatarRadius
     cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75,
                               self.avatarRadius * 1.04)
     cSphere.setTangible(0)
     cSphereNode = CollisionNode('Flyer.cEventSphereNode')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     self.event = CollisionHandlerEvent()
     self.event.addInPattern('enter%in')
     self.event.addOutPattern('exit%in')
     self.cEventSphereNodePath = cSphereNodePath
 def setupWallSphere(self, bitmask, avatarRadius):
     self.avatarRadius = avatarRadius
     cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius)
     cSphereNode = CollisionNode('Flyer.cWallSphereNode')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     if config.GetBool('want-fluid-pusher', 0):
         self.pusher = CollisionHandlerFluidPusher()
     else:
         self.pusher = CollisionHandlerPusher()
     self.pusher.addCollider(cSphereNodePath, self.avatarNodePath)
     self.cWallSphereNodePath = cSphereNodePath
示例#31
0
class CogdoMazeExit(CogdoGameExit, DirectObject):
    __module__ = __name__
    EnterEventName = 'CogdoMazeDoor_Enter'

    def __init__(self):
        CogdoGameExit.__init__(self)
        self.revealed = False
        self._players = []
        self._initCollisions()

    def _initCollisions(self):
        collSphere = CollisionSphere(0, 0, 0, 3.0)
        collSphere.setTangible(0)
        self.collNode = CollisionNode(self.getName())
        self.collNode.addSolid(collSphere)
        self.collNP = self.attachNewNode(self.collNode)

    def destroy(self):
        self.ignoreAll()
        CogdoGameExit.destroy(self)

    def enable(self):
        self.collNode.setFromCollideMask(ToontownGlobals.WallBitmask)
        self.accept('enter' + self.getName(), self._handleEnterCollision)

    def disable(self):
        self.ignore('enter' + self.getName())
        self.collNode.setFromCollideMask(BitMask32(0))

    def _handleEnterCollision(self, collEntry):
        messenger.send(CogdoMazeExit.EnterEventName, [self])

    def onstage(self):
        self.unstash()
        self.enable()

    def offstage(self):
        self.stash()
        self.disable()

    def playerEntersDoor(self, player):
        if player not in self._players:
            self._players.append(player)
            self.toonEnters(player.toon)

    def getPlayerCount(self):
        return len(self._players)

    def hasPlayer(self, player):
        return player in self._players
示例#32
0
文件: Controller.py 项目: crempp/psg
class Selector(object):
    '''A Selector listens for mouse clicks and then runs select. Select then
       broadcasts the selected tag (if there is one)'''

    def __init__(self):
        ''' Should the traverser be shared? '''

        LOG.debug("[Selector] Initializing")

        # The collision traverser does the checking of solids for collisions
        self.cTrav = CollisionTraverser()

        # The collision handler queue is a simple handler that records all
        # detected collisions during traversal
        self.cHandler = CollisionHandlerQueue()

        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.cTrav.addCollider(self.pickerNP, self.cHandler)

        # Start listening to clicks
        self.resume()

    def select(self, event):
        LOG.debug("[Selector] Selecting ")
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.cTrav.traverse(render) # TODO - change this to a lower node
            if self.cHandler.getNumEntries() > 0:
                #LOG.debug("[Selector] Entries=%d"%self.cHandler.getNumEntries())
                self.cHandler.sortEntries()
                selectionNP = self.cHandler.getEntry(0).getIntoNodePath()
                selection = selectionNP.findNetTag('SelectorTag').getTag('SelectorTag')
                if selection is not '':
                    LOG.debug("[Selector] Collision with %s" % selection)
                    Event.Dispatcher().broadcast(Event.Event('E_EntitySelect', src=self, data=selection))
                else:
                    LOG.debug("[Selector] No collision")
                    #Event.Dispatcher().broadcast(Event.Event('E_EntityUnSelect', src=self, data=selection))

    def pause(self):
        Event.Dispatcher().unregister(self, 'E_Mouse_1')

    def resume(self):
        print("unpausing selector")
        Event.Dispatcher().register(self, 'E_Mouse_1', self.select)
 def setupWallSphere(self, bitmask, avatarRadius):
     self.avatarRadius = avatarRadius
     cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75,
                               self.avatarRadius)
     cSphereNode = CollisionNode('Flyer.cWallSphereNode')
     cSphereNode.addSolid(cSphere)
     cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
     cSphereNode.setFromCollideMask(bitmask)
     cSphereNode.setIntoCollideMask(BitMask32.allOff())
     if config.GetBool('want-fluid-pusher', 0):
         self.pusher = CollisionHandlerFluidPusher()
     else:
         self.pusher = CollisionHandlerPusher()
     self.pusher.addCollider(cSphereNodePath, self.avatarNodePath)
     self.cWallSphereNodePath = cSphereNodePath
 def setupRay(self, bitmask, floorOffset, reach):
     cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0)
     cRayNode = CollisionNode('Flyer.cRayNode')
     cRayNode.addSolid(cRay)
     self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
     cRayNode.setFromCollideMask(bitmask)
     cRayNode.setIntoCollideMask(BitMask32.allOff())
     self.lifter = CollisionHandlerGravity()
     self.lifter.setLegacyMode(self._legacyLifter)
     self.lifter.setGravity(self.getGravity(0))
     self.lifter.addInPattern('%fn-enter-%in')
     self.lifter.addAgainPattern('%fn-again-%in')
     self.lifter.addOutPattern('%fn-exit-%in')
     self.lifter.setOffset(floorOffset)
     self.lifter.setReach(reach)
     self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath)
 def setupRay(self, bitmask, floorOffset, reach):
     cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0)
     cRayNode = CollisionNode('Flyer.cRayNode')
     cRayNode.addSolid(cRay)
     self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
     cRayNode.setFromCollideMask(bitmask)
     cRayNode.setIntoCollideMask(BitMask32.allOff())
     self.lifter = CollisionHandlerGravity()
     self.lifter.setLegacyMode(self._legacyLifter)
     self.lifter.setGravity(self.getGravity(0))
     self.lifter.addInPattern('%fn-enter-%in')
     self.lifter.addAgainPattern('%fn-again-%in')
     self.lifter.addOutPattern('%fn-exit-%in')
     self.lifter.setOffset(floorOffset)
     self.lifter.setReach(reach)
     self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath)
示例#36
0
文件: Picker.py 项目: sambarza/bo
class Picker(object):
    '''
    classdocs
    '''

    def __init__(self, camera, mouseWatcherNode, camNode, things):
        '''
        Constructor
        '''
        
        self.mouseWatcherNode = mouseWatcherNode
        self.camNode = camNode
        self.things = things
        
        self.pickerRay = CollisionRay()
        
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.pickerNode.addSolid(self.pickerRay)
        
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pq       = CollisionHandlerQueue()      
        
        self.picker = CollisionTraverser()
        self.picker.addCollider(self.pickerNP, self.pq)
        
    def getMouseOn(self, mouse_x, mouse_y):
        
        #Set the position of the ray based on the mouse position
        self.pickerRay.setFromLens(self.camNode, mouse_x, mouse_y)
      
        self.picker.traverse(self.things.node)
        
        if self.pq.getNumEntries() > 0:
            #if we have hit something, sort the hits so that the closest
            #is first, and highlight that node
            self.pq.sortEntries()
            
            selectedNode = self.pq.getEntry(0).getIntoNode()
            
            selectedNodeId = selectedNode.getTag('nodeId')
            thingId        = selectedNode.getTag('ID')
            
            mouseOnInfo = MouseOnInfo(self.things.getById(thingId), thingId, selectedNode, selectedNodeId, mouse_x, mouse_y)
             
            return mouseOnInfo
                                        
示例#37
0
 def _initCollisions(self):
     self._camCollRay = CollisionRay()
     camCollNode = CollisionNode('CameraToonRay')
     camCollNode.addSolid(self._camCollRay)
     camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask)
     camCollNode.setIntoCollideMask(0)
     self._camCollNP = self._camera.attachNewNode(camCollNode)
     self._camCollNP.show()
     self._collOffset = Vec3(0, 0, 0.5)
     self._collHandler = CollisionHandlerQueue()
     self._collTrav = CollisionTraverser()
     self._collTrav.addCollider(self._camCollNP, self._collHandler)
     self._betweenCamAndToon = {}
     self._transNP = NodePath('trans')
     self._transNP.reparentTo(render)
     self._transNP.setTransparency(True)
     self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
     self._transNP.setBin('fixed', 10000)
 def _initCollisions(self):
     self._camCollRay = CollisionRay()
     camCollNode = CollisionNode('CameraToonRay')
     camCollNode.addSolid(self._camCollRay)
     camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask)
     camCollNode.setIntoCollideMask(0)
     self._camCollNP = self._camera.attachNewNode(camCollNode)
     self._camCollNP.show()
     self._collOffset = Vec3(0, 0, 0.5)
     self._collHandler = CollisionHandlerQueue()
     self._collTrav = CollisionTraverser()
     self._collTrav.addCollider(self._camCollNP, self._collHandler)
     self._betweenCamAndToon = {}
     self._transNP = NodePath('trans')
     self._transNP.reparentTo(render)
     self._transNP.setTransparency(True)
     self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
     self._transNP.setBin('fixed', 10000)
 def GenerateCollisionGeometry(geomFaces):
     collisionFaces = []
     
     for geomFace in geomFaces:
         tempVerts = list(geomFace.vertex)
         tempVerts.reverse()
         
         colPoly = CollisionPolygon(*tempVerts) 
         collision = CollisionNode('blockCollision')
         collision.addSolid(colPoly)
         collision.setFromCollideMask(BitMask32.allOff())
         
         if(geomFace.blockFace == BlockFace.TOP):
             collision.setIntoCollideMask(Globals.BLOCK_PICKER_BITMASK)
         else:
             collision.setIntoCollideMask(Globals.BLOCK_PICKER_BITMASK | Globals.WALL_BITMASK)
         
         collisionFaces.append(collision)
         
     return collisionFaces
示例#40
0
    def init_ui(self):
        self.cTrav = CollisionTraverser('ui_collision_traverser')
        self.collision_handler = CollisionHandlerQueue()
        picker_node = CollisionNode('mouse_click_ray')
        self.picker_node_path = self.camera.attachNewNode(picker_node)
        picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.picker_ray = CollisionRay()
        picker_node.addSolid(self.picker_ray)
        self.cTrav.addCollider(self.picker_node_path, self.collision_handler)

        '''
        #debug: make a visible line segment
        from pandac.PandaModules import LineSegs, LVecBase4f, NodePath
        seg_drawer = LineSegs()
        seg_drawer.setColor(LVecBase4f(1, 0, 0, 1)) #red
        seg_drawer.moveTo(0,0,0)
        seg_drawer.drawTo(0,100,0)
        NodePath(seg_drawer.create()).reparentTo(self.picker_node_path)
        '''

        self.accept('a', self.mouse_ray)
示例#41
0
    def createCollisionHandlers(self):
        # Create a new collision traverser instance. We will use this to determine
        # if any collisions occurred after performing movement.
        self.cTrav = CollisionTraverser()

        camGroundRay = CollisionRay()
        camGroundRay.setOrigin(0, 0, 1000)
        camGroundRay.setDirection(0, 0, -1)
        camGroundCol = CollisionNode('camRay')
        camGroundCol.addSolid(camGroundRay)
        camGroundCol.setFromCollideMask(BitMask32.bit(0))
        camGroundCol.setIntoCollideMask(BitMask32.allOff())
        camGroundColNp = base.camera.attachNewNode(camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(camGroundColNp, self.camGroundHandler)

        # register the collision pusher
        self.pusher = CollisionHandlerPusher()

        # register collision event pattern names
        self.pusher.addInPattern('col-%fn-into')
示例#42
0
 def placeCollectibles(self):
     self.placeCol = render.attachNewNode("Collectible-Placeholder")
     self.placeCol.setPos(0,0,0)
     
     # Add the health items to the placeCol node
     for i in range(self.numObjects):
         # Load in the health item model
         self.collect = loader.loadModel(MYDIR+"/ball/jack")
         self.collect.setPos(0,0,0)
         self.collect.setH(90)
         self.collect.setScale(2)
         self.collect.reparentTo(self.placeCol)
         
         self.placeItem(self.collect)
         
         # Add spherical collision detection
         colSphere = CollisionSphere(0,0,0,1)
         sphereNode = CollisionNode('colSphere')
         sphereNode.addSolid(colSphere)
         sphereNode.setFromCollideMask(BitMask32.allOff())
         sphereNode.setIntoCollideMask(BitMask32.bit(1))
         sphereNp = self.collect.attachNewNode(sphereNode)
    def showToonThrowingPie(self, avId, timestamp, heading, pos):
        toon = self.getAvatar(avId)
        if toon:
            (tossTrack, pieTrack, flyPie) = self.getTossPieInterval(toon, pos[0], pos[1], pos[2], heading, 0, 0, 0)
            
            def removePieFromTraverser(flyPie = flyPie):
                if base.cTrav:
                    if flyPie:
                        base.cTrav.removeCollider(flyPie)
                    
                

            if avId == self.localAvId:
                flyPie.setTag('throwerId', str(avId))
                collSphere = CollisionSphere(0, 0, 0, 0.5)
                collSphere.setTangible(0)
                name = 'PieSphere-%d' % avId
                collSphereName = self.uniqueName(name)
                collNode = CollisionNode(collSphereName)
                collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
                collNode.addSolid(collSphere)
                colNp = flyPie.attachNewNode(collNode)
                colNp.show()
                base.cTrav.addCollider(colNp, self.pieHandler)
                self.accept('pieHit-' + collSphereName, self.handlePieHitting)
            
            
            def matchRunningAnim(toon = toon):
                toon.playingAnim = None
                toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed)

            newTossTrack = Sequence(tossTrack, Func(matchRunningAnim))
            pieTrack = Parallel(newTossTrack, pieTrack)
            elapsedTime = globalClockDelta.localElapsedTime(timestamp)
            if elapsedTime < 16.0 / 24.0:
                elapsedTime = 16.0 / 24.0
            
            pieTrack.start(elapsedTime)
            self.toonPieTracks[avId] = pieTrack
    def showToonThrowingPie(self, avId, timestamp, heading, pos):
        toon = self.getAvatar(avId)
        if toon:
            (tossTrack, pieTrack,
             flyPie) = self.getTossPieInterval(toon, pos[0], pos[1], pos[2],
                                               heading, 0, 0, 0)

            def removePieFromTraverser(flyPie=flyPie):
                if base.cTrav:
                    if flyPie:
                        base.cTrav.removeCollider(flyPie)

            if avId == self.localAvId:
                flyPie.setTag('throwerId', str(avId))
                collSphere = CollisionSphere(0, 0, 0, 0.5)
                collSphere.setTangible(0)
                name = 'PieSphere-%d' % avId
                collSphereName = self.uniqueName(name)
                collNode = CollisionNode(collSphereName)
                collNode.setFromCollideMask(ToontownGlobals.PieBitmask)
                collNode.addSolid(collSphere)
                colNp = flyPie.attachNewNode(collNode)
                colNp.show()
                base.cTrav.addCollider(colNp, self.pieHandler)
                self.accept('pieHit-' + collSphereName, self.handlePieHitting)

            def matchRunningAnim(toon=toon):
                toon.playingAnim = None
                toon.setSpeed(toon.forwardSpeed, toon.rotateSpeed)

            newTossTrack = Sequence(tossTrack, Func(matchRunningAnim))
            pieTrack = Parallel(newTossTrack, pieTrack)
            elapsedTime = globalClockDelta.localElapsedTime(timestamp)
            if elapsedTime < 16.0 / 24.0:
                elapsedTime = 16.0 / 24.0

            pieTrack.start(elapsedTime)
            self.toonPieTracks[avId] = pieTrack
示例#45
0
    def gameLoop(self, task):
        #print "game task"

        # ***************** SET CAMERA ******************

        base.taskMgr.add(self.rotateCamera, "rotateCamera")

        self.game.setPlayer(self.player)

        # ***************** PICKABLE SHITS ***************
        # setup the pickable suqre planes on the board
        planes = []
        id_plane = 0
        for k in range(3):
            for i in range(3):
                #print "adding plane: ", id_plane
                p = addPlane(3)
                p.setPos(3 * i - 2.5, 3 * k - 2.5, 3.1)
                p.setTag('pickable', str(id_plane))
                p.hide()
                planes.append(p)
                id_plane += 1

        # set picks
        pickerNode = CollisionNode('mouseRay')
        pickerNP = self.cam.attachNewNode(pickerNode)
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        pickerNode.addSolid(self.pickerRay)
        #pickerNP.show()
        self.rayQueue = CollisionHandlerQueue()
        self.cTrav = CollisionTraverser()
        self.cTrav.addCollider(pickerNP, self.rayQueue)

        # set action in case of pick
        self.accept('mouse1', self.picked)
示例#46
0
class characterCollSystem():
    def __init__(self,rootNode,trav,id):
        self.GroundRay=CollisionRay(0,0,10,0,0,-1)
        self.GroundCol = CollisionNode('colDown_'+str(id))
        self.GroundCol.addSolid(self.GroundRay)
        self.GroundCol.setFromCollideMask(BitMask32.bit(1))
        self.GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.GroundColNp = rootNode.attachNewNode(self.GroundCol)
        #self.GroundColNp.show()
        self.GroundHandler = CollisionHandlerQueue()
        trav.addCollider(self.GroundColNp, self.GroundHandler)
        
        self.EnvDetector=CollisionSphere(0, 0, 1, 0.8)
        self.EnvCol = CollisionNode('colEnv_'+str(id))
        self.EnvCol.addSolid(self.EnvDetector)
        self.EnvCol.setFromCollideMask(BitMask32.bit(2))
        self.EnvCol.setIntoCollideMask(BitMask32.allOff())
        self.EnvColNp = rootNode.attachNewNode(self.EnvCol)
        #self.EnvColNp.show()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.EnvColNp, rootNode)
        trav.addCollider(self.EnvColNp, self.pusher)
            
        self.trav=trav
示例#47
0
    def __init__(self, name, world, pos):
        ActorNode.__init__(self, name)

        self.nodePath = NodePath(self)

        self.world = world

        # init the model or the Actor
        self.model = self.getModel()
        self.model.reparentTo(self.nodePath)

        self.nodePath.setPos(*pos)

        self.prevPos = self.nodePath.getPos()

        # collision detection
        fromObject = self.nodePath.attachNewNode(CollisionNode(name))
        self.addSolids(fromObject)
        fromObject.show()

        # setup the ground ray, needed for detecting the ground
        groundRay = CollisionRay()
        groundRay.setOrigin(0, 0, 1000)
        groundRay.setDirection(0, 0, -1)
        groundCol = CollisionNode('groundRay')
        groundCol.addSolid(groundRay)
        groundCol.setFromCollideMask(BitMask32.bit(0))
        groundCol.setIntoCollideMask(BitMask32.allOff())
        groundColNp = base.camera.attachNewNode(groundCol)
        self.groundHandler = CollisionHandlerQueue()
        self.world.cTrav.addCollider(groundColNp, self.groundHandler)

        #        self.world.cTrav.addCollider(fromObject, self.world.pusher)
        #        self.world.pusher.addCollider(fromObject, self.nodePath)

        self.postInit()
示例#48
0
class DistributedIceGame(DistributedMinigame.DistributedMinigame,
                         DistributedIceWorld.DistributedIceWorld):
    notify = directNotify.newCategory('DistributedIceGame')
    MaxLocalForce = 100
    MaxPhysicsForce = 25000

    def __init__(self, cr):
        DistributedMinigame.DistributedMinigame.__init__(self, cr)
        DistributedIceWorld.DistributedIceWorld.__init__(self, cr)
        self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGame', [
            State.State('off', self.enterOff, self.exitOff, ['inputChoice']),
            State.State(
                'inputChoice', self.enterInputChoice, self.exitInputChoice,
                ['waitServerChoices', 'moveTires', 'displayVotes', 'cleanup']),
            State.State('waitServerChoices', self.enterWaitServerChoices,
                        self.exitWaitServerChoices, ['moveTires', 'cleanup']),
            State.State('moveTires', self.enterMoveTires, self.exitMoveTires,
                        ['synch', 'cleanup']),
            State.State('synch', self.enterSynch, self.exitSynch,
                        ['inputChoice', 'scoring', 'cleanup']),
            State.State('scoring', self.enterScoring, self.exitScoring,
                        ['cleanup', 'finalResults', 'inputChoice']),
            State.State('finalResults', self.enterFinalResults,
                        self.exitFinalResults, ['cleanup']),
            State.State('cleanup', self.enterCleanup, self.exitCleanup, [])
        ], 'off', 'cleanup')
        self.addChildGameFSM(self.gameFSM)
        self.cameraThreeQuarterView = (0, -22, 45, 0, -62.890000000000001, 0)
        self.tireDict = {}
        self.forceArrowDict = {}
        self.canDrive = False
        self.timer = None
        self.timerStartTime = None
        self.curForce = 0
        self.curHeading = 0
        self.headingMomentum = 0.0
        self.forceMomentum = 0.0
        self.allTireInputs = None
        self.curRound = 0
        self.curMatch = 0
        self.controlKeyWarningLabel = DirectLabel(
            text=TTLocalizer.IceGameControlKeyWarning,
            text_fg=VBase4(1, 0, 0, 1),
            relief=None,
            pos=(0.0, 0, 0),
            scale=0.14999999999999999)
        self.controlKeyWarningLabel.hide()
        self.waitingMoveLabel = DirectLabel(
            text=TTLocalizer.IceGameWaitingForPlayersToFinishMove,
            text_fg=VBase4(1, 1, 1, 1),
            relief=None,
            pos=(-0.59999999999999998, 0, -0.75),
            scale=0.074999999999999997)
        self.waitingMoveLabel.hide()
        self.waitingSyncLabel = DirectLabel(
            text=TTLocalizer.IceGameWaitingForAISync,
            text_fg=VBase4(1, 1, 1, 1),
            relief=None,
            pos=(-0.59999999999999998, 0, -0.75),
            scale=0.074999999999999997)
        self.waitingSyncLabel.hide()
        self.infoLabel = DirectLabel(text='',
                                     text_fg=VBase4(0, 0, 0, 1),
                                     relief=None,
                                     pos=(0.0, 0, 0.69999999999999996),
                                     scale=0.074999999999999997)
        self.updateInfoLabel()
        self.lastForceArrowUpdateTime = 0
        self.sendForceArrowUpdateAsap = False
        self.treasures = []
        self.penalties = []
        self.obstacles = []
        self.controlKeyPressed = False
        self.controlKeyWarningIval = None

    def delete(self):
        DistributedIceWorld.DistributedIceWorld.delete(self)
        DistributedMinigame.DistributedMinigame.delete(self)
        if self.controlKeyWarningIval:
            self.controlKeyWarningIval.finish()
            self.controlKeyWarningIval = None

        self.controlKeyWarningLabel.destroy()
        del self.controlKeyWarningLabel
        self.waitingMoveLabel.destroy()
        del self.waitingMoveLabel
        self.waitingSyncLabel.destroy()
        del self.waitingSyncLabel
        self.infoLabel.destroy()
        del self.infoLabel
        for treasure in self.treasures:
            treasure.destroy()

        del self.treasures
        for penalty in self.penalties:
            penalty.destroy()

        del self.penalties
        for obstacle in self.obstacles:
            obstacle.removeNode()

        del self.obstacles
        del self.gameFSM

    def announceGenerate(self):
        DistributedMinigame.DistributedMinigame.announceGenerate(self)
        DistributedIceWorld.DistributedIceWorld.announceGenerate(self)
        self.debugTaskName = self.uniqueName('debugTask')

    def getTitle(self):
        return TTLocalizer.IceGameTitle

    def getInstructions(self):
        szId = self.getSafezoneId()
        numPenalties = IceGameGlobals.NumPenalties[szId]
        result = TTLocalizer.IceGameInstructions
        if numPenalties == 0:
            result = TTLocalizer.IceGameInstructionsNoTnt

        return result

    def getMaxDuration(self):
        return 0

    def load(self):
        self.notify.debug('load')
        DistributedMinigame.DistributedMinigame.load(self)
        self.music = base.loadMusic('phase_4/audio/bgm/MG_IceGame.mid')
        self.gameBoard = loader.loadModel(
            'phase_4/models/minigames/ice_game_icerink')
        background = loader.loadModel('phase_4/models/minigames/ice_game_2d')
        background.reparentTo(self.gameBoard)
        self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0)
        self.gameBoard.setScale(1.0)
        self.setupSimulation()
        index = 0
        for avId in self.avIdList:
            self.setupTire(avId, index)
            self.setupForceArrow(avId)
            index += 1

        for index in xrange(len(self.avIdList), 4):
            self.setupTire(-index, index)
            self.setupForceArrow(-index)

        self.showForceArrows(realPlayersOnly=True)
        self.westWallModel = NodePath()
        if not self.westWallModel.isEmpty():
            self.westWallModel.reparentTo(self.gameBoard)
            self.westWallModel.setPos(IceGameGlobals.MinWall[0],
                                      IceGameGlobals.MinWall[1], 0)
            self.westWallModel.setScale(4)

        self.eastWallModel = NodePath()
        if not self.eastWallModel.isEmpty():
            self.eastWallModel.reparentTo(self.gameBoard)
            self.eastWallModel.setPos(IceGameGlobals.MaxWall[0],
                                      IceGameGlobals.MaxWall[1], 0)
            self.eastWallModel.setScale(4)
            self.eastWallModel.setH(180)

        self.arrowKeys = ArrowKeys.ArrowKeys()
        self.target = loader.loadModel('phase_3/models/misc/sphere')
        self.target.setScale(0.01)
        self.target.reparentTo(self.gameBoard)
        self.target.setPos(0, 0, 0)
        self.scoreCircle = loader.loadModel(
            'phase_4/models/minigames/ice_game_score_circle')
        self.scoreCircle.setScale(0.01)
        self.scoreCircle.reparentTo(self.gameBoard)
        self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0)
        self.scoreCircle.setAlphaScale(0.5)
        self.scoreCircle.setTransparency(1)
        self.scoreCircle.hide()
        self.treasureModel = loader.loadModel(
            'phase_4/models/minigames/ice_game_barrel')
        self.penaltyModel = loader.loadModel(
            'phase_4/models/minigames/ice_game_tnt2')
        self.penaltyModel.setScale(0.75, 0.75, 0.69999999999999996)
        szId = self.getSafezoneId()
        obstacles = IceGameGlobals.Obstacles[szId]
        index = 0
        cubicObstacle = IceGameGlobals.ObstacleShapes[szId]
        for pos in obstacles:
            newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius)
            newObstacle = self.createObstacle(newPos, index, cubicObstacle)
            self.obstacles.append(newObstacle)
            index += 1

        self.countSound = loader.loadSfx(
            'phase_3.5/audio/sfx/tick_counter.mp3')
        self.treasureGrabSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_sfx_vine_game_bananas.mp3')
        self.penaltyGrabSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_cannon_fire_alt.mp3')
        self.tireSounds = []
        for tireIndex in xrange(4):
            tireHit = loader.loadSfx(
                'phase_4/audio/sfx/Golf_Hit_Barrier_1.mp3')
            wallHit = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.mp3')
            obstacleHit = loader.loadSfx(
                'phase_4/audio/sfx/Golf_Hit_Barrier_2.mp3')
            self.tireSounds.append({
                'tireHit': tireHit,
                'wallHit': wallHit,
                'obstacleHit': obstacleHit
            })

        self.arrowRotateSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_sfx_ice_force_rotate.wav')
        self.arrowUpSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.mp3')
        self.arrowDownSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.mp3')
        self.scoreCircleSound = loader.loadSfx(
            'phase_4/audio/sfx/MG_sfx_ice_scoring_1.mp3')

    def unload(self):
        self.notify.debug('unload')
        DistributedMinigame.DistributedMinigame.unload(self)
        del self.music
        self.gameBoard.removeNode()
        del self.gameBoard
        for forceArrow in self.forceArrowDict.values():
            forceArrow.removeNode()

        del self.forceArrowDict
        self.scoreCircle.removeNode()
        del self.scoreCircle
        del self.countSound

    def onstage(self):
        self.notify.debug('onstage')
        DistributedMinigame.DistributedMinigame.onstage(self)
        self.gameBoard.reparentTo(render)
        self._DistributedIceGame__placeToon(self.localAvId)
        self.moveCameraToTop()
        self.scorePanels = []
        base.playMusic(self.music, looping=1, volume=0.80000000000000004)

    def offstage(self):
        self.notify.debug('offstage')
        self.music.stop()
        self.gameBoard.hide()
        self.infoLabel.hide()
        for avId in self.tireDict:
            self.tireDict[avId]['tireNodePath'].hide()

        for panel in self.scorePanels:
            panel.cleanup()

        del self.scorePanels
        for obstacle in self.obstacles:
            obstacle.hide()

        for treasure in self.treasures:
            treasure.nodePath.hide()

        for penalty in self.penalties:
            penalty.nodePath.hide()

        for avId in self.avIdList:
            av = self.getAvatar(avId)
            if av:
                av.dropShadow.show()
                av.resetLOD()
                continue

        taskMgr.remove(self.uniqueName('aimtask'))
        self.arrowKeys.destroy()
        del self.arrowKeys
        DistributedMinigame.DistributedMinigame.offstage(self)

    def handleDisabledAvatar(self, avId):
        self.notify.debug('handleDisabledAvatar')
        self.notify.debug('avatar ' + str(avId) + ' disabled')
        DistributedMinigame.DistributedMinigame.handleDisabledAvatar(
            self, avId)

    def setGameReady(self):
        if not self.hasLocalToon:
            return None

        self.notify.debug('setGameReady')
        if DistributedMinigame.DistributedMinigame.setGameReady(self):
            return None

        for index in xrange(self.numPlayers):
            avId = self.avIdList[index]
            toon = self.getAvatar(avId)
            if toon:
                toon.reparentTo(render)
                self._DistributedIceGame__placeToon(avId)
                toon.forwardSpeed = 0
                toon.rotateSpeed = False
                toon.dropShadow.hide()
                toon.setAnimState('Sit')
                if avId in self.tireDict:
                    tireNp = self.tireDict[avId]['tireNodePath']
                    toon.reparentTo(tireNp)
                    toon.setY(1.0)
                    toon.setZ(-3)

                toon.startLookAround()
                continue

    def setGameStart(self, timestamp):
        if not self.hasLocalToon:
            return None

        self.notify.debug('setGameStart')
        DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp)
        for avId in self.remoteAvIdList:
            toon = self.getAvatar(avId)
            if toon:
                toon.stopLookAround()
                continue

        self.scores = [0] * self.numPlayers
        spacing = 0.40000000000000002
        for i in xrange(self.numPlayers):
            avId = self.avIdList[i]
            avName = self.getAvatarName(avId)
            scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(
                avId, avName)
            scorePanel.setScale(0.90000000000000002)
            scorePanel.setPos(0.75 - spacing * (self.numPlayers - 1 - i), 0.0,
                              0.875)
            scorePanel.makeTransparent(0.75)
            self.scorePanels.append(scorePanel)

        self.arrowKeys.setPressHandlers([
            self._DistributedIceGame__upArrowPressed,
            self._DistributedIceGame__downArrowPressed,
            self._DistributedIceGame__leftArrowPressed,
            self._DistributedIceGame__rightArrowPressed,
            self._DistributedIceGame__controlPressed
        ])

    def isInPlayState(self):
        if not self.gameFSM.getCurrentState():
            return False

        if not self.gameFSM.getCurrentState().getName() == 'play':
            return False

        return True

    def enterOff(self):
        self.notify.debug('enterOff')

    def exitOff(self):
        pass

    def enterInputChoice(self):
        self.notify.debug('enterInputChoice')
        self.forceLocalToonToTire()
        self.controlKeyPressed = False
        if self.curRound == 0:
            self.setupStartOfMatch()
        else:
            self.notify.debug('self.curRound = %s' % self.curRound)
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.hide()
        if self.timerStartTime != None:
            self.startTimer()

        self.showForceArrows(realPlayersOnly=True)
        self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0)
        self.localForceArrow().reparentTo(self.localTireNp())
        self.localForceArrow().setY(IceGameGlobals.TireRadius)
        self.localTireNp().headsUp(self.target)
        self.notify.debug('self.localForceArrow() heading = %s' %
                          self.localForceArrow().getH())
        self.curHeading = self.localTireNp().getH()
        self.curForce = 25
        self.updateLocalForceArrow()
        for avId in self.forceArrowDict:
            forceArrow = self.forceArrowDict[avId]
            forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0)
            tireNp = self.tireDict[avId]['tireNodePath']
            forceArrow.reparentTo(tireNp)
            forceArrow.setY(IceGameGlobals.TireRadius)
            tireNp.headsUp(self.target)
            self.updateForceArrow(avId, tireNp.getH(), 25)

        taskMgr.add(self._DistributedIceGame__aimTask,
                    self.uniqueName('aimtask'))
        if base.localAvatar.laffMeter:
            base.localAvatar.laffMeter.stop()

        self.sendForceArrowUpdateAsap = False

    def exitInputChoice(self):
        if not self.controlKeyPressed:
            if self.controlKeyWarningIval:
                self.controlKeyWarningIval.finish()
                self.controlKeyWarningIval = None

            self.controlKeyWarningIval = Sequence(
                Func(self.controlKeyWarningLabel.show),
                self.controlKeyWarningLabel.colorScaleInterval(
                    10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1,
                                                                   1)),
                Func(self.controlKeyWarningLabel.hide))
            self.controlKeyWarningIval.start()

        if self.timer != None:
            self.timer.destroy()
            self.timer = None

        self.timerStartTime = None
        self.hideForceArrows()
        self.arrowRotateSound.stop()
        self.arrowUpSound.stop()
        self.arrowDownSound.stop()
        taskMgr.remove(self.uniqueName('aimtask'))

    def enterWaitServerChoices(self):
        self.waitingMoveLabel.show()
        self.showForceArrows(True)

    def exitWaitServerChoices(self):
        self.waitingMoveLabel.hide()
        self.hideForceArrows()

    def enterMoveTires(self):
        for key in self.tireDict:
            body = self.tireDict[key]['tireBody']
            body.setAngularVel(0, 0, 0)
            body.setLinearVel(0, 0, 0)

        for index in xrange(len(self.allTireInputs)):
            input = self.allTireInputs[index]
            avId = self.avIdList[index]
            body = self.getTireBody(avId)
            degs = input[1] + 90
            tireNp = self.getTireNp(avId)
            tireH = tireNp.getH()
            self.notify.debug('tireH = %s' % tireH)
            radAngle = deg2Rad(degs)
            foo = NodePath('foo')
            dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0)
            self.notify.debug('dirVector is now=%s' % dirVector)
            inputForce = input[0]
            inputForce /= self.MaxLocalForce
            inputForce *= self.MaxPhysicsForce
            force = dirVector * inputForce
            self.notify.debug('adding force %s to %d' % (force, avId))
            body.addForce(force)

        self.enableAllTireBodies()
        self.totalPhysicsSteps = 0
        self.startSim()
        taskMgr.add(self._DistributedIceGame__moveTiresTask,
                    self.uniqueName('moveTiresTtask'))

    def exitMoveTires(self):
        self.forceLocalToonToTire()
        self.disableAllTireBodies()
        self.stopSim()
        self.notify.debug('total Physics steps = %d' % self.totalPhysicsSteps)
        taskMgr.remove(self.uniqueName('moveTiresTtask'))

    def enterSynch(self):
        self.waitingSyncLabel.show()

    def exitSynch(self):
        self.waitingSyncLabel.hide()

    def enterScoring(self):
        sortedByDistance = []
        for avId in self.avIdList:
            np = self.getTireNp(avId)
            pos = np.getPos()
            pos.setZ(0)
            sortedByDistance.append((avId, pos.length()))

        def compareDistance(x, y):
            if x[1] - y[1] > 0:
                return 1
            elif x[1] - y[1] < 0:
                return -1
            else:
                return 0

        sortedByDistance.sort(cmp=compareDistance)
        self.scoreMovie = Sequence()
        curScale = 0.01
        curTime = 0
        self.scoreCircle.setScale(0.01)
        self.scoreCircle.show()
        self.notify.debug('newScores = %s' % self.newScores)
        circleStartTime = 0
        for index in xrange(len(sortedByDistance)):
            distance = sortedByDistance[index][1]
            avId = sortedByDistance[index][0]
            scorePanelIndex = self.avIdList.index(avId)
            time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec
            if time < 0:
                time = 0.01

            scaleXY = distance + IceGameGlobals.TireRadius
            self.notify.debug('circleStartTime = %s' % circleStartTime)
            self.scoreMovie.append(
                Parallel(
                    LerpScaleInterval(self.scoreCircle, time,
                                      Point3(scaleXY, scaleXY, 1.0)),
                    SoundInterval(self.scoreCircleSound,
                                  duration=time,
                                  startTime=circleStartTime)))
            circleStartTime += time
            startScore = self.scorePanels[scorePanelIndex].getScore()
            destScore = self.newScores[scorePanelIndex]
            self.notify.debug('for avId %d, startScore=%d, newScores=%d' %
                              (avId, startScore, destScore))

            def increaseScores(t,
                               scorePanelIndex=scorePanelIndex,
                               startScore=startScore,
                               destScore=destScore):
                oldScore = self.scorePanels[scorePanelIndex].getScore()
                diff = destScore - startScore
                newScore = int(startScore + diff * t)
                if newScore > oldScore:
                    base.playSfx(self.countSound)

                self.scorePanels[scorePanelIndex].setScore(newScore)
                self.scores[scorePanelIndex] = newScore

            duration = (destScore -
                        startScore) * IceGameGlobals.ScoreCountUpRate
            tireNp = self.tireDict[avId]['tireNodePath']
            self.scoreMovie.append(
                Parallel(
                    LerpFunctionInterval(increaseScores, duration),
                    Sequence(
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 1, 1, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 1, 1, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0,
                                               VBase4(1, 1, 1, 1)))))
            curScale += distance

        self.scoreMovie.append(
            Func(self.sendUpdate, 'reportScoringMovieDone', []))
        self.scoreMovie.start()

    def exitScoring(self):
        self.scoreMovie.finish()
        self.scoreMovie = None
        self.scoreCircle.hide()

    def enterFinalResults(self):
        lerpTrack = Parallel()
        lerpDur = 0.5
        tY = 0.59999999999999998
        bY = -0.050000000000000003
        lX = -0.5
        cX = 0
        rX = 0.5
        scorePanelLocs = (((cX, bY), ), ((lX, bY), (rX, bY)),
                          ((cX, tY), (lX, bY), (rX, bY)), ((lX, tY), (rX, tY),
                                                           (lX, bY), (rX, bY)))
        scorePanelLocs = scorePanelLocs[self.numPlayers - 1]
        for i in xrange(self.numPlayers):
            panel = self.scorePanels[i]
            pos = scorePanelLocs[i]
            lerpTrack.append(
                Parallel(
                    LerpPosInterval(panel,
                                    lerpDur,
                                    Point3(pos[0], 0, pos[1]),
                                    blendType='easeInOut'),
                    LerpScaleInterval(panel,
                                      lerpDur,
                                      Vec3(panel.getScale()) * 2.0,
                                      blendType='easeInOut')))

        self.showScoreTrack = Parallel(
            lerpTrack,
            Sequence(Wait(IceGameGlobals.ShowScoresDuration),
                     Func(self.gameOver)))
        self.showScoreTrack.start()

    def exitFinalResults(self):
        self.showScoreTrack.pause()
        del self.showScoreTrack

    def enterCleanup(self):
        self.notify.debug('enterCleanup')
        if base.localAvatar.laffMeter:
            base.localAvatar.laffMeter.start()

    def exitCleanup(self):
        pass

    def _DistributedIceGame__placeToon(self, avId):
        toon = self.getAvatar(avId)
        if toon:
            toon.setPos(0, 0, 0)
            toon.setHpr(0, 0, 0)

    def moveCameraToTop(self):
        camera.reparentTo(render)
        p = self.cameraThreeQuarterView
        camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5])

    def setupTire(self, avId, index):
        (tireNp, tireBody, tireOdeGeom) = self.createTire(index)
        self.tireDict[avId] = {
            'tireNodePath': tireNp,
            'tireBody': tireBody,
            'tireOdeGeom': tireOdeGeom
        }
        if avId <= 0:
            tireBlocker = tireNp.find('**/tireblockermesh')
            if not tireBlocker.isEmpty():
                tireBlocker.hide()

        if avId == self.localAvId:
            tireNp = self.tireDict[avId]['tireNodePath']
            self.treasureSphereName = 'treasureCollider'
            self.treasureCollSphere = CollisionSphere(
                0, 0, 0, IceGameGlobals.TireRadius)
            self.treasureCollSphere.setTangible(0)
            self.treasureCollNode = CollisionNode(self.treasureSphereName)
            self.treasureCollNode.setFromCollideMask(
                ToontownGlobals.PieBitmask)
            self.treasureCollNode.addSolid(self.treasureCollSphere)
            self.treasureCollNodePath = tireNp.attachNewNode(
                self.treasureCollNode)
            self.treasureHandler = CollisionHandlerEvent()
            self.treasureHandler.addInPattern('%fn-intoTreasure')
            base.cTrav.addCollider(self.treasureCollNodePath,
                                   self.treasureHandler)
            eventName = '%s-intoTreasure' % self.treasureCollNodePath.getName()
            self.notify.debug('eventName = %s' % eventName)
            self.accept(eventName, self.toonHitSomething)

    def setupForceArrow(self, avId):
        arrow = loader.loadModel('phase_4/models/minigames/ice_game_arrow')
        priority = 0
        if avId < 0:
            priority = -avId
        else:
            priority = self.avIdList.index(avId)
            if avId == self.localAvId:
                priority = 10

        self.forceArrowDict[avId] = arrow

    def hideForceArrows(self):
        for forceArrow in self.forceArrowDict.values():
            forceArrow.hide()

    def showForceArrows(self, realPlayersOnly=True):
        for avId in self.forceArrowDict:
            if realPlayersOnly:
                if avId > 0:
                    self.forceArrowDict[avId].show()
                else:
                    self.forceArrowDict[avId].hide()
            avId > 0
            self.forceArrowDict[avId].show()

    def localForceArrow(self):
        if self.localAvId in self.forceArrowDict:
            return self.forceArrowDict[self.localAvId]
        else:
            return None

    def setChoices(self, input0, input1, input2, input3):
        pass

    def startDebugTask(self):
        taskMgr.add(self.debugTask, self.debugTaskName)

    def stopDebugTask(self):
        taskMgr.remove(self.debugTaskName)

    def debugTask(self, task):
        if self.canDrive and self.tireDict.has_key(localAvatar.doId):
            dt = globalClock.getDt()
            forceMove = 25000
            forceMoveDt = forceMove
            tireBody = self.tireDict[localAvatar.doId]['tireBody']
            if self.arrowKeys.upPressed() and not tireBody.isEnabled():
                x = 0
                y = 1
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))

            if self.arrowKeys.downPressed() and not tireBody.isEnabled():
                x = 0
                y = -1
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))

            if self.arrowKeys.leftPressed() and not tireBody.isEnabled():
                x = -1
                y = 0
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))

            if self.arrowKeys.rightPressed() and not tireBody.isEnabled():
                x = 1
                y = 0
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))

        return task.cont

    def _DistributedIceGame__upArrowPressed(self):
        pass

    def _DistributedIceGame__downArrowPressed(self):
        pass

    def _DistributedIceGame__leftArrowPressed(self):
        pass

    def _DistributedIceGame__rightArrowPressed(self):
        pass

    def _DistributedIceGame__controlPressed(self):
        if self.gameFSM.getCurrentState().getName() == 'inputChoice':
            self.sendForceArrowUpdateAsap = True
            self.updateLocalForceArrow()
            self.controlKeyPressed = True
            self.sendUpdate('setAvatarChoice',
                            [self.curForce, self.curHeading])
            self.gameFSM.request('waitServerChoices')

    def startTimer(self):
        now = globalClock.getFrameTime()
        elapsed = now - self.timerStartTime
        self.timer.posInTopRightCorner()
        self.timer.setTime(IceGameGlobals.InputTimeout)
        self.timer.countdown(IceGameGlobals.InputTimeout - elapsed,
                             self.handleChoiceTimeout)
        self.timer.show()

    def setTimerStartTime(self, timestamp):
        if not self.hasLocalToon:
            return None

        self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp)
        if self.timer != None:
            self.startTimer()

    def handleChoiceTimeout(self):
        self.sendUpdate('setAvatarChoice', [0, 0])
        self.gameFSM.request('waitServerChoices')

    def localTireNp(self):
        ret = None
        if self.localAvId in self.tireDict:
            ret = self.tireDict[self.localAvId]['tireNodePath']

        return ret

    def localTireBody(self):
        ret = None
        if self.localAvId in self.tireDict:
            ret = self.tireDict[self.localAvId]['tireBody']

        return ret

    def getTireBody(self, avId):
        ret = None
        if avId in self.tireDict:
            ret = self.tireDict[avId]['tireBody']

        return ret

    def getTireNp(self, avId):
        ret = None
        if avId in self.tireDict:
            ret = self.tireDict[avId]['tireNodePath']

        return ret

    def updateForceArrow(self, avId, curHeading, curForce):
        forceArrow = self.forceArrowDict[avId]
        tireNp = self.tireDict[avId]['tireNodePath']
        tireNp.setH(curHeading)
        tireBody = self.tireDict[avId]['tireBody']
        tireBody.setQuaternion(tireNp.getQuat())
        self.notify.debug('curHeading = %s' % curHeading)
        yScale = curForce / 100.0
        yScale *= 1
        headY = yScale * 15
        xScale = (yScale - 1) / 2.0 + 1.0
        shaft = forceArrow.find('**/arrow_shaft')
        head = forceArrow.find('**/arrow_head')
        shaft.setScale(xScale, yScale, 1)
        head.setPos(0, headY, 0)
        head.setScale(xScale, xScale, 1)

    def updateLocalForceArrow(self):
        avId = self.localAvId
        self.b_setForceArrowInfo(avId, self.curHeading, self.curForce)

    def _DistributedIceGame__aimTask(self, task):
        if not hasattr(self, 'arrowKeys'):
            return task.done

        dt = globalClock.getDt()
        headingMomentumChange = dt * 60.0
        forceMomentumChange = dt * 160.0
        arrowUpdate = False
        arrowRotating = False
        arrowUp = False
        arrowDown = False
        if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed():
            self.forceMomentum += forceMomentumChange
            if self.forceMomentum < 0:
                self.forceMomentum = 0

            if self.forceMomentum > 50:
                self.forceMomentum = 50

            oldForce = self.curForce
            self.curForce += self.forceMomentum * dt
            arrowUpdate = True
            if oldForce < self.MaxLocalForce:
                arrowUp = True

        elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed():
            self.forceMomentum += forceMomentumChange
            if self.forceMomentum < 0:
                self.forceMomentum = 0

            if self.forceMomentum > 50:
                self.forceMomentum = 50

            oldForce = self.curForce
            self.curForce -= self.forceMomentum * dt
            arrowUpdate = True
            if oldForce > 0.01:
                arrowDown = True

        else:
            self.forceMomentum = 0
        if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed():
            self.headingMomentum += headingMomentumChange
            if self.headingMomentum < 0:
                self.headingMomentum = 0

            if self.headingMomentum > 50:
                self.headingMomentum = 50

            self.curHeading += self.headingMomentum * dt
            arrowUpdate = True
            arrowRotating = True
        elif self.arrowKeys.rightPressed(
        ) and not self.arrowKeys.leftPressed():
            self.headingMomentum += headingMomentumChange
            if self.headingMomentum < 0:
                self.headingMomentum = 0

            if self.headingMomentum > 50:
                self.headingMomentum = 50

            self.curHeading -= self.headingMomentum * dt
            arrowUpdate = True
            arrowRotating = True
        else:
            self.headingMomentum = 0
        if arrowUpdate:
            self.normalizeHeadingAndForce()
            self.updateLocalForceArrow()

        if arrowRotating:
            if not self.arrowRotateSound.status(
            ) == self.arrowRotateSound.PLAYING:
                base.playSfx(self.arrowRotateSound, looping=True)

        else:
            self.arrowRotateSound.stop()
        if arrowUp:
            if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING:
                base.playSfx(self.arrowUpSound, looping=False)

        else:
            self.arrowUpSound.stop()
        if arrowDown:
            if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING:
                base.playSfx(self.arrowDownSound, looping=False)

        else:
            self.arrowDownSound.stop()
        return task.cont

    def normalizeHeadingAndForce(self):
        if self.curForce > self.MaxLocalForce:
            self.curForce = self.MaxLocalForce

        if self.curForce < 0.01:
            self.curForce = 0.01

    def setTireInputs(self, tireInputs):
        if not self.hasLocalToon:
            return None

        self.allTireInputs = tireInputs
        self.gameFSM.request('moveTires')

    def enableAllTireBodies(self):
        for avId in self.tireDict.keys():
            self.tireDict[avId]['tireBody'].enable()

    def disableAllTireBodies(self):
        for avId in self.tireDict.keys():
            self.tireDict[avId]['tireBody'].disable()

    def areAllTiresDisabled(self):
        for avId in self.tireDict.keys():
            if self.tireDict[avId]['tireBody'].isEnabled():
                return False
                continue

        return True

    def _DistributedIceGame__moveTiresTask(self, task):
        if self.areAllTiresDisabled():
            self.sendTirePositions()
            self.gameFSM.request('synch')
            return task.done

        return task.cont

    def sendTirePositions(self):
        tirePositions = []
        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            tire = self.getTireBody(avId)
            pos = Point3(tire.getPosition())
            tirePositions.append([pos[0], pos[1], pos[2]])

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            tire = self.getTireBody(avId)
            pos = Point3(tire.getPosition())
            tirePositions.append([pos[0], pos[1], pos[2]])

        self.sendUpdate('endingPositions', [tirePositions])

    def setFinalPositions(self, finalPos):
        if not self.hasLocalToon:
            return None

        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            tire = self.getTireBody(avId)
            np = self.getTireNp(avId)
            pos = finalPos[index]
            tire.setPosition(pos[0], pos[1], pos[2])
            np.setPos(pos[0], pos[1], pos[2])

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            tire = self.getTireBody(avId)
            np = self.getTireNp(avId)
            pos = finalPos[index]
            tire.setPosition(pos[0], pos[1], pos[2])
            np.setPos(pos[0], pos[1], pos[2])

    def updateInfoLabel(self):
        self.infoLabel['text'] = TTLocalizer.IceGameInfo % {
            'curMatch': self.curMatch + 1,
            'numMatch': IceGameGlobals.NumMatches,
            'curRound': self.curRound + 1,
            'numRound': IceGameGlobals.NumRounds
        }

    def setMatchAndRound(self, match, round):
        if not self.hasLocalToon:
            return None

        self.curMatch = match
        self.curRound = round
        self.updateInfoLabel()

    def setScores(self, match, round, scores):
        if not self.hasLocalToon:
            return None

        self.newMatch = match
        self.newRound = round
        self.newScores = scores

    def setNewState(self, state):
        if not self.hasLocalToon:
            return None

        self.notify.debug('setNewState gameFSM=%s newState=%s' %
                          (self.gameFSM, state))
        self.gameFSM.request(state)

    def putAllTiresInStartingPositions(self):
        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            np = self.tireDict[avId]['tireNodePath']
            np.setPos(IceGameGlobals.StartingPositions[index])
            self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos))
            np.setHpr(0, 0, 0)
            quat = np.getQuat()
            body = self.tireDict[avId]['tireBody']
            body.setPosition(IceGameGlobals.StartingPositions[index])
            body.setQuaternion(quat)

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            np = self.tireDict[avId]['tireNodePath']
            np.setPos(IceGameGlobals.StartingPositions[index])
            self.notify.debug('avId=%s newPos=%s' % (avId, np.getPos))
            np.setHpr(0, 0, 0)
            quat = np.getQuat()
            body = self.tireDict[avId]['tireBody']
            body.setPosition(IceGameGlobals.StartingPositions[index])
            body.setQuaternion(quat)

    def b_setForceArrowInfo(self, avId, force, heading):
        self.setForceArrowInfo(avId, force, heading)
        self.d_setForceArrowInfo(avId, force, heading)

    def d_setForceArrowInfo(self, avId, force, heading):
        sendIt = False
        curTime = self.getCurrentGameTime()
        if self.sendForceArrowUpdateAsap:
            sendIt = True
        elif curTime - self.lastForceArrowUpdateTime > 0.20000000000000001:
            sendIt = True

        if sendIt:
            self.sendUpdate('setForceArrowInfo', [avId, force, heading])
            self.sendForceArrowUpdateAsap = False
            self.lastForceArrowUpdateTime = self.getCurrentGameTime()

    def setForceArrowInfo(self, avId, force, heading):
        if not self.hasLocalToon:
            return None

        self.updateForceArrow(avId, force, heading)

    def setupStartOfMatch(self):
        self.putAllTiresInStartingPositions()
        szId = self.getSafezoneId()
        self.numTreasures = IceGameGlobals.NumTreasures[szId]
        if self.treasures:
            for treasure in self.treasures:
                treasure.destroy()

            self.treasures = []

        index = 0
        treasureMargin = IceGameGlobals.TireRadius + 1.0
        while len(self.treasures) < self.numTreasures:
            xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5,
                                               IceGameGlobals.MaxWall[0] - 5)
            yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5,
                                               IceGameGlobals.MaxWall[1] - 5)
            self.notify.debug('yPos=%s' % yPos)
            pos = Point3(xPos, yPos, IceGameGlobals.TireRadius)
            newTreasure = IceTreasure.IceTreasure(self.treasureModel,
                                                  pos,
                                                  index,
                                                  self.doId,
                                                  penalty=False)
            goodSpot = True
            for obstacle in self.obstacles:
                if newTreasure.nodePath.getDistance(obstacle) < treasureMargin:
                    goodSpot = False
                    break
                    continue

            if goodSpot:
                for treasure in self.treasures:
                    if newTreasure.nodePath.getDistance(
                            treasure.nodePath) < treasureMargin:
                        goodSpot = False
                        break
                        continue

            if goodSpot:
                self.treasures.append(newTreasure)
                index += 1
                continue
            newTreasure.destroy()
        self.numPenalties = IceGameGlobals.NumPenalties[szId]
        if self.penalties:
            for penalty in self.penalties:
                penalty.destroy()

            self.penalties = []

        index = 0
        while len(self.penalties) < self.numPenalties:
            xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5,
                                               IceGameGlobals.MaxWall[0] - 5)
            yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5,
                                               IceGameGlobals.MaxWall[1] - 5)
            self.notify.debug('yPos=%s' % yPos)
            pos = Point3(xPos, yPos, IceGameGlobals.TireRadius)
            newPenalty = IceTreasure.IceTreasure(self.penaltyModel,
                                                 pos,
                                                 index,
                                                 self.doId,
                                                 penalty=True)
            goodSpot = True
            for obstacle in self.obstacles:
                if newPenalty.nodePath.getDistance(obstacle) < treasureMargin:
                    goodSpot = False
                    break
                    continue

            if goodSpot:
                for treasure in self.treasures:
                    if newPenalty.nodePath.getDistance(
                            treasure.nodePath) < treasureMargin:
                        goodSpot = False
                        break
                        continue

            if goodSpot:
                for penalty in self.penalties:
                    if newPenalty.nodePath.getDistance(
                            penalty.nodePath) < treasureMargin:
                        goodSpot = False
                        break
                        continue

            if goodSpot:
                self.penalties.append(newPenalty)
                index += 1
                continue
            newPenalty.destroy()

    def toonHitSomething(self, entry):
        self.notify.debug('---- treasure Enter ---- ')
        self.notify.debug('%s' % entry)
        name = entry.getIntoNodePath().getName()
        parts = name.split('-')
        if len(parts) < 3:
            self.notify.debug('collided with %s, but returning' % name)
            return None

        if not int(parts[1]) == self.doId:
            self.notify.debug("collided with %s, but doId doesn't match" %
                              name)
            return None

        treasureNum = int(parts[2])
        if 'penalty' in parts[0]:
            self._DistributedIceGame__penaltyGrabbed(treasureNum)
        else:
            self._DistributedIceGame__treasureGrabbed(treasureNum)

    def _DistributedIceGame__treasureGrabbed(self, treasureNum):
        self.treasures[treasureNum].showGrab()
        self.treasureGrabSound.play()
        self.sendUpdate('claimTreasure', [treasureNum])

    def setTreasureGrabbed(self, avId, treasureNum):
        if not self.hasLocalToon:
            return None

        self.notify.debug('treasure %s grabbed by %s' % (treasureNum, avId))
        if avId != self.localAvId:
            self.treasures[treasureNum].showGrab()

        i = self.avIdList.index(avId)
        self.scores[i] += 1
        self.scorePanels[i].setScore(self.scores[i])

    def _DistributedIceGame__penaltyGrabbed(self, penaltyNum):
        self.penalties[penaltyNum].showGrab()
        self.sendUpdate('claimPenalty', [penaltyNum])

    def setPenaltyGrabbed(self, avId, penaltyNum):
        if not self.hasLocalToon:
            return None

        self.notify.debug('penalty %s grabbed by %s' % (penaltyNum, avId))
        if avId != self.localAvId:
            self.penalties[penaltyNum].showGrab()

        i = self.avIdList.index(avId)
        self.scores[i] -= 1
        self.scorePanels[i].setScore(self.scores[i])

    def postStep(self):
        DistributedIceWorld.DistributedIceWorld.postStep(self)
        for count in range(self.colCount):
            (c0, c1) = self.getOrderedContacts(count)
            if c1 in self.tireCollideIds:
                tireIndex = self.tireCollideIds.index(c1)
                if c0 in self.tireCollideIds:
                    self.tireSounds[tireIndex]['tireHit'].play()
                elif c0 == self.wallCollideId:
                    self.tireSounds[tireIndex]['wallHit'].play()
                elif c0 == self.obstacleCollideId:
                    self.tireSounds[tireIndex]['obstacleHit'].play()

            c0 in self.tireCollideIds

    def forceLocalToonToTire(self):
        toon = localAvatar
        if toon and self.localAvId in self.tireDict:
            tireNp = self.tireDict[self.localAvId]['tireNodePath']
            toon.reparentTo(tireNp)
            toon.setPosHpr(0, 0, 0, 0, 0, 0)
            toon.setY(1.0)
            toon.setZ(-3)
示例#49
0
class cameraCollisionClass:
  def __init__( self ):
    self.collisionCheckSetup()
    
  def collisionCheckSetup( self ):
    print "setting up collision check"
    #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.cameraGroundRay = CollisionRay()     #Create the ray
    self.cameraGroundRay.setOrigin(0,0,0.0)    #Set its origin
    self.cameraGroundRay.setDirection(0,0,-1.0) #And its direction
    #Collision solids go in CollisionNode
    self.cameraGroundCol = CollisionNode('cameraGroundRay') #Create and name the node
    self.cameraGroundCol.addSolid(self.cameraGroundRay) #Add the ray
    self.cameraGroundCol.setFromCollideMask(bitMaskOr([GROUND])) #Set its bitmasks
    self.cameraGroundCol.setIntoCollideMask(bitMaskOr([]))
    #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.cameraGroundColNp = base.camera.attachNewNode(self.cameraGroundCol)
    ### the ground controller is allways looking down NOT ACTIVE
    self.horizontalCameraNode = base.camera.attachNewNode('horizontalCameraNode')
    self.horizontalCameraNode.reparentTo( base.camera )
    self.cameraGroundColNp = self.horizontalCameraNode.attachNewNode(self.cameraGroundCol)
    
    #Uncomment this line to see the ray
    #self.cameraGroundColNp.show()
    '''
    # the camera forward rays look in the direction of the camera
    self.cameraFrontRay = CollisionRay()     #Create the ray
    self.cameraFrontRay.setOrigin   (0,-1,0)    #Set its origin
    self.cameraFrontRay.setDirection(0, 5,0) #And its direction
    self.cameraFrontCol = CollisionNode('cameraFrontRay') #Create and name the node
    self.cameraFrontCol.addSolid(self.cameraFrontRay) #Add the ray
    self.cameraFrontCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks
    self.cameraFrontCol.setIntoCollideMask(bitMaskOr([]))
    self.cameraFrontColNp = base.camera.attachNewNode(self.cameraFrontCol)
    #self.cameraFrontColNp.show()
    
    self.cameraBackRay = CollisionRay()     #Create the ray
    self.cameraBackRay.setOrigin   (0, 1,0)    #Set its origin
    self.cameraBackRay.setDirection(0,-5,0) #And its direction
    self.cameraBackCol = CollisionNode('cameraBackRay') #Create and name the node
    self.cameraBackCol.addSolid(self.cameraBackRay) #Add the ray
    self.cameraBackCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks
    self.cameraBackCol.setIntoCollideMask(bitMaskOr([]))
    self.cameraBackColNp = base.camera.attachNewNode(self.cameraBackCol)
    #self.cameraBackColNp.show()
    
    # the camera left/right rays
    self.cameraLeftRay = CollisionRay()     #Create the ray
    self.cameraLeftRay.setOrigin   (-1,0,0)    #Set its origin
    self.cameraLeftRay.setDirection( 5,0,0) #And its direction
    self.cameraLeftCol = CollisionNode('cameraLeftRay') #Create and name the node
    self.cameraLeftCol.addSolid(self.cameraLeftRay) #Add the ray
    self.cameraLeftCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks
    self.cameraLeftCol.setIntoCollideMask(bitMaskOr([]))
    self.cameraLeftColNp = base.camera.attachNewNode(self.cameraLeftCol)
    #self.cameraLeftColNp.show()
    
    self.cameraRightRay = CollisionRay()     #Create the ray
    self.cameraRightRay.setOrigin   ( 1,0,0)    #Set its origin
    self.cameraRightRay.setDirection(-5,0,0) #And its direction
    self.cameraRightCol = CollisionNode('cameraRightRay') #Create and name the node
    self.cameraRightCol.addSolid(self.cameraRightRay) #Add the ray
    self.cameraRightCol.setFromCollideMask(bitMaskOr([WALLS])) #Set its bitmasks
    self.cameraRightCol.setIntoCollideMask(bitMaskOr([]))
    self.cameraRightColNp = base.camera.attachNewNode(self.cameraRightCol)
    #self.cameraRightColNp.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.cGroundHandler = CollisionHandlerQueue()
    self.cWallHandler = 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.cameraBallSphere, self.cHandler)
    self.cTrav.addCollider(self.cameraGroundColNp, self.cGroundHandler)
    '''
    self.cTrav.addCollider(self.cameraBackColNp, self.cWallHandler)
    self.cTrav.addCollider(self.cameraFrontColNp, self.cWallHandler)
    self.cTrav.addCollider(self.cameraLeftColNp, self.cWallHandler)
    self.cTrav.addCollider(self.cameraRightColNp, self.cWallHandler)
    '''
    # we dont want this to be automatically executed
    #base.cTrav = self.cTrav
    
    #Collision traversers have a built in tool to help visualize collisions.
    #Uncomment the next line to see it.
    #self.cTrav.showCollisions(render)
    
    #self.cTrav.traverse( render )
    
    # add a task to check for collisions
    taskMgr.add(self.collisionCheckTask, 'collisionCheckTask')
  
  def collisionCheckTask( self, task ):
    # make the parent of the groundCollideHandler be horizontal relative to render
    self.horizontalCameraNode.setHpr( render, Vec3(0,0,0))
    
    self.cTrav.traverse( render )
    
    #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.cGroundHandler.getNumEntries()):
      self.cGroundHandler.sortEntries()
      entry = self.cGroundHandler.getEntry(i)
      object = entry.getIntoNode()
      self.groundCollideHandler(entry)
      # stop after first one
      break
    for i in range(self.cWallHandler.getNumEntries()):
      self.cWallHandler.sortEntries()
      entry = self.cWallHandler.getEntry(i)
      object = entry.getIntoNode()
      self.wallCollideHandler(entry)
      # stop after first one
      break
    return Task.cont
  
  def groundCollideHandler( self, colEntry ):
    # get Z position of collision
    newZ = colEntry.getSurfacePoint(render).getZ()
    # set position node of camera above collision point
    base.camera.setZ(newZ+GROUNDDISTANCE)
  
  def wallCollideHandler( self, colEntry ):
    # get position of collision
    collisionPos = colEntry.getSurfacePoint(render)
    # get position of camera
    cameraPos = base.camera.getPos(render)
    # distance from collisionpoint to camera
    distance = collisionPos - cameraPos
    # length of the distance
    distanceLength = distance.length()
    # if distance to collision point smaller then defined
    if distanceLength < MINDISTANCEWALL:
      # move camera backwand to be at correct distance
      base.camera.setPos( base.camera.getPos() - (distance * (MINDISTANCEWALL - distanceLength)))
示例#50
0
    def load(self):
        self.notify.debug('load')
        DistributedMinigame.load(self)
        self.music = base.loadMusic('phase_4/audio/bgm/MG_CogThief.ogg')
        self.initCogInfo()
        for barrelIndex in xrange(CTGG.NumBarrels):
            barrel = loader.loadModel(
                'phase_4/models/minigames/cogthief_game_gagTank')
            barrel.setPos(CTGG.BarrelStartingPositions[barrelIndex])
            barrel.setScale(self.BarrelScale)
            barrel.reparentTo(render)
            barrel.setTag('barrelIndex', str(barrelIndex))
            collSphere = CollisionSphere(0, 0, 0, 4)
            collSphere.setTangible(0)
            name = 'BarrelSphere-%d' % barrelIndex
            collSphereName = self.uniqueName(name)
            collNode = CollisionNode(collSphereName)
            collNode.setFromCollideMask(CTGG.BarrelBitmask)
            collNode.addSolid(collSphere)
            colNp = barrel.attachNewNode(collNode)
            handler = CollisionHandlerEvent()
            handler.setInPattern('barrelHit-%fn')
            base.cTrav.addCollider(colNp, handler)
            self.accept('barrelHit-' + collSphereName, self.handleEnterBarrel)
            nodeToHide = '**/gagMoneyTen'
            if barrelIndex % 2:
                nodeToHide = '**/gagMoneyFive'
            iconToHide = barrel.find(nodeToHide)
            if not iconToHide.isEmpty():
                iconToHide.hide()
            self.barrels.append(barrel)

        self.gameBoard = loader.loadModel(
            'phase_4/models/minigames/cogthief_game')
        self.gameBoard.find('**/floor_TT').hide()
        self.gameBoard.find('**/floor_DD').hide()
        self.gameBoard.find('**/floor_DG').hide()
        self.gameBoard.find('**/floor_MM').hide()
        self.gameBoard.find('**/floor_BR').hide()
        self.gameBoard.find('**/floor_DL').hide()
        zone = self.getSafezoneId()
        if zone == ToontownGlobals.ToontownCentral:
            self.gameBoard.find('**/floor_TT').show()
        elif zone == ToontownGlobals.DonaldsDock:
            self.gameBoard.find('**/floor_DD').show()
        elif zone == ToontownGlobals.DaisyGardens:
            self.gameBoard.find('**/floor_DG').show()
        elif zone == ToontownGlobals.MinniesMelodyland:
            self.gameBoard.find('**/floor_MM').show()
        elif zone == ToontownGlobals.TheBrrrgh:
            self.gameBoard.find('**/floor_BR').show()
        elif zone == ToontownGlobals.DonaldsDreamland:
            self.gameBoard.find('**/floor_DL').show()
        else:
            self.gameBoard.find('**/floor_TT').show()
        self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0)
        self.gameBoard.setScale(1.0)
        self.toonSDs = {}
        avId = self.localAvId
        toonSD = CogThiefGameToonSD.CogThiefGameToonSD(avId, self)
        self.toonSDs[avId] = toonSD
        toonSD.load()
        self.loadCogs()
        self.toonHitTracks = {}
        self.toonPieTracks = {}
        self.sndOof = base.loadSfx('phase_4/audio/sfx/MG_cannon_hit_dirt.ogg')
        self.sndRewardTick = base.loadSfx(
            'phase_3.5/audio/sfx/tick_counter.ogg')
        self.sndPerfect = base.loadSfx('phase_4/audio/sfx/ring_perfect.ogg')
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.posInTopRightCorner()
        self.timer.hide()
        purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui')
        self.jarImage = purchaseModels.find('**/Jar')
        self.jarImage.reparentTo(hidden)
        self.rewardPanel = DirectLabel(parent=hidden,
                                       relief=None,
                                       pos=(-0.173, 0.0, -0.55),
                                       scale=0.65,
                                       text='',
                                       text_scale=0.2,
                                       text_fg=(0.95, 0.95, 0, 1),
                                       text_pos=(0, -.13),
                                       text_font=ToontownGlobals.getSignFont(),
                                       image=self.jarImage)
        self.rewardPanelTitle = DirectLabel(parent=self.rewardPanel,
                                            relief=None,
                                            pos=(0, 0, 0.06),
                                            scale=0.08,
                                            text=TTLocalizer.CannonGameReward,
                                            text_fg=(0.95, 0.95, 0, 1),
                                            text_shadow=(0, 0, 0, 1))
        return
示例#51
0
class Character: 
    
    """A character with an animated avatar that moves left, right or forward 
       according to the controls turned on or off in self.controlMap. 
    
    Public fields: 
    self.controlMap -- The character's movement controls 
    self.actor -- The character's Actor (3D animated model) 
    
    
    Public functions: 
    __init__ -- Initialise the character 
    move -- Move and animate the character for one frame. This is a task 
            function that is called every frame by Panda3D. 
    setControl -- Set one of the character's controls on or off. 
    
    """ 

    def __init__(self, model, run, walk, startPos, scale):        
        """Initialise the character. 
        
        Arguments: 
        model -- The path to the character's model file (string) 
           run : The path to the model's run animation (string) 
           walk : The path to the model's walk animation (string) 
           startPos : Where in the world the character will begin (pos) 
           scale : The amount by which the size of the model will be scaled 
                   (float) 
                    
           """ 

        self.controlMap = {"left":0, "right":0, "up":0, "down":0} 

        self.actor = Actor(Config.MYDIR+model, 
                                 {"run":Config.MYDIR+run, 
                                  "walk":Config.MYDIR+walk})        
        self.actor.reparentTo(render) 
        self.actor.setScale(scale) 
        self.actor.setPos(startPos) 

        self.controller = Controller.LocalController(self)
        
        taskMgr.add(self.move,"moveTask") # Note: deriving classes DO NOT need 
                                          # to add their own move tasks to the 
                                          # task manager. If they override 
                                          # self.move, then their own self.move 
                                          # function will get called by the 
                                          # task manager (they must then 
                                          # explicitly call Character.move in 
                                          # that function if they want it). 
        self.prevtime = 0 
        self.isMoving = False 

        # We will detect the height of the terrain by creating a collision 
        # ray and casting it downward toward the terrain.  One ray will 
        # start above ralph's head, and the other will start above the camera. 
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it 
        # hits the terrain, we can detect the height.  If it hits anything 
        # else, we rule that the move is illegal. 

        self.cTrav = CollisionTraverser() 

        self.groundRay = CollisionRay() 
        self.groundRay.setOrigin(0,0,1000) 
        self.groundRay.setDirection(0,0,-1) 
        self.groundCol = CollisionNode('ralphRay') 
        self.groundCol.addSolid(self.groundRay) 
        self.groundCol.setFromCollideMask(BitMask32.bit(1)) 
        self.groundCol.setIntoCollideMask(BitMask32.allOff()) 
        self.groundColNp = self.actor.attachNewNode(self.groundCol)
        self.groundHandler = CollisionHandlerQueue() 
        self.cTrav.addCollider(self.groundColNp, self.groundHandler) 

        # Uncomment this line to see the collision rays 
        # self.groundColNp.show() 

        #Uncomment this line to show a visual representation of the
        #collisions occuring 
        # self.cTrav.showCollisions(render) 

    def move(self, task): 
        """Move and animate the character for one frame. 
        
        This is a task function that is called every frame by Panda3D. 
        The character is moved according to which of it's movement controls 
        are set, and the function keeps the character's feet on the ground 
        and stops the character from moving if a collision is detected. 
        This function also handles playing the characters movement 
        animations. 

        Arguments: 
        task -- A direct.task.Task object passed to this function by Panda3D. 
        
        Return: 
        Task.cont -- To tell Panda3D to call this task function again next 
                     frame. 
        """ 
        
        elapsed = task.time - self.prevtime 

        # save the character's initial position so that we can restore it, 
        # in case he falls off the map or runs into something. 

        startpos = self.actor.getPos() 

        # pass on input
        self.controller.move(task, elapsed)
        
        # If the character is moving, loop the run animation. 
        # If he is standing still, stop the animation. 

        if (self.controlMap["up"]!=0) or (self.controlMap["left"]!=0) or (self.controlMap["right"]!=0) or (self.controlMap["down"]!=0): 
            
            if self.isMoving is False: 
                self.actor.loop("run") 
                self.isMoving = True 
        else: 
            if self.isMoving: 
                self.actor.stop() 
                self.actor.pose("walk",5) 
                self.isMoving = False 

        # Now check for collisions. 

        self.cTrav.traverse(render) 

        # Adjust the character's Z coordinate.  If the character's ray hit terrain, 
        # update his Z. If it hit anything else, or didn't hit anything, put 
        # him back where he was last frame. 

        entries = [] 
        for i in range(self.groundHandler.getNumEntries()): 
            entry = self.groundHandler.getEntry(i) 
            entries.append(entry) 
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), 
                                     x.getSurfacePoint(render).getZ())) 
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.actor.setZ(entries[0].getSurfacePoint(render).getZ()) 
        else: 
            self.actor.setPos(startpos) 

        # Store the task time and continue. 
        self.prevtime = task.time 
        return Task.cont 

    def setControl(self, control, value): 
        """Set the state of one of the character's movement controls. 
        
        Arguments: 
        See self.controlMap in __init__. 
        control -- The control to be set, must be a string matching one of 
                   the strings in self.controlMap. 
        value -- The value to set the control to. 
        
        """ 

        # FIXME: this function is duplicated in Camera and Character, and 
        # keyboard control settings are spread throughout the code. Maybe 
        # add a Controllable class? 
        
        self.controlMap[control] = value 
示例#52
0
class thirdPerson(DirectObject):
    def __init__(self, parserClass, mainClass, mapLoaderClass,
                 modelLoaderClass):
        self.switchState = False

        #self.t = Timer()

        self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0}
        self.ralph = Actor(
            "data/models/units/ralph/ralph", {
                "run": "data/models/units/ralph/ralph-run",
                "walk": "data/models/units/ralph/ralph-walk"
            })
        self.ralph.reparentTo(render)
        #		self.ralph.setPos(42, 30, 0)
        self.ralph.setPos(6, 10, 0)
        self.ralph.setScale(0.1)

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("arrow_down", self.setKey, ["backward", 1])
        self.accept("arrow_down-up", self.setKey, ["backward", 0])

        self.isMoving = False

        self.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 1000)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)
        #self.ralphGroundCol.show()

        base.cam.reparentTo(self.ralph)
        base.cam.setPos(0, 9, 7)
        self.floater2 = NodePath(PandaNode("floater2"))
        self.floater2.reparentTo(self.ralph)
        self.floater2.setZ(self.floater2.getZ() + 6)
        base.cam.lookAt(self.floater2)

        # Uncomment this line to see the collision rays
        #		self.ralphGroundColNp.show()
        #		self.camGroundColNp.show()

        #Uncomment this line to show a visual representation of the
        #collisions occuring
        #		self.cTrav.showCollisions(render)

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        taskMgr.add(self.move,
                    "movingTask",
                    extraArgs=[
                        mainClass, parserClass, mapLoaderClass,
                        modelLoaderClass
                    ])

    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value

    def move(self, mainClass, parserClass, mapLoaderClass, modelLoaderClass):
        # Get the time elapsed since last frame. We need this
        # for framerate-independent movement.
        elapsed = globalClock.getDt()

        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.ralph.getPos()

        # If a move-key is pressed, move ralph in the specified direction.

        if (self.keyMap["left"] != 0):
            self.ralph.setH(self.ralph.getH() + elapsed * 300)
        if (self.keyMap["right"] != 0):
            self.ralph.setH(self.ralph.getH() - elapsed * 300)
        if (self.keyMap["forward"] != 0):
            self.ralph.setY(self.ralph, -(elapsed * 50))  #25))
        if (self.keyMap["backward"] != 0):
            self.ralph.setY(self.ralph, +(elapsed * 20))

        if (self.keyMap["forward"] != 0) or (self.keyMap["left"] !=
                                             0) or (self.keyMap["right"] != 0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True

        elif (self.keyMap["backward"] != 0):
            if self.isMoving is False:
                self.ralph.stop()
                self.ralph.pose("walk", 5)
                self.isMoving = False

        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk", 5)
                self.isMoving = False

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.

        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x, y: cmp(
            y.getSurfacePoint(render).getZ(),
            x.getSurfacePoint(render).getZ()))

        if (len(entries) > 0) and (entries[0].getIntoNode().getName()[0:4]
                                   == "tile"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())

        elif (len(entries) > 0) and (entries[0].getIntoNode().getName()[0:5]
                                     == "solid"):
            self.ralph.setPos(startpos)
            x = int(entries[0].getIntoNode().getName()
                    [len(entries[0].getIntoNode().getName()) -
                     6:len(entries[0].getIntoNode().getName()) - 4])
            y = int(entries[0].getIntoNode().getName()
                    [len(entries[0].getIntoNode().getName()) - 2:])
            if (mapLoaderClass.tileArray[y][x].drillTime != None):
                mainClass.changeTile(mapLoaderClass.tileArray[y][x], 0,
                                     parserClass, modelLoaderClass,
                                     mapLoaderClass)
        else:
            self.ralph.setPos(startpos)

        self.ralph.setP(0)
        return Task.cont
示例#53
0
class world(DirectObject):
    def __init__(self):
        base.disableMouse()
        base.camLens.setFar(100)
        self.parserClass = Parser.Parser()  # Making the required instances
        self.mapLoaderClass = mapLoader.mapLoader(self)

        self.gameObjects = {}
        self.gameObjectID = 0

        self.mapX = self.mapLoaderClass.mapConfigParser.getint(
            "map", "width") - 1  # Name says it all really
        self.mapY = self.mapLoaderClass.mapConfigParser.getint(
            "map", "height") - 1

        self.modelLoaderClass = modelLoader.modelLoader(self)

        self.cameraClass = stratCam.CameraHandler(self)
        self.mouseClass = stratCam.mouseHandler(self)
        self.GUI = stratCam.GUI(self)
        #	self.GUI = stratCam.GUI(self)
        self.priorities = priorities.priorities()

        base.setFrameRateMeter(True)

        ###############
        base.cTrav2 = CollisionTraverser('world2')
        #	base.cTrav2.showCollisions(render)

        self.heightRay = CollisionRay(
        )  # A collision ray, used for getting the height of the terrain
        self.heightRay.setOrigin(0, 0, 100)
        self.heightRay.setDirection(0, 0, -1)

        self.heightCol = CollisionNode('unit Ray')
        self.heightCol.addSolid(self.heightRay)
        self.heightCol.setTag('units', 'ray1')

        self.heightCol.setFromCollideMask(BitMask32.bit(0))
        #	self.heightCol.setIntoCollideMask(BitMask32.allOff())
        self.heightColNp = render.attachNewNode(self.heightCol)
        self.heightColNp.setPos(2, 2, 0)
        self.heightHandler = CollisionHandlerQueue()

        base.cTrav2.addCollider(self.heightColNp, self.heightHandler)
        ###############

        #	myFrame = DirectFrame(frameColor=(0, 0, 0, 1),
        #					frameSize=(-0.25, 0.25, -1, 1),
        #					pos=(1.08, 0, 0))
        #	button = DirectButton(text = ("button"), scale = 0.1)
        #	button.reparentTo(myFrame)
        #	button.setPos(0, 0, 0.9)

        self.grids = astar.grid(self)

        self.unitHandler = unitHandler.world(self)
        #	self.unitHandler.addUnit(0, (10,10,5), self)
        #	self.unitHandler.addUnit(1, (6,10,5), self)
        #	self.unitHandler.moveTo(self, (6, 34), 0)
        #	self.unitHandler.moveTo(self, (34, 30), 1)

        self.buildingHandler = buildingHandler.buildingHandler(self)

        self.tileSelected = (0, 0)

        taskMgr.add(self.tskCheckWalls, "Wall checking")
        taskMgr.add(self.priorities.jobTask, "Jobs", extraArgs=[self])

        self.loadLight()

        self.accept("escape", sys.exit)
        self.accept("1", self.unitHandler.addUnit2, extraArgs=[0, self])
        self.accept("2", self.unitHandler.addUnit2, extraArgs=[1, self])
        self.accept("3", self.unitHandler.addUnit2, extraArgs=[2, self])

        self.accept("enter",
                    self.buildingHandler.addBuilding2,
                    extraArgs=[self, 0])

        self.accept("p", self.priorities.addJob)

        print 'END OF GAMEMAIN.PY!'

    def tskCheckWalls(self, task):
        for row in self.mapLoaderClass.tileArray:
            for tile in row:
                if (tile.solid == True):
                    aroundNo = 0
                    #	if (tile.solidMap[1] == True):
                    #		aroundNo += 1
                    #	if (tile.solidMap[3] == True):
                    #		aroundNo += 1
                    #	if (tile.solidMap[5] == True):
                    #		aroundNo += 1
                    #	if (tile.solidMap[7] == True):
                    #		aroundNo += 1
                    for i in tile.solidMap:
                        if (i == True):
                            aroundNo += 1

                    if ((
                            tile.solidMap[1] == True
                            and  # If only supported by 1 other solid
                            tile.solidMap[3] == False and tile.solidMap[5]
                            == False and tile.solidMap[7] == False) or
                        (tile.solidMap[1] == False and tile.solidMap[3] == True
                         and tile.solidMap[5] == False
                         and tile.solidMap[7] == False)
                            or (tile.solidMap[1] == False
                                and tile.solidMap[3] == False
                                and tile.solidMap[5] == True
                                and tile.solidMap[7] == False)
                            or (tile.solidMap[1] == False
                                and tile.solidMap[3] == False
                                and tile.solidMap[5] == False
                                and tile.solidMap[7] == True) or
                        (tile.solidMap[1] == True and tile.solidMap[3] == False
                         and tile.solidMap[5] == False
                         and tile.solidMap[7] == True) or
                        (tile.solidMap[1] == False and tile.solidMap[3] == True
                         and tile.solidMap[5] == True
                         and tile.solidMap[7] == False) or  #):
                        (aroundNo < 3)):

                        #(tile.modelName[0:13] == 'solid no work')):
                        self.mineWall(tile)
        return Task.cont

    def mineWall(self, firstTile):
        def changer(firstTile, finalTileNumber):
            firstTile.model.detachNode()

            finalTileData = self.parserClass.wall[
                self.parserClass.main['wall_types'][finalTileNumber]]

            finalTile = copy.copy(finalTileData)
            finalTile.posX = firstTile.posX
            finalTile.posY = firstTile.posY
            finalTile.posZ = firstTile.posZ
            finalTile.cornerMap = firstTile.cornerMap
            finalTile.solidMap = firstTile.solidMap
            finalTile.reda = 0
            finalTile.renu = 0

            print finalTile.posX / 4, finalTile.posY / 4

            if (finalTileData.solid == False):
                finalTile.solidMap[4] == False
                if (finalTile.walkable == True
                    ):  # Change the meshes for the new tile
                    self.grids.landMesh[finalTile.posY / 4][finalTile.posX /
                                                            4] = True
                else:
                    self.grids.landMesh[finalTile.posY / 4][finalTile.posX /
                                                            4] = False
                if (finalTile.water == True):
                    self.grids.waterMesh[finalTile.posY / 4][finalTile.posX /
                                                             4] = True
                else:
                    self.grids.waterMesh[finalTile.posY / 4][finalTile.posX /
                                                             4] = False

                if (finalTile.lava == True) or (finalTile.water
                                                == True) or (finalTile.walkable
                                                             == True):
                    self.grids.airMesh[finalTile.posY / 4][finalTile.posX /
                                                           4] = True
                else:
                    self.grids.airMesh[finalTile.posY / 4][finalTile.posX /
                                                           4] = False

            elif (finalTileData.solid == True):
                finalTile.solidMap[4] == True

                self.grids.landMesh[finalTile.posY / 4][finalTile.posX /
                                                        4] = True
                self.grids.waterMesh[finalTile.posY / 4][finalTile.posX /
                                                         4] = True
                self.grids.airMesh[finalTile.posY / 4][finalTile.posX /
                                                       4] = True

            finalTile.model = self.modelLoaderClass.makeModel(
                finalTile, self
            )  #, mapLoaderClass) # From here on is reparenting and positioning the tile to the right place

            finalTile.model.reparentTo(render)
            finalTile.model.setPos(finalTile.posX, finalTile.posY, 0)
            finalTile.model.setCollideMask(0x1)

            tex = loader.loadTexture(finalTile.texture)
            finalTile.model.setTexture(tex, 1)

            if (firstTile.renu != 0):
                print self.parserClass.main['objects'][
                    firstTile.reda], firstTile.renu

                for i in range(firstTile.renu):
                    self.modelLoaderClass.addObject(self, firstTile.reda,
                                                    finalTile)

            return finalTile

        self.mapLoaderClass.tileArray[firstTile.posY / 4][firstTile.posX /
                                                          4] = changer(
                                                              firstTile, 0)
        self.reloadSurround(self.mapLoaderClass.tileArray[firstTile.posY /
                                                          4][firstTile.posX /
                                                             4])

    def reloadSurround(self, tileChanged):
        aroundInfo = []

        yBehind = tileChanged.posY / 4 - 1
        yInfront = tileChanged.posY / 4 + 1

        xBehind = tileChanged.posX / 4 - 1
        xInfront = tileChanged.posX / 4 + 1

        if (yInfront >= self.mapY - 1):
            yInfront = self.mapY - 1

        if (yBehind <= 0):
            yBehind = 0

        if (xInfront >= self.mapX - 1):
            xInfront = self.mapX - 1

        if (xBehind <= 0):
            xBehind = 0

        aroundInfo.append(
            self.mapLoaderClass.tileArray[yBehind][xBehind])  # BL
        aroundInfo.append(
            self.mapLoaderClass.tileArray[yBehind][tileChanged.posX / 4])  # BC
        aroundInfo.append(
            self.mapLoaderClass.tileArray[yBehind][xInfront])  # BR

        aroundInfo.append(self.mapLoaderClass.tileArray[tileChanged.posY /
                                                        4][xBehind])  # L
        aroundInfo.append(
            self.mapLoaderClass.tileArray[tileChanged.posY /
                                          4][tileChanged.posX / 4 - 1])
        aroundInfo.append(self.mapLoaderClass.tileArray[tileChanged.posY /
                                                        4][xInfront])  # R

        aroundInfo.append(
            self.mapLoaderClass.tileArray[yInfront][xBehind])  # TL
        aroundInfo.append(
            self.mapLoaderClass.tileArray[yInfront][tileChanged.posX /
                                                    4])  # TC
        aroundInfo.append(
            self.mapLoaderClass.tileArray[yInfront][xInfront])  # TR

        name = self.mapLoaderClass.tileArray[tileChanged.posY / 4 +
                                             1][tileChanged.posX / 4 +
                                                1].modelName

        for around in aroundInfo:
            around.solidMap = self.modelLoaderClass.reloadSolidMap(
                self, around.posX / 4, around.posY / 4)

            around.model.remove()

            around.model = self.modelLoaderClass.makeModel(around, self)
            around.model.setCollideMask(0x01)

            around.model.reparentTo(render)
            around.model.setPos(around.posX, around.posY, 0)

            tex = loader.loadTexture(around.texture)
            around.model.setTexture(tex, 1)

    def loadLight(self):  #Sets the lights
        plight = AmbientLight('my plight')
        light = self.parserClass.userConfig.getfloat('display', 'light')
        plight.setColor(VBase4(light, light, light, 0.5))
        plnp = render.attachNewNode(plight)
        render.setLight(plnp)
class DistributedIceGame(DistributedMinigame.DistributedMinigame, DistributedIceWorld.DistributedIceWorld):
    notify = directNotify.newCategory("DistributedIceGame")
    MaxLocalForce = 100
    MaxPhysicsForce = 25000

    def __init__(self, cr):
        DistributedMinigame.DistributedMinigame.__init__(self, cr)
        DistributedIceWorld.DistributedIceWorld.__init__(self, cr)
        self.gameFSM = ClassicFSM.ClassicFSM(
            "DistributedIceGame",
            [
                State.State("off", self.enterOff, self.exitOff, ["inputChoice"]),
                State.State(
                    "inputChoice",
                    self.enterInputChoice,
                    self.exitInputChoice,
                    ["waitServerChoices", "moveTires", "displayVotes", "cleanup"],
                ),
                State.State(
                    "waitServerChoices",
                    self.enterWaitServerChoices,
                    self.exitWaitServerChoices,
                    ["moveTires", "cleanup"],
                ),
                State.State("moveTires", self.enterMoveTires, self.exitMoveTires, ["synch", "cleanup"]),
                State.State("synch", self.enterSynch, self.exitSynch, ["inputChoice", "scoring", "cleanup"]),
                State.State("scoring", self.enterScoring, self.exitScoring, ["cleanup", "finalResults", "inputChoice"]),
                State.State("finalResults", self.enterFinalResults, self.exitFinalResults, ["cleanup"]),
                State.State("cleanup", self.enterCleanup, self.exitCleanup, []),
            ],
            "off",
            "cleanup",
        )
        self.addChildGameFSM(self.gameFSM)
        self.cameraThreeQuarterView = (0, -22, 45, 0, -62.89, 0)
        self.tireDict = {}
        self.forceArrowDict = {}
        self.canDrive = False
        self.timer = None
        self.timerStartTime = None
        self.curForce = 0
        self.curHeading = 0
        self.headingMomentum = 0.0
        self.forceMomentum = 0.0
        self.allTireInputs = None
        self.curRound = 0
        self.curMatch = 0
        self.controlKeyWarningLabel = DirectLabel(
            text=TTLocalizer.IceGameControlKeyWarning,
            text_fg=VBase4(1, 0, 0, 1),
            relief=None,
            pos=(0.0, 0, 0),
            scale=0.15,
        )
        self.controlKeyWarningLabel.hide()
        self.waitingMoveLabel = DirectLabel(
            text=TTLocalizer.IceGameWaitingForPlayersToFinishMove,
            text_fg=VBase4(1, 1, 1, 1),
            relief=None,
            pos=(-0.6, 0, -0.75),
            scale=0.075,
        )
        self.waitingMoveLabel.hide()
        self.waitingSyncLabel = DirectLabel(
            text=TTLocalizer.IceGameWaitingForAISync,
            text_fg=VBase4(1, 1, 1, 1),
            relief=None,
            pos=(-0.6, 0, -0.75),
            scale=0.075,
        )
        self.waitingSyncLabel.hide()
        self.infoLabel = DirectLabel(text="", text_fg=VBase4(0, 0, 0, 1), relief=None, pos=(0.0, 0, 0.7), scale=0.075)
        self.updateInfoLabel()
        self.lastForceArrowUpdateTime = 0
        self.sendForceArrowUpdateAsap = False
        self.treasures = []
        self.penalties = []
        self.obstacles = []
        self.controlKeyPressed = False
        self.controlKeyWarningIval = None
        return

    def delete(self):
        DistributedIceWorld.DistributedIceWorld.delete(self)
        DistributedMinigame.DistributedMinigame.delete(self)
        if self.controlKeyWarningIval:
            self.controlKeyWarningIval.finish()
            self.controlKeyWarningIval = None
        self.controlKeyWarningLabel.destroy()
        del self.controlKeyWarningLabel
        self.waitingMoveLabel.destroy()
        del self.waitingMoveLabel
        self.waitingSyncLabel.destroy()
        del self.waitingSyncLabel
        self.infoLabel.destroy()
        del self.infoLabel
        for treasure in self.treasures:
            treasure.destroy()

        del self.treasures
        for penalty in self.penalties:
            penalty.destroy()

        del self.penalties
        for obstacle in self.obstacles:
            obstacle.removeNode()

        del self.obstacles
        del self.gameFSM
        return

    def announceGenerate(self):
        DistributedMinigame.DistributedMinigame.announceGenerate(self)
        DistributedIceWorld.DistributedIceWorld.announceGenerate(self)
        self.debugTaskName = self.uniqueName("debugTask")

    def getTitle(self):
        return TTLocalizer.IceGameTitle

    def getInstructions(self):
        szId = self.getSafezoneId()
        numPenalties = IceGameGlobals.NumPenalties[szId]
        result = TTLocalizer.IceGameInstructions
        if numPenalties == 0:
            result = TTLocalizer.IceGameInstructionsNoTnt
        return result

    def getMaxDuration(self):
        return 0

    def load(self):
        self.notify.debug("load")
        DistributedMinigame.DistributedMinigame.load(self)
        self.music = base.loadMusic("phase_4/audio/bgm/MG_IceGame.ogg")
        self.gameBoard = loader.loadModel("phase_4/models/minigames/ice_game_icerink")
        background = loader.loadModel("phase_4/models/minigames/ice_game_2d")
        backgroundWide = loader.loadModel("phase_4/models/minigames/iceslide_ground")
        background.reparentTo(self.gameBoard)
        backgroundWide.reparentTo(self.gameBoard)
        backgroundWide.setPos(0, -0.3, -0.5)
        self.gameBoard.setPosHpr(0, 0, 0, 0, 0, 0)
        self.gameBoard.setScale(1.0)
        self.setupSimulation()
        index = 0
        for avId in self.avIdList:
            self.setupTire(avId, index)
            self.setupForceArrow(avId)
            index += 1

        for index in xrange(len(self.avIdList), 4):
            self.setupTire(-index, index)
            self.setupForceArrow(-index)

        self.showForceArrows(realPlayersOnly=True)
        self.westWallModel = NodePath()
        if not self.westWallModel.isEmpty():
            self.westWallModel.reparentTo(self.gameBoard)
            self.westWallModel.setPos(IceGameGlobals.MinWall[0], IceGameGlobals.MinWall[1], 0)
            self.westWallModel.setScale(4)
        self.eastWallModel = NodePath()
        if not self.eastWallModel.isEmpty():
            self.eastWallModel.reparentTo(self.gameBoard)
            self.eastWallModel.setPos(IceGameGlobals.MaxWall[0], IceGameGlobals.MaxWall[1], 0)
            self.eastWallModel.setScale(4)
            self.eastWallModel.setH(180)
        self.arrowKeys = ArrowKeys.ArrowKeys()
        self.target = loader.loadModel("phase_3/models/misc/sphere")
        self.target.setScale(0.01)
        self.target.reparentTo(self.gameBoard)
        self.target.setPos(0, 0, 0)
        self.scoreCircle = loader.loadModel("phase_4/models/minigames/ice_game_score_circle")
        self.scoreCircle.setScale(0.01)
        self.scoreCircle.reparentTo(self.gameBoard)
        self.scoreCircle.setZ(IceGameGlobals.TireRadius / 2.0)
        self.scoreCircle.setAlphaScale(0.5)
        self.scoreCircle.setTransparency(1)
        self.scoreCircle.hide()
        self.treasureModel = loader.loadModel("phase_4/models/minigames/ice_game_barrel")
        self.penaltyModel = loader.loadModel("phase_4/models/minigames/ice_game_tnt2")
        self.penaltyModel.setScale(0.75, 0.75, 0.7)
        szId = self.getSafezoneId()
        obstacles = IceGameGlobals.Obstacles[szId]
        index = 0
        cubicObstacle = IceGameGlobals.ObstacleShapes[szId]
        for pos in obstacles:
            newPos = Point3(pos[0], pos[1], IceGameGlobals.TireRadius)
            newObstacle = self.createObstacle(newPos, index, cubicObstacle)
            self.obstacles.append(newObstacle)
            index += 1

        self.countSound = loader.loadSfx("phase_3.5/audio/sfx/tick_counter.ogg")
        self.treasureGrabSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_vine_game_bananas.ogg")
        self.penaltyGrabSound = loader.loadSfx("phase_4/audio/sfx/MG_cannon_fire_alt.ogg")
        self.tireSounds = []
        for tireIndex in xrange(4):
            tireHit = loader.loadSfx("phase_4/audio/sfx/Golf_Hit_Barrier_1.ogg")
            wallHit = loader.loadSfx("phase_4/audio/sfx/MG_maze_pickup.ogg")
            obstacleHit = loader.loadSfx("phase_4/audio/sfx/Golf_Hit_Barrier_2.ogg")
            self.tireSounds.append({"tireHit": tireHit, "wallHit": wallHit, "obstacleHit": obstacleHit})

        self.arrowRotateSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_rotate.ogg")
        self.arrowUpSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_increase_3sec.ogg")
        self.arrowDownSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_force_decrease_3sec.ogg")
        self.scoreCircleSound = loader.loadSfx("phase_4/audio/sfx/MG_sfx_ice_scoring_1.ogg")

    def unload(self):
        self.notify.debug("unload")
        DistributedMinigame.DistributedMinigame.unload(self)
        del self.music
        self.gameBoard.removeNode()
        del self.gameBoard
        for forceArrow in self.forceArrowDict.values():
            forceArrow.removeNode()

        del self.forceArrowDict
        self.scoreCircle.removeNode()
        del self.scoreCircle
        del self.countSound

    def onstage(self):
        self.notify.debug("onstage")
        DistributedMinigame.DistributedMinigame.onstage(self)
        self.gameBoard.reparentTo(render)
        self.__placeToon(self.localAvId)
        self.moveCameraToTop()
        self.scorePanels = []
        base.playMusic(self.music, looping=1, volume=0.8)

    def offstage(self):
        self.notify.debug("offstage")
        self.music.stop()
        self.gameBoard.hide()
        self.infoLabel.hide()
        for avId in self.tireDict:
            self.tireDict[avId]["tireNodePath"].hide()

        for panel in self.scorePanels:
            panel.cleanup()

        del self.scorePanels
        for obstacle in self.obstacles:
            obstacle.hide()

        for treasure in self.treasures:
            treasure.nodePath.hide()

        for penalty in self.penalties:
            penalty.nodePath.hide()

        for avId in self.avIdList:
            av = self.getAvatar(avId)
            if av:
                av.dropShadow.show()
                av.resetLOD()

        taskMgr.remove(self.uniqueName("aimtask"))
        self.arrowKeys.destroy()
        del self.arrowKeys
        DistributedMinigame.DistributedMinigame.offstage(self)

    def handleDisabledAvatar(self, avId):
        self.notify.debug("handleDisabledAvatar")
        self.notify.debug("avatar " + str(avId) + " disabled")
        DistributedMinigame.DistributedMinigame.handleDisabledAvatar(self, avId)

    def setGameReady(self):
        if not self.hasLocalToon:
            return
        self.notify.debug("setGameReady")
        if DistributedMinigame.DistributedMinigame.setGameReady(self):
            return
        for index in xrange(self.numPlayers):
            avId = self.avIdList[index]
            toon = self.getAvatar(avId)
            if toon:
                toon.reparentTo(render)
                self.__placeToon(avId)
                toon.forwardSpeed = 0
                toon.rotateSpeed = False
                toon.dropShadow.hide()
                toon.setAnimState("Sit")
                if avId in self.tireDict:
                    tireNp = self.tireDict[avId]["tireNodePath"]
                    toon.reparentTo(tireNp)
                    toon.setY(1.0)
                    toon.setZ(-3)
                toon.startLookAround()

    def setGameStart(self, timestamp):
        if not self.hasLocalToon:
            return
        self.notify.debug("setGameStart")
        DistributedMinigame.DistributedMinigame.setGameStart(self, timestamp)
        for avId in self.remoteAvIdList:
            toon = self.getAvatar(avId)
            if toon:
                toon.stopLookAround()

        self.scores = [0] * self.numPlayers
        spacing = 0.4
        for i in xrange(self.numPlayers):
            avId = self.avIdList[i]
            avName = self.getAvatarName(avId)
            scorePanel = MinigameAvatarScorePanel.MinigameAvatarScorePanel(avId, avName)
            scorePanel.setScale(0.9)
            scorePanel.setPos(-0.583 - spacing * (self.numPlayers - 1 - i), 0.0, -0.15)
            scorePanel.reparentTo(base.a2dTopRight)
            scorePanel.makeTransparent(0.75)
            self.scorePanels.append(scorePanel)

        self.arrowKeys.setPressHandlers(
            [
                self.__upArrowPressed,
                self.__downArrowPressed,
                self.__leftArrowPressed,
                self.__rightArrowPressed,
                self.__controlPressed,
            ]
        )

    def isInPlayState(self):
        if not self.gameFSM.getCurrentState():
            return False
        if not self.gameFSM.getCurrentState().getName() == "play":
            return False
        return True

    def enterOff(self):
        self.notify.debug("enterOff")

    def exitOff(self):
        pass

    def enterInputChoice(self):
        self.notify.debug("enterInputChoice")
        self.forceLocalToonToTire()
        self.controlKeyPressed = False
        if self.curRound == 0:
            self.setupStartOfMatch()
        else:
            self.notify.debug("self.curRound = %s" % self.curRound)
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.hide()
        if self.timerStartTime != None:
            self.startTimer()
        self.showForceArrows(realPlayersOnly=True)
        self.localForceArrow().setPosHpr(0, 0, -1.0, 0, 0, 0)
        self.localForceArrow().reparentTo(self.localTireNp())
        self.localForceArrow().setY(IceGameGlobals.TireRadius)
        self.localTireNp().headsUp(self.target)
        self.notify.debug("self.localForceArrow() heading = %s" % self.localForceArrow().getH())
        self.curHeading = self.localTireNp().getH()
        self.curForce = 25
        self.updateLocalForceArrow()
        for avId in self.forceArrowDict:
            forceArrow = self.forceArrowDict[avId]
            forceArrow.setPosHpr(0, 0, -1.0, 0, 0, 0)
            tireNp = self.tireDict[avId]["tireNodePath"]
            forceArrow.reparentTo(tireNp)
            forceArrow.setY(IceGameGlobals.TireRadius)
            tireNp.headsUp(self.target)
            self.updateForceArrow(avId, tireNp.getH(), 25)

        taskMgr.add(self.__aimTask, self.uniqueName("aimtask"))
        if base.localAvatar.laffMeter:
            base.localAvatar.laffMeter.stop()
        self.sendForceArrowUpdateAsap = False
        return

    def exitInputChoice(self):
        if not self.controlKeyPressed:
            if self.controlKeyWarningIval:
                self.controlKeyWarningIval.finish()
                self.controlKeyWarningIval = None
            self.controlKeyWarningIval = Sequence(
                Func(self.controlKeyWarningLabel.show),
                self.controlKeyWarningLabel.colorScaleInterval(
                    10, VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)
                ),
                Func(self.controlKeyWarningLabel.hide),
            )
            self.controlKeyWarningIval.start()
        if self.timer != None:
            self.timer.destroy()
            self.timer = None
        self.timerStartTime = None
        self.hideForceArrows()
        self.arrowRotateSound.stop()
        self.arrowUpSound.stop()
        self.arrowDownSound.stop()
        taskMgr.remove(self.uniqueName("aimtask"))
        return

    def enterWaitServerChoices(self):
        self.waitingMoveLabel.show()
        self.showForceArrows(True)

    def exitWaitServerChoices(self):
        self.waitingMoveLabel.hide()
        self.hideForceArrows()

    def enterMoveTires(self):
        for key in self.tireDict:
            body = self.tireDict[key]["tireBody"]
            body.setAngularVel(0, 0, 0)
            body.setLinearVel(0, 0, 0)

        for index in xrange(len(self.allTireInputs)):
            input = self.allTireInputs[index]
            avId = self.avIdList[index]
            body = self.getTireBody(avId)
            degs = input[1] + 90
            tireNp = self.getTireNp(avId)
            tireH = tireNp.getH()
            self.notify.debug("tireH = %s" % tireH)
            radAngle = deg2Rad(degs)
            foo = NodePath("foo")
            dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0)
            self.notify.debug("dirVector is now=%s" % dirVector)
            inputForce = input[0]
            inputForce /= self.MaxLocalForce
            inputForce *= self.MaxPhysicsForce
            force = dirVector * inputForce
            self.notify.debug("adding force %s to %d" % (force, avId))
            body.addForce(force)

        self.enableAllTireBodies()
        self.totalPhysicsSteps = 0
        self.startSim()
        taskMgr.add(self.__moveTiresTask, self.uniqueName("moveTiresTtask"))

    def exitMoveTires(self):
        self.forceLocalToonToTire()
        self.disableAllTireBodies()
        self.stopSim()
        self.notify.debug("total Physics steps = %d" % self.totalPhysicsSteps)
        taskMgr.remove(self.uniqueName("moveTiresTtask"))

    def enterSynch(self):
        self.waitingSyncLabel.show()

    def exitSynch(self):
        self.waitingSyncLabel.hide()

    def enterScoring(self):
        sortedByDistance = []
        for avId in self.avIdList:
            np = self.getTireNp(avId)
            pos = np.getPos()
            pos.setZ(0)
            sortedByDistance.append((avId, pos.length()))

        def compareDistance(x, y):
            if x[1] - y[1] > 0:
                return 1
            elif x[1] - y[1] < 0:
                return -1
            else:
                return 0

        sortedByDistance.sort(cmp=compareDistance)
        self.scoreMovie = Sequence()
        curScale = 0.01
        curTime = 0
        self.scoreCircle.setScale(0.01)
        self.scoreCircle.show()
        self.notify.debug("newScores = %s" % self.newScores)
        circleStartTime = 0
        for index in xrange(len(sortedByDistance)):
            distance = sortedByDistance[index][1]
            avId = sortedByDistance[index][0]
            scorePanelIndex = self.avIdList.index(avId)
            time = (distance - curScale) / IceGameGlobals.ExpandFeetPerSec
            if time < 0:
                time = 0.01
            scaleXY = distance + IceGameGlobals.TireRadius
            self.notify.debug("circleStartTime = %s" % circleStartTime)
            self.scoreMovie.append(
                Parallel(
                    LerpScaleInterval(self.scoreCircle, time, Point3(scaleXY, scaleXY, 1.0)),
                    SoundInterval(self.scoreCircleSound, duration=time, startTime=circleStartTime),
                )
            )
            circleStartTime += time
            startScore = self.scorePanels[scorePanelIndex].getScore()
            destScore = self.newScores[scorePanelIndex]
            self.notify.debug("for avId %d, startScore=%d, newScores=%d" % (avId, startScore, destScore))

            def increaseScores(t, scorePanelIndex=scorePanelIndex, startScore=startScore, destScore=destScore):
                oldScore = self.scorePanels[scorePanelIndex].getScore()
                diff = destScore - startScore
                newScore = int(startScore + diff * t)
                if newScore > oldScore:
                    base.playSfx(self.countSound)
                self.scorePanels[scorePanelIndex].setScore(newScore)
                self.scores[scorePanelIndex] = newScore

            duration = (destScore - startScore) * IceGameGlobals.ScoreCountUpRate
            tireNp = self.tireDict[avId]["tireNodePath"]
            self.scoreMovie.append(
                Parallel(
                    LerpFunctionInterval(increaseScores, duration),
                    Sequence(
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 0, 0, 1)),
                        LerpColorScaleInterval(tireNp, duration / 6.0, VBase4(1, 1, 1, 1)),
                    ),
                )
            )
            curScale += distance

        self.scoreMovie.append(Func(self.sendUpdate, "reportScoringMovieDone", []))
        self.scoreMovie.start()

    def exitScoring(self):
        self.scoreMovie.finish()
        self.scoreMovie = None
        self.scoreCircle.hide()
        return

    def enterFinalResults(self):
        lerpTrack = Parallel()
        lerpDur = 0.5
        tY = 0.6
        bY = -0.05
        lX = -0.5
        cX = 0
        rX = 0.5
        scorePanelLocs = (
            ((cX, bY),),
            ((lX, bY), (rX, bY)),
            ((cX, tY), (lX, bY), (rX, bY)),
            ((lX, tY), (rX, tY), (lX, bY), (rX, bY)),
        )
        scorePanelLocs = scorePanelLocs[self.numPlayers - 1]
        for i in xrange(self.numPlayers):
            panel = self.scorePanels[i]
            pos = scorePanelLocs[i]
            panel.wrtReparentTo(aspect2d)
            lerpTrack.append(
                Parallel(
                    LerpPosInterval(panel, lerpDur, Point3(pos[0], 0, pos[1]), blendType="easeInOut"),
                    LerpScaleInterval(panel, lerpDur, Vec3(panel.getScale()) * 2.0, blendType="easeInOut"),
                )
            )

        self.showScoreTrack = Parallel(
            lerpTrack, Sequence(Wait(IceGameGlobals.ShowScoresDuration), Func(self.gameOver))
        )
        self.showScoreTrack.start()

    def exitFinalResults(self):
        self.showScoreTrack.pause()
        del self.showScoreTrack

    def enterCleanup(self):
        self.notify.debug("enterCleanup")
        if base.localAvatar.laffMeter:
            base.localAvatar.laffMeter.start()

    def exitCleanup(self):
        pass

    def __placeToon(self, avId):
        toon = self.getAvatar(avId)
        if toon:
            toon.setPos(0, 0, 0)
            toon.setHpr(0, 0, 0)

    def moveCameraToTop(self):
        camera.reparentTo(render)
        p = self.cameraThreeQuarterView
        camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5])

    def setupTire(self, avId, index):
        tireNp, tireBody, tireOdeGeom = self.createTire(index)
        self.tireDict[avId] = {"tireNodePath": tireNp, "tireBody": tireBody, "tireOdeGeom": tireOdeGeom}
        if avId <= 0:
            tireBlocker = tireNp.find("**/tireblockermesh")
            if not tireBlocker.isEmpty():
                tireBlocker.hide()
        if avId == self.localAvId:
            tireNp = self.tireDict[avId]["tireNodePath"]
            self.treasureSphereName = "treasureCollider"
            self.treasureCollSphere = CollisionSphere(0, 0, 0, IceGameGlobals.TireRadius)
            self.treasureCollSphere.setTangible(0)
            self.treasureCollNode = CollisionNode(self.treasureSphereName)
            self.treasureCollNode.setFromCollideMask(ToontownGlobals.PieBitmask)
            self.treasureCollNode.addSolid(self.treasureCollSphere)
            self.treasureCollNodePath = tireNp.attachNewNode(self.treasureCollNode)
            self.treasureHandler = CollisionHandlerEvent()
            self.treasureHandler.addInPattern("%fn-intoTreasure")
            base.cTrav.addCollider(self.treasureCollNodePath, self.treasureHandler)
            eventName = "%s-intoTreasure" % self.treasureCollNodePath.getName()
            self.notify.debug("eventName = %s" % eventName)
            self.accept(eventName, self.toonHitSomething)

    def setupForceArrow(self, avId):
        arrow = loader.loadModel("phase_4/models/minigames/ice_game_arrow")
        priority = 0
        if avId < 0:
            priority = -avId
        else:
            priority = self.avIdList.index(avId)
            if avId == self.localAvId:
                priority = 10
        self.forceArrowDict[avId] = arrow

    def hideForceArrows(self):
        for forceArrow in self.forceArrowDict.values():
            forceArrow.hide()

    def showForceArrows(self, realPlayersOnly=True):
        for avId in self.forceArrowDict:
            if realPlayersOnly:
                if avId > 0:
                    self.forceArrowDict[avId].show()
                else:
                    self.forceArrowDict[avId].hide()
            else:
                self.forceArrowDict[avId].show()

    def localForceArrow(self):
        if self.localAvId in self.forceArrowDict:
            return self.forceArrowDict[self.localAvId]
        else:
            return None
        return None

    def setChoices(self, input0, input1, input2, input3):
        pass

    def startDebugTask(self):
        taskMgr.add(self.debugTask, self.debugTaskName)

    def stopDebugTask(self):
        taskMgr.remove(self.debugTaskName)

    def debugTask(self, task):
        if self.canDrive and self.tireDict.has_key(localAvatar.doId):
            dt = globalClock.getDt()
            forceMove = 25000
            forceMoveDt = forceMove
            tireBody = self.tireDict[localAvatar.doId]["tireBody"]
            if self.arrowKeys.upPressed() and not tireBody.isEnabled():
                x = 0
                y = 1
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))
            if self.arrowKeys.downPressed() and not tireBody.isEnabled():
                x = 0
                y = -1
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))
            if self.arrowKeys.leftPressed() and not tireBody.isEnabled():
                x = -1
                y = 0
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))
            if self.arrowKeys.rightPressed() and not tireBody.isEnabled():
                x = 1
                y = 0
                tireBody.enable()
                tireBody.addForce(Vec3(x * forceMoveDt, y * forceMoveDt, 0))
        return task.cont

    def __upArrowPressed(self):
        pass

    def __downArrowPressed(self):
        pass

    def __leftArrowPressed(self):
        pass

    def __rightArrowPressed(self):
        pass

    def __controlPressed(self):
        if self.gameFSM.getCurrentState().getName() == "inputChoice":
            self.sendForceArrowUpdateAsap = True
            self.updateLocalForceArrow()
            self.controlKeyPressed = True
            self.sendUpdate("setAvatarChoice", [self.curForce, self.curHeading])
            self.gameFSM.request("waitServerChoices")

    def startTimer(self):
        now = globalClock.getFrameTime()
        elapsed = now - self.timerStartTime
        self.timer.posInTopRightCorner()
        self.timer.setTime(IceGameGlobals.InputTimeout)
        self.timer.countdown(IceGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout)
        self.timer.show()

    def setTimerStartTime(self, timestamp):
        if not self.hasLocalToon:
            return
        self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp)
        if self.timer != None:
            self.startTimer()
        return

    def handleChoiceTimeout(self):
        self.sendUpdate("setAvatarChoice", [0, 0])
        self.gameFSM.request("waitServerChoices")

    def localTireNp(self):
        ret = None
        if self.localAvId in self.tireDict:
            ret = self.tireDict[self.localAvId]["tireNodePath"]
        return ret

    def localTireBody(self):
        ret = None
        if self.localAvId in self.tireDict:
            ret = self.tireDict[self.localAvId]["tireBody"]
        return ret

    def getTireBody(self, avId):
        ret = None
        if avId in self.tireDict:
            ret = self.tireDict[avId]["tireBody"]
        return ret

    def getTireNp(self, avId):
        ret = None
        if avId in self.tireDict:
            ret = self.tireDict[avId]["tireNodePath"]
        return ret

    def updateForceArrow(self, avId, curHeading, curForce):
        forceArrow = self.forceArrowDict[avId]
        tireNp = self.tireDict[avId]["tireNodePath"]
        tireNp.setH(curHeading)
        tireBody = self.tireDict[avId]["tireBody"]
        tireBody.setQuaternion(tireNp.getQuat())
        self.notify.debug("curHeading = %s" % curHeading)
        yScale = curForce / 100.0
        yScale *= 1
        headY = yScale * 15
        xScale = (yScale - 1) / 2.0 + 1.0
        shaft = forceArrow.find("**/arrow_shaft")
        head = forceArrow.find("**/arrow_head")
        shaft.setScale(xScale, yScale, 1)
        head.setPos(0, headY, 0)
        head.setScale(xScale, xScale, 1)

    def updateLocalForceArrow(self):
        avId = self.localAvId
        self.b_setForceArrowInfo(avId, self.curHeading, self.curForce)

    def __aimTask(self, task):
        if not hasattr(self, "arrowKeys"):
            return task.done
        dt = globalClock.getDt()
        headingMomentumChange = dt * 60.0
        forceMomentumChange = dt * 160.0
        arrowUpdate = False
        arrowRotating = False
        arrowUp = False
        arrowDown = False
        if self.arrowKeys.upPressed() and not self.arrowKeys.downPressed():
            self.forceMomentum += forceMomentumChange
            if self.forceMomentum < 0:
                self.forceMomentum = 0
            if self.forceMomentum > 50:
                self.forceMomentum = 50
            oldForce = self.curForce
            self.curForce += self.forceMomentum * dt
            arrowUpdate = True
            if oldForce < self.MaxLocalForce:
                arrowUp = True
        elif self.arrowKeys.downPressed() and not self.arrowKeys.upPressed():
            self.forceMomentum += forceMomentumChange
            if self.forceMomentum < 0:
                self.forceMomentum = 0
            if self.forceMomentum > 50:
                self.forceMomentum = 50
            oldForce = self.curForce
            self.curForce -= self.forceMomentum * dt
            arrowUpdate = True
            if oldForce > 0.01:
                arrowDown = True
        else:
            self.forceMomentum = 0
        if self.arrowKeys.leftPressed() and not self.arrowKeys.rightPressed():
            self.headingMomentum += headingMomentumChange
            if self.headingMomentum < 0:
                self.headingMomentum = 0
            if self.headingMomentum > 50:
                self.headingMomentum = 50
            self.curHeading += self.headingMomentum * dt
            arrowUpdate = True
            arrowRotating = True
        elif self.arrowKeys.rightPressed() and not self.arrowKeys.leftPressed():
            self.headingMomentum += headingMomentumChange
            if self.headingMomentum < 0:
                self.headingMomentum = 0
            if self.headingMomentum > 50:
                self.headingMomentum = 50
            self.curHeading -= self.headingMomentum * dt
            arrowUpdate = True
            arrowRotating = True
        else:
            self.headingMomentum = 0
        if arrowUpdate:
            self.normalizeHeadingAndForce()
            self.updateLocalForceArrow()
        if arrowRotating:
            if not self.arrowRotateSound.status() == self.arrowRotateSound.PLAYING:
                base.playSfx(self.arrowRotateSound, looping=True)
        else:
            self.arrowRotateSound.stop()
        if arrowUp:
            if not self.arrowUpSound.status() == self.arrowUpSound.PLAYING:
                base.playSfx(self.arrowUpSound, looping=False)
        else:
            self.arrowUpSound.stop()
        if arrowDown:
            if not self.arrowDownSound.status() == self.arrowDownSound.PLAYING:
                base.playSfx(self.arrowDownSound, looping=False)
        else:
            self.arrowDownSound.stop()
        return task.cont

    def normalizeHeadingAndForce(self):
        if self.curForce > self.MaxLocalForce:
            self.curForce = self.MaxLocalForce
        if self.curForce < 0.01:
            self.curForce = 0.01

    def setTireInputs(self, tireInputs):
        if not self.hasLocalToon:
            return
        self.allTireInputs = tireInputs
        self.gameFSM.request("moveTires")

    def enableAllTireBodies(self):
        for avId in self.tireDict.keys():
            self.tireDict[avId]["tireBody"].enable()

    def disableAllTireBodies(self):
        for avId in self.tireDict.keys():
            self.tireDict[avId]["tireBody"].disable()

    def areAllTiresDisabled(self):
        for avId in self.tireDict.keys():
            if self.tireDict[avId]["tireBody"].isEnabled():
                return False

        return True

    def __moveTiresTask(self, task):
        if self.areAllTiresDisabled():
            self.sendTirePositions()
            self.gameFSM.request("synch")
            return task.done
        return task.cont

    def sendTirePositions(self):
        tirePositions = []
        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            tire = self.getTireBody(avId)
            pos = Point3(tire.getPosition())
            tirePositions.append([pos[0], pos[1], pos[2]])

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            tire = self.getTireBody(avId)
            pos = Point3(tire.getPosition())
            tirePositions.append([pos[0], pos[1], pos[2]])

        self.sendUpdate("endingPositions", [tirePositions])

    def setFinalPositions(self, finalPos):
        if not self.hasLocalToon:
            return
        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            tire = self.getTireBody(avId)
            np = self.getTireNp(avId)
            pos = finalPos[index]
            tire.setPosition(pos[0], pos[1], pos[2])
            np.setPos(pos[0], pos[1], pos[2])

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            tire = self.getTireBody(avId)
            np = self.getTireNp(avId)
            pos = finalPos[index]
            tire.setPosition(pos[0], pos[1], pos[2])
            np.setPos(pos[0], pos[1], pos[2])

    def updateInfoLabel(self):
        self.infoLabel["text"] = TTLocalizer.IceGameInfo % {
            "curMatch": self.curMatch + 1,
            "numMatch": IceGameGlobals.NumMatches,
            "curRound": self.curRound + 1,
            "numRound": IceGameGlobals.NumRounds,
        }

    def setMatchAndRound(self, match, round):
        if not self.hasLocalToon:
            return
        self.curMatch = match
        self.curRound = round
        self.updateInfoLabel()

    def setScores(self, match, round, scores):
        if not self.hasLocalToon:
            return
        self.newMatch = match
        self.newRound = round
        self.newScores = scores

    def setNewState(self, state):
        if not self.hasLocalToon:
            return
        self.notify.debug("setNewState gameFSM=%s newState=%s" % (self.gameFSM, state))
        self.gameFSM.request(state)

    def putAllTiresInStartingPositions(self):
        for index in xrange(len(self.avIdList)):
            avId = self.avIdList[index]
            np = self.tireDict[avId]["tireNodePath"]
            np.setPos(IceGameGlobals.StartingPositions[index])
            self.notify.debug("avId=%s newPos=%s" % (avId, np.getPos))
            np.setHpr(0, 0, 0)
            quat = np.getQuat()
            body = self.tireDict[avId]["tireBody"]
            body.setPosition(IceGameGlobals.StartingPositions[index])
            body.setQuaternion(quat)

        for index in xrange(len(self.avIdList), 4):
            avId = -index
            np = self.tireDict[avId]["tireNodePath"]
            np.setPos(IceGameGlobals.StartingPositions[index])
            self.notify.debug("avId=%s newPos=%s" % (avId, np.getPos))
            np.setHpr(0, 0, 0)
            quat = np.getQuat()
            body = self.tireDict[avId]["tireBody"]
            body.setPosition(IceGameGlobals.StartingPositions[index])
            body.setQuaternion(quat)

    def b_setForceArrowInfo(self, avId, force, heading):
        self.setForceArrowInfo(avId, force, heading)
        self.d_setForceArrowInfo(avId, force, heading)

    def d_setForceArrowInfo(self, avId, force, heading):
        sendIt = False
        curTime = self.getCurrentGameTime()
        if self.sendForceArrowUpdateAsap:
            sendIt = True
        elif curTime - self.lastForceArrowUpdateTime > 0.2:
            sendIt = True
        if sendIt:
            self.sendUpdate("setForceArrowInfo", [avId, force, heading])
            self.sendForceArrowUpdateAsap = False
            self.lastForceArrowUpdateTime = self.getCurrentGameTime()

    def setForceArrowInfo(self, avId, force, heading):
        if not self.hasLocalToon:
            return
        self.updateForceArrow(avId, force, heading)

    def setupStartOfMatch(self):
        self.putAllTiresInStartingPositions()
        szId = self.getSafezoneId()
        self.numTreasures = IceGameGlobals.NumTreasures[szId]
        if self.treasures:
            for treasure in self.treasures:
                treasure.destroy()

            self.treasures = []
        index = 0
        treasureMargin = IceGameGlobals.TireRadius + 1.0
        while len(self.treasures) < self.numTreasures:
            xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5)
            yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5)
            self.notify.debug("yPos=%s" % yPos)
            pos = Point3(xPos, yPos, IceGameGlobals.TireRadius)
            newTreasure = IceTreasure.IceTreasure(self.treasureModel, pos, index, self.doId, penalty=False)
            goodSpot = True
            for obstacle in self.obstacles:
                if newTreasure.nodePath.getDistance(obstacle) < treasureMargin:
                    goodSpot = False
                    break

            if goodSpot:
                for treasure in self.treasures:
                    if newTreasure.nodePath.getDistance(treasure.nodePath) < treasureMargin:
                        goodSpot = False
                        break

            if goodSpot:
                self.treasures.append(newTreasure)
                index += 1
            else:
                newTreasure.destroy()

        self.numPenalties = IceGameGlobals.NumPenalties[szId]
        if self.penalties:
            for penalty in self.penalties:
                penalty.destroy()

            self.penalties = []
        index = 0
        while len(self.penalties) < self.numPenalties:
            xPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[0] + 5, IceGameGlobals.MaxWall[0] - 5)
            yPos = self.randomNumGen.randrange(IceGameGlobals.MinWall[1] + 5, IceGameGlobals.MaxWall[1] - 5)
            self.notify.debug("yPos=%s" % yPos)
            pos = Point3(xPos, yPos, IceGameGlobals.TireRadius)
            newPenalty = IceTreasure.IceTreasure(self.penaltyModel, pos, index, self.doId, penalty=True)
            goodSpot = True
            for obstacle in self.obstacles:
                if newPenalty.nodePath.getDistance(obstacle) < treasureMargin:
                    goodSpot = False
                    break

            if goodSpot:
                for treasure in self.treasures:
                    if newPenalty.nodePath.getDistance(treasure.nodePath) < treasureMargin:
                        goodSpot = False
                        break

            if goodSpot:
                for penalty in self.penalties:
                    if newPenalty.nodePath.getDistance(penalty.nodePath) < treasureMargin:
                        goodSpot = False
                        break

            if goodSpot:
                self.penalties.append(newPenalty)
                index += 1
            else:
                newPenalty.destroy()

    def toonHitSomething(self, entry):
        self.notify.debug("---- treasure Enter ---- ")
        self.notify.debug("%s" % entry)
        name = entry.getIntoNodePath().getName()
        parts = name.split("-")
        if len(parts) < 3:
            self.notify.debug("collided with %s, but returning" % name)
            return
        if not int(parts[1]) == self.doId:
            self.notify.debug("collided with %s, but doId doesn't match" % name)
            return
        treasureNum = int(parts[2])
        if "penalty" in parts[0]:
            self.__penaltyGrabbed(treasureNum)
        else:
            self.__treasureGrabbed(treasureNum)

    def __treasureGrabbed(self, treasureNum):
        self.treasures[treasureNum].showGrab()
        self.treasureGrabSound.play()
        self.sendUpdate("claimTreasure", [treasureNum])

    def setTreasureGrabbed(self, avId, treasureNum):
        if not self.hasLocalToon:
            return
        self.notify.debug("treasure %s grabbed by %s" % (treasureNum, avId))
        if avId != self.localAvId:
            self.treasures[treasureNum].showGrab()
        i = self.avIdList.index(avId)
        self.scores[i] += 1
        self.scorePanels[i].setScore(self.scores[i])

    def __penaltyGrabbed(self, penaltyNum):
        self.penalties[penaltyNum].showGrab()
        self.sendUpdate("claimPenalty", [penaltyNum])

    def setPenaltyGrabbed(self, avId, penaltyNum):
        if not self.hasLocalToon:
            return
        self.notify.debug("penalty %s grabbed by %s" % (penaltyNum, avId))
        if avId != self.localAvId:
            self.penalties[penaltyNum].showGrab()
        i = self.avIdList.index(avId)
        self.scores[i] -= 1
        self.scorePanels[i].setScore(self.scores[i])

    def postStep(self):
        DistributedIceWorld.DistributedIceWorld.postStep(self)
        if not self.colCount:
            return
        for count in xrange(self.colCount):
            c0, c1 = self.getOrderedContacts(count)
            if c1 in self.tireCollideIds:
                tireIndex = self.tireCollideIds.index(c1)
                if c0 in self.tireCollideIds:
                    self.tireSounds[tireIndex]["tireHit"].play()
                elif c0 == self.wallCollideId:
                    self.tireSounds[tireIndex]["wallHit"].play()
                elif c0 == self.obstacleCollideId:
                    self.tireSounds[tireIndex]["obstacleHit"].play()

    def forceLocalToonToTire(self):
        toon = localAvatar
        if toon and self.localAvId in self.tireDict:
            tireNp = self.tireDict[self.localAvId]["tireNodePath"]
            toon.reparentTo(tireNp)
            toon.setPosHpr(0, 0, 0, 0, 0, 0)
            toon.setY(1.0)
            toon.setZ(-3)
示例#55
0
class cWorld:
    def __init__(self):
        #  set background color
        base.setBackgroundColor(0, 0, 0)
        # create target
        self.createTarget()
        # create boids
        self.createBoids()
        # setup camera
        self.setupCamera()
        # setup lights
        self.setupLights()
        # setup collision detection
        self.setupCollision()
        # add task
        taskMgr.add(self.steer, 'steer')  # steer task
        taskMgr.add(self.moveTarget, 'moveTarget')  # mouse move target task

    def createBoids(self):
        self.redBoid = cBoid()  # create red boid
        # setup blue boid with model path, starting location, max force, and max speed
        self.redBoid.setup('assets/models/boid_one.egg', Vec3(0.0, 0.0, 0.0),
                           4.0, 0.1)
        # create blue boid
        self.blueBoid = cBoid()
        # setup blue boid with model path, starting location, max force, and max speed
        self.blueBoid.setup('assets/models/boid_two.egg', Vec3(0.0, 0.0, 0.0),
                            4.0, 1.0)

    def createTarget(self):
        # load in model file
        self.target = loader.loadModel('assets/models/target.egg')
        # parent
        self.target.reparentTo(render)
        # set location
        self.target.setPos(Vec3(0.0, 0.0, 0.0))

    def setupCamera(self):
        # disable auto controls
        base.disableMouse()
        # set position, heading, pitch, and roll
        camera.setPosHpr(Vec3(0.0, -45.0, 45.0), Vec3(0.0, -45.0, 0))

    def setupLights(self):
        # create a point light
        plight = PointLight('plight')
        # set its color
        plight.setColor(VBase4(1.0, 1.0, 1.0, 1))
        # attach the light to the render
        plnp = render.attachNewNode(plight)
        # set position
        plnp.setPos(0.0, 0.0, 2.0)
        # turn on light
        render.setLight(plnp)

    def setupCollision(self):
        # create collision traverser
        self.picker = CollisionTraverser()
        # create collision handler
        self.pq = CollisionHandlerQueue()
        # create collision node
        self.pickerNode = CollisionNode('mouseRay')  # create collision node
        # attach new collision node to camera node
        self.pickerNP = camera.attachNewNode(
            self.pickerNode)  # attach collision node to camera
        # set bit mask to one
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))  # set bit mask
        # create a collision ray
        self.pickerRay = CollisionRay()  # create collision ray
        # add picker ray to the picker node
        self.pickerNode.addSolid(
            self.pickerRay)  # add the collision ray to the collision node
        # make the traverser know about the picker node and its even handler queue
        self.picker.addCollider(
            self.pickerNP,
            self.pq)  # add the colision node path and collision handler queue
        #self.picker.showCollisions( render ) # render or draw the collisions
        #self.pickerNP.show( ) # render picker ray
        # create col node
        self.colPlane = CollisionNode('colPlane')
        # add solid to col node plane
        self.colPlane.addSolid(
            CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0))))
        # attach new node to the render
        self.colPlanePath = render.attachNewNode(self.colPlane)
        #self.colPlanePath.show( ) # render node
        # make the col plane look at the camera
        # this makes it alway look at the camera no matter the orientation
        # we need this because the ray nees to intersect a plane parallel
        # to the camera
        self.colPlanePath.lookAt(camera)
        # prop up the col plane
        self.colPlanePath.setP(-45)
        # set bit mask to one
        # as I understand it, this makes all col nodes with bit mask one
        # create collisions while ignoring others of other masks
        self.colPlanePath.node().setIntoCollideMask(BitMask32.bit(1))

    def steer(self, Task):
        # seek after target
        self.redBoid.seek(Vec3(self.target.getPos()))
        # run the algorithm
        self.redBoid.run()
        # arrive at the target
        self.blueBoid.arrive(Vec3(self.target.getPos()))
        # run the algorithm
        self.blueBoid.run()
        return Task.cont  # continue task

    def moveTarget(self, Task):
        # traverse through the render tree
        self.picker.traverse(render)
        # go through the queue of collisions
        for i in range(self.pq.getNumEntries()):
            entry = self.pq.getEntry(i)  # get entry
            surfacePoint = entry.getSurfacePoint(
                render)  # get surface point of collision
            self.target.setPos(
                surfacePoint)  # set surface point to target's position
        if base.mouseWatcherNode.hasMouse():  # if we have a mouse
            mpos = base.mouseWatcherNode.getMouse(
            )  # get the path to the mouse
            # shoot ray from camera
            # based on X & Y coordinate of mouse
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
        return Task.cont  # continue task
示例#56
0
class MouseControls(DirectObject.DirectObject):
    def __init__(self):

        self.keys = {}
        for char in string.ascii_lowercase:
            self.keys[char] = BUTTON_UP

            def makeKeyPair(ch):
                def keyUp():
                    self.keys[ch] = BUTTON_DOWN
                    #print "%s UP" % (ch)
                def keyDown():
                    self.keys[ch] = BUTTON_UP
                    #print "%s DOWN" % (ch)

                return [keyUp, keyDown]

            keyPair = makeKeyPair(char)
            self.accept(char, keyPair[0])
            self.accept(char + '-up', keyPair[1])

        self.accept('mouse1', self.leftClick)
        self.accept('mouse1-up', self.leftClickUp)
        self.accept('mouse2', self.mClick)
        self.accept('mouse2-up', self.mClickUp)
        self.accept('mouse3', self.rightClick)
        self.accept('mouse3-up', self.rightClickUp)

        self.mouse1Down = False
        self.mouse2Down = False
        self.mouse3Down = False
        self.trackMouseTimeOld = 0
        self.trackMouseX = 0
        self.trackMouseY = 0
        self.trackMouse_Mouse1DownOld = False
        self.trackMouse_Mouse2DownOld = False
        self.trackMouse_Mouse3DownOld = False
        taskMgr.add(self.trackMouseTask, 'trackMouseTask')

        #
        base.cTrav = CollisionTraverser()
        self.pickerQ = CollisionHandlerQueue()
        self.pickerCollN = CollisionNode('mouseRay')
        self.pickerCamN = base.camera.attachNewNode(self.pickerCollN)
        self.pickerCollN.setFromCollideMask(BitMask32.bit(1))
        self.pickerRay = CollisionRay()
        self.pickerCollN.addSolid(self.pickerRay)
        base.cTrav.addCollider(self.pickerCamN, self.pickerQ)

        self.objectUnderCursor = None
        #taskMgr.add(self.mousePickerTask, 'Mouse picker process')

    def leftClick(self):
        self.mouse1Down = True

        #Collision traversal
        pickerNode = CollisionNode('mouseRay')
        pickerNP = base.camera.attachNewNode(pickerNode)
        pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        pickerRay = CollisionRay()
        pickerNode.addSolid(pickerRay)
        myTraverser = CollisionTraverser()
        myHandler = CollisionHandlerQueue()
        myTraverser.addCollider(pickerNP, myHandler)

        if base.mouseWatcherNode.hasMouse():

            mpos = base.mouseWatcherNode.getMouse()
            pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            myTraverser.traverse(render)
            # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
            if myHandler.getNumEntries() > 0:
                # This is so we get the closest object
                myHandler.sortEntries()
                pickedObj = myHandler.getEntry(0).getIntoNodePath()
                objTag = pickedObj.findNetTag('mouseCollisionTag').getTag(
                    'mouseCollisionTag')
                if objTag and len(objTag) > 0:
                    messenger.send('object_click', [objTag])
        pickerNP.remove()

    def leftClickUp(self):
        self.mouse1Down = False

    def mClick(self):
        self.mouse2Down = True

    def mClickUp(self):
        self.mouse2Down = False

    def rightClick(self):
        self.mouse3Down = True

    def rightClickUp(self):
        self.mouse3Down = False

    def trackMouseTask(self, task):
        timeElapsed = task.time - self.trackMouseTimeOld
        if timeElapsed < 0.05:
            return Task.cont
        self.trackMouseTimeOld = task.time

        if base.mouseWatcherNode.hasMouse():
            mX = base.mouseWatcherNode.getMouseX()
            mY = base.mouseWatcherNode.getMouseY()
            diffX = mX - self.trackMouseX
            diffY = mY - self.trackMouseY
            if (abs(diffX) > DRAG_THRESH) or (abs(diffY) > DRAG_THRESH):
                messenger.send('mouseDelta', [diffX, diffY])
                self.trackMouseX = mX
                self.trackMouseY = mY
                if self.trackMouse_Mouse1DownOld and self.mouse1Down:
                    messenger.send('mouse1Delta', [diffX, diffY])
                if self.trackMouse_Mouse2DownOld and self.mouse2Down:
                    messenger.send('mouse2Delta', [diffX, diffY])
                if self.trackMouse_Mouse3DownOld and self.mouse3Down:
                    messenger.send('mouse3Delta', [diffX, diffY])

            self.trackMouse_Mouse1DownOld = self.mouse1Down
            self.trackMouse_Mouse2DownOld = self.mouse2Down
            self.trackMouse_Mouse3DownOld = self.mouse3Down
        return Task.cont

    def mousePickerTask(self, task):
        print 'lalala: ', self.objectUnderCursor
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            #self.picker.traverse(base.render)
            if self.pickerQ.getNumEntries() > 0:
                self.pickerQ.sortEntries()
                firstNode = self.pickerQ.getEntry(0).getIntoNode()
                if firstNode != self.objectUnderCursor:
                    if self.objectUnderCursor:
                        messenger.send(
                            'interactive-scene-event',
                            [self.objectUnderCursor.getName(), 'rollout'])
                        print 'Rollout', self.objectUnderCursor.getName()
                    self.objectUnderCursor = firstNode
                    messenger.send(
                        'interactive-scene-event',
                        [self.objectUnderCursor.getName(), 'rollin'])
                    print 'Rollin', self.objectUnderCursor.getName()
            else:
                if self.objectUnderCursor:
                    messenger.send(
                        'interactive-scene-event',
                        [self.objectUnderCursor.getName(), 'rollout'])
                    print 'Rollout', self.objectUnderCursor.getName()
                    self.objectUnderCursor = None
        return task.cont
示例#57
0
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.debug = True
        self.statusLabel = self.makeStatusLabel(0)
        self.collisionLabel = self.makeStatusLabel(1)

        self.world = self.loader.loadModel("world.bam")
        self.world.reparentTo(self.render)

        self.maxspeed = 100.0
        # Avion à la pointe des chateaux, direction Ouest !
        self.startPos = Vec3(1200, 320, 85)
        #print (self.startPos)
        self.startHpr = Vec3(0, 0, 0)
        #self.player.setPos(1200,320,85)
        #self.player.setH(0)
        self.player = self.loader.loadModel("alliedflanker.egg")
        #self.player.setPos(640,640,85)
        self.player.setScale(0.2, 0.2, 0.2)
        self.player.reparentTo(self.render)
        self.resetPlayer()

        # load the explosion ring
        self.explosionModel = loader.loadModel('explosion')
        self.explosionModel.reparentTo(self.render)
        self.explosionModel.setScale(0.0)
        self.explosionModel.setLightOff()
        # only one explosion at a time:
        self.exploding = False

        # performance (to be masked later by fog) and view:
        self.maxdistance = 1200
        self.camLens.setFar(self.maxdistance)
        self.camLens.setFov(60)

        self.taskMgr.add(self.updateTask, "update")
        self.keyboardSetup()

        # relevant for world boundaries
        self.worldsize = 1024

        self.createEnvironment()

        self.setupCollisions()
        self.textCounter = 0

    def resetPlayer(self):
        self.player.show()
        #self.player.setPos(self.world,self.startPos)
        #self.player.setHpr(self.world,self.startHpr)
        self.player.setPos(self.startPos)
        self.player.setHpr(self.startHpr)
        self.speed = 10.0
        #self.speed = self.maxspeed/2

        #print (self.player.getPos())

    def makeStatusLabel(self, i):
        return OnscreenText(style=2, fg=(.5,1,.5,1), pos=(-1.3,0.92-(.08 * i)), \
  align=TextNode.ALeft, scale = .08, mayChange = 1)

    def updateTask(self, task):
        self.updatePlayer()
        self.updateCamera()

        self.collTrav.traverse(self.render)
        for i in range(self.playerGroundHandler.getNumEntries()):
            entry = self.playerGroundHandler.getEntry(i)
            if (self.debug == True):
                self.collisionLabel.setText("DEAD:" +
                                            str(globalClock.getFrameTime()))
            if (self.exploding == False):
                self.player.setZ(
                    entry.getSurfacePoint(self.render).getZ() + 10)
                self.explosionSequence()
            # we will later deal with 'what to do' when the player dies

        return task.cont

    def keyboardSetup(self):
        self.keyMap = {"left":0, "right":0, "climb":0, "fall":0, \
            "accelerate":0, "decelerate":0, "fire":0}

        self.accept("escape", sys.exit)

        ## Gestion Vitesse
        self.accept("a", self.setKey, ["accelerate", 1])
        self.accept("a-up", self.setKey, ["accelerate", 0])

        self.accept("q", self.setKey, ["decelerate", 1])
        self.accept("q-up", self.setKey, ["decelerate", 0])

        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])

        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_right-up", self.setKey, ["right", 0])

        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("arrow_left-up", self.setKey, ["left", 0])

        self.accept("arrow_down", self.setKey, ["climb", 1])
        self.accept("arrow_down-up", self.setKey, ["climb", 0])

        self.accept("arrow_up", self.setKey, ["fall", 1])
        self.accept("arrow_up-up", self.setKey, ["fall", 0])

        # self.accept(“space”, self.setKey, [“fire”,1])
        # self.accept(“space-up”, self.setKey, [“fire”,0])
        base.disableMouse()  # or updateCamera will fail!

    def setKey(self, key, value):
        self.keyMap[key] = value

    def updateCamera(self):
        # see issue content for how we calculated these:
        self.camera.setPos(self.player, 25.6225, 3.8807, 10.2779)
        #self.camera.setPos(0, 0, 90)
        self.camera.setHpr(self.player, 94.8996, -16.6549, 1.55508)

    def updatePlayer(self):
        # Global Clock
        # by default, panda runs as fast as it can frame to frame
        scalefactor = (globalClock.getDt() * self.speed)
        #climbfactor = scalefactor * 0.5
        #bankfactor = scalefactor
        #speedfactor = scalefactor * 2.9
        climbfactor = scalefactor * 0.5 * 2
        bankfactor = scalefactor * 2.0
        speedfactor = scalefactor * 2.9

        # throttle control
        if (self.keyMap["accelerate"] != 0):
            self.speed += 1
            if (self.speed > self.maxspeed):
                self.speed = self.maxspeed

        elif (self.keyMap["decelerate"] != 0):
            self.speed -= 1
            if (self.speed < 0.0):
                self.speed = 0.0

        # Left and Right
        if (self.keyMap["left"] != 0 and self.speed > 0.0):
            self.player.setH(self.player.getH() + bankfactor)
            self.player.setP(self.player.getP() + bankfactor)
            if (self.player.getP() >= 180):
                self.player.setP(-180)

        elif (self.keyMap["right"] != 0 and self.speed > 0.0):
            self.player.setH(self.player.getH() - bankfactor)
            self.player.setP(self.player.getP() - bankfactor)
            if (self.player.getP() <= -180):
                self.player.setP(180)

        elif (self.player.getP() > 0):  # autoreturn from right
            self.player.setP(self.player.getP() - (bankfactor + 0.1))
            if (self.player.getP() < 0): self.player.setP(0)

        elif (self.player.getP() < 0):  # autoreturn from left
            self.player.setP(self.player.getP() + (bankfactor + 0.1))
            if (self.player.getP() > 0):
                self.player.setP(0)

        # Climb and Fall
        if (self.keyMap["climb"] != 0 and self.speed > 0.00):
            # faster you go, quicker you climb
            self.player.setZ(self.player.getZ() + climbfactor)
            self.player.setR(self.player.getR() + climbfactor)
            if (self.player.getR() >= 180):
                self.player.setR(-180)

        elif (self.keyMap["fall"] != 0 and self.speed > 0.00):
            self.player.setZ(self.player.getZ() - climbfactor)
            self.player.setR(self.player.getR() - climbfactor)
            if (self.player.getR() <= -180):
                self.player.setR(180)

        elif (self.player.getR() > 0):  # autoreturn from up
            self.player.setR(self.player.getR() - (climbfactor + 0.1))
            if (self.player.getR() < 0):
                self.player.setR(0)
        # avoid jitter
        elif (self.player.getR() < 0):  # autoreturn from down
            self.player.setR(self.player.getR() + (climbfactor + 0.1))
            if (self.player.getR() > 0):
                self.player.setR(0)

        # move forwards - our X/Y is inverted, see the issue
        if self.exploding == False:
            self.player.setX(self.player, -speedfactor)
            self.applyBoundaries()

    def createEnvironment(self):
        # Fog to hide a performance tweak:
        colour = (0.0, 0.0, 0.0)
        expfog = Fog("scene-wide-fog")
        expfog.setColor(*colour)
        expfog.setExpDensity(0.001)  # original : 0.004
        render.setFog(expfog)
        base.setBackgroundColor(*colour)

        # Our sky
        skydome = loader.loadModel('sky.egg')
        skydome.setEffect(CompassEffect.make(self.render))
        skydome.setScale(self.maxdistance / 2)  # bit less than "far"
        skydome.setZ(-65)  # sink it
        # NOT render - you'll fly through the sky!:
        skydome.reparentTo(self.camera)

        # Our lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.6, .6, .6, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(0, -10, -10))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def setupCollisions(self):
        self.collTrav = CollisionTraverser()

        self.playerGroundSphere = CollisionSphere(0, 1.5, -1.5, 1.5)
        self.playerGroundCol = CollisionNode('playerSphere')
        self.playerGroundCol.addSolid(self.playerGroundSphere)

        # bitmasks
        self.playerGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.playerGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.world.setCollideMask(BitMask32.bit(0))

        # and done
        self.playerGroundColNp = self.player.attachNewNode(
            self.playerGroundCol)
        self.playerGroundHandler = CollisionHandlerQueue()
        self.collTrav.addCollider(self.playerGroundColNp,
                                  self.playerGroundHandler)

        # DEBUG
        if (self.debug == True):
            self.playerGroundColNp.show()
            self.collTrav.showCollisions(self.render)

    def applyBoundaries(self):
        if (self.player.getZ() > self.maxdistance):
            self.player.setZ(self.maxdistance)
        # should never happen once we add collision, but in case:
        elif (self.player.getZ() < 0):
            self.player.setZ(0)

        # and now the X/Y world boundaries:
        boundary = False
        if (self.player.getX() < 0):
            self.player.setX(0)
            boundary = True
        elif (self.player.getX() > self.worldsize):
            self.player.setX(self.worldsize)
            boundary = True
        if (self.player.getY() < 0):
            self.player.setY(0)
            boundary = True
        elif (self.player.getY() > self.worldsize):
            self.player.setY(self.worldsize)
            boundary = True

        # lets not be doing this every frame...
        if boundary == True and self.textCounter > 30:
            self.statusLabel.setText("STATUS: MAP END; TURN AROUND")
        elif self.textCounter > 30:
            self.statusLabel.setText("STATUS: OK")

        if self.textCounter > 30:
            self.textCounter = 0
        else:
            self.textCounter = self.textCounter + 1

    def explosionSequence(self):
        self.exploding = True
        self.explosionModel.setPosHpr( Vec3(self.player.getX(),self.player.getY(), \
                               self.player.getZ()), Vec3( self.player.getH(),0,0))
        self.player.hide()
        taskMgr.add(self.expandExplosion, 'expandExplosion')

    def expandExplosion(self, Task):
        # expand the explosion rign each frame until a certain size
        if self.explosionModel.getScale() < VBase3(60.0, 60.0, 60.0):
            factor = globalClock.getDt()
            scale = self.explosionModel.getScale()
            scale = scale + VBase3(factor * 40, factor * 40, factor * 40)
            self.explosionModel.setScale(scale)
            return Task.cont
        else:
            self.explosionModel.setScale(0)
            self.exploding = False
            self.resetPlayer()
示例#58
0
class Mouse(DirectObject):
    def __init__(self, app):
        # local variables for mouse class
        self.app = app
        self.init_collide()
        self.has_mouse = None
        self.prev_pos = None
        self.pos = None
        self.drag_start = None
        self.hovered_object = None
        self.button2 = False
        self.mouseTask = taskMgr.add(self.mouse_task, 'mouseTask')
        self.task = None
        # set up event and response to this event
        self.accept('mouse1', self.mouse1)
        self.accept('mouse1-up', self.mouse1_up)
        # change the mouse to accept 'right-click' to rotate camera
        self.accept('mouse3', self.rotateCamera)
        self.accept('mouse3-up', self.stopCamera)
        self.accept('wheel_up', self.zoomIn)
        self.accept('wheel_down', self.zoomOut)

    # set up the collision for object
    def init_collide(self):
        # why the heck he import within method
        from pandac.PandaModules import CollisionTraverser, CollisionNode
        from pandac.PandaModules import CollisionHandlerQueue, CollisionRay
        # init and import collision for object
        self.cTrav = CollisionTraverser('MousePointer')
        self.cQueue = CollisionHandlerQueue()
        self.cNode = CollisionNode('MousePointer')
        self.cNodePath = base.camera.attachNewNode(self.cNode)
        self.cNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.cRay = CollisionRay()
        self.cNode.addSolid(self.cRay)
        self.cTrav.addCollider(self.cNodePath, self.cQueue)

    # by the collision methods mouse is able to find out which tile mouse is at
    def find_object(self):
        if self.app.world.nodePath:
            self.cRay.setFromLens(base.camNode, self.pos.getX(),
                                  self.pos.getY())
            self.cTrav.traverse(self.app.world.terrain.nodePath)
            if self.cQueue.getNumEntries() > 0:
                self.cQueue.sortEntries()
                return self.cQueue.getEntry(0).getIntoNodePath()
        return None

    # setting task for mouse
    def mouse_task(self, task):
        action = task.cont
        # if the current tile has a mouse point to this
        self.has_mouse = base.mouseWatcherNode.hasMouse()
        if self.has_mouse:
            self.pos = base.mouseWatcherNode.getMouse()
            if self.prev_pos:
                self.delta = self.pos - self.prev_pos
            else:
                self.delta = None
            if self.task:
                action = self.task(task)
        else:
            self.pos = None
        if self.pos:
            self.prev_pos = Point2(self.pos.getX(), self.pos.getY())
        return action

    # when mouse hover over this hexagon
    def hover(self, task):
        if self.hovered_object:
            self.hovered_object.unhover()
            self.hovered_object = None
        if self.button2:
            self.camera_drag()
        hovered_nodePath = self.find_object()
        if hovered_nodePath:
            tile = hovered_nodePath.findNetTag('tile')
            if not tile.isEmpty():
                tag = tile.getTag('tile')
                coords = tag.split(',')
                (x, y) = [int(n) for n in coords]
                # set the hovered target to be the corresponding hexagon on terrain
                self.hovered_object = self.app.world.terrain.rows[x][y]
                self.hovered_object.hover()
            character = hovered_nodePath.findNetTag('char')
            if not character.isEmpty():
                tag = character.getTag('char')
                (team_index, char_id) = [int(n) for n in tag.split(',')]
                self.hovered_object = self.app.world.teams[
                    team_index].characters_dict[char_id]
                self.hovered_object.hover()
            ghost = hovered_nodePath.findNetTag('ghost')
            if not ghost.isEmpty():
                tag = ghost.getTag('ghost')
                (team_index, char_id) = [int(n) for n in tag.split(',')]
                for ghostInstance in self.app.ghosts:
                    if (ghostInstance.team.index
                            == team_index) and (ghostInstance.id == char_id):
                        self.hovered_object = ghostInstance
                self.hovered_object.hover()
        return task.cont

    def mouse1(self):
        self.app.state.request('mouse1')

    def mouse1_up(self):
        self.app.state.request('mouse1-up')

    def camera_drag(self):
        if self.delta:
            old_heading = base.camera.getH()
            new_heading = old_heading - self.delta.getX() * 180
            base.camera.setH(new_heading % 360)
            old_pitch = base.camera.getP()
            new_pitch = old_pitch + self.delta.getY() * 90
            new_pitch = max(-90, min(-10, new_pitch))
            base.camera.setP(new_pitch)

    def rotateCamera(self):
        self.button2 = True

    def stopCamera(self):
        self.button2 = False

    def zoomIn(self):
        lens = base.cam.node().getLens()
        size = lens.getFilmSize()
        if size.length() >= 75:
            lens.setFilmSize(size / 1.2)

    def zoomOut(self):
        lens = base.cam.node().getLens()
        size = lens.getFilmSize()
        if size.length() <= 250:
            lens.setFilmSize(size * 1.2)
示例#59
0
class World(DirectObject):
    #class World, extends DirectObject, builds the world to play the game

###################### INITIALIZATIONS #########################################
    def __init__(self):

        mySplashScreen = SplashScreen()
        mySplashScreen.loading()
        mySplashScreen.introduction()
        self.promptMode()

        self.turnWallNotification()

        ##### Creating Scene #####
        self.createBackground()
        self.loadWallModel()
        self.loadBallModel()
        self.setCamera()
        self.createLighting()

        ##### Create Controls #####
        self.createKeyControls()
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "drop":0}

        ##### Task Manager #####
        timer = 0.2
        taskMgr.doMethodLater(timer, self.traverseTask, "tsk_traverse")
            #scans for collisions every 0.2 seconds
        taskMgr.add(self.move,"moveTask")
            #constant smooth movement

        ##### Collisions #####
        self.createBallColliderModel()
        self.disableForwardMovement = False
        self.disableBackwardMovement = False
        self.disableLeftMovement = False
        self.disableRightMovement = False

        ##### Game state variables #####
        self.isMoving = False
        self.isDropping = False 
        self.camAngle = math.pi/2
        self.direction = "W" #constant; does not change with relativity
        self.drop = False

        self.levelHeight = 2.1
        self.level = 0
        self.maxLevel = 6
        self.currentHeight = 13.302
        self.cameraHeight = 0.2
        self.mode = None
        self.timer = ""

        ##### Views #####
        self.xray_mode = False
        self.collision_mode = False
        self.wireframe = False

        ##### On-Screen Text #####
        self.title = addTitle("aMAZEing")
        self.instructions = OnscreenText(text="[ i ]: Toggle Instructions", 
                style=1, fg=(0, 0, 0, 1), pos=(1.3, 0.95), 
                align=TextNode.ARight, scale=0.05)
        self.instr = []
        self.messages = []
        self.levelText = OnscreenText(text= "Level = " + str(self.level), 
                style=1, fg=(0, 0, 0, 1), pos=(-1.3, -0.95), 
                align=TextNode.ALeft, scale=0.07)
        self.directionText = OnscreenText(text="Direction = " + self.direction,
                style=1, fg=(0, 0, 0, 1), pos=(-1.3, -0.85),
                align=TextNode.ALeft, scale=0.07)

        self.timerText = OnscreenText(text= self.timer, 
                style=1, fg=(1, 1, 1, 1), pos=(1.3, 0.85), 
                align=TextNode.ARight, scale=0.07)
    
    def setKey(self, key, value):
        #records the state of the arrow keys
        self.keyMap[key] = value

    ###################### Onscreen Text #######################################

    def postInstructions(self):
        #posts the instructions onto the screen

        inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.instr.append(inst1)
        inst2 = addInstructions(0.90,  "[Left Arrow]: Turn Left")
        self.instr.append(inst2)
                               
        inst3 = addInstructions(0.85, "[Right Arrow]: Turn Right")
        self.instr.append(inst3)
                                
        inst4 = addInstructions(0.80, "[Up Arrow]: Move Ball Forward")
        self.instr.append(inst4)
                                
        inst5 = addInstructions(0.75,  "[Down Arrow]: Move Ball Backwards")
        self.instr.append(inst5)
                               
        inst6 = addInstructions(0.70,
                            "[Space]: Drop Levels (if level drop is availale)")
        self.instr.append(inst6)
                               
        inst7 = addInstructions(0.60,  "[x]: Toggle XRay Mode")
        self.instr.append(inst7)
                               
        inst8 = addInstructions(0.55, "[c]: Toggle Collision Mode")
        self.instr.append(inst8)
                                
        inst9 = addInstructions(0.50, "[z]: Toggle Wireframe")
        self.instr.append(inst9)

        inst10 = OnscreenText(text='''Hello!
        Welcome to aMAZEing!
        You are this sphere,
        and your goal is to find the exit of the maze! Each level
        of the maze has a hole you can drop through, to move on to the
        next level. This maze has six levels and each maze is a 12x12.
        If you chose timer mode, you have 5 minutes to finish the maze,
        or else you lose.
        Good luck! You're aMAZEing :)''', style = 1, 
                fg=(0, 0, 0, 1), pos=(0, -.1), align=TextNode.ACenter, scale=0.07)
        self.instr.append(inst10)

    def deleteInstructions(self):
        #deletes onscreen instructions
        for instr in self.instr:
            instr.destroy()

    def addNotification(self, txt):
        #adds a notification to the screen
        y = 0.9
        tex = OnscreenText(text=txt, style=1, fg= (0, 0, 0, 1), pos=(0, y))
        self.messages.append(tex)

    def deleteNotifications(self):
        #deletes all on-screen notifications
        for msg in self.messages:
            msg.destroy()

    def updateLevelText(self):
        #updates the level text
        self.levelText.destroy()

        levelTextPos = (-1.3, -0.95)
        levelScale = 0.07

        self.levelText = OnscreenText(text= "Level = " + str(self.level), 
                style=1, fg=(0, 0, 0, 1), pos=levelTextPos, 
                align=TextNode.ALeft, scale=levelScale)

    def updateDirectionText(self):
        #updates the direction text on the screen
        self.directionText.destroy()

        directionTextPos = (-1.3, -0.85)
        directionScale = 0.07

        self.directionText = OnscreenText(text="Direction = " + self.direction,
                style=1, fg=(0, 0, 0, 1), pos=directionTextPos,
                align=TextNode.ALeft, scale=directionScale)

    def updateTimerText(self):
        #updates timer on screen
        self.timerText.destroy()

        timerTextPos = (1.3, 0.85)
        timerScale = 0.07

        if self.mode == "timer":
            self.timerText = OnscreenText(text= self.timer, 
                style=1, fg=(1, 1, 1, 1), pos=timerTextPos, 
                align=TextNode.ARight, scale=timerScale)

    def turnWallNotification(self):
        #give a notification sequence at the beginning
        notificationSeq = Sequence()
        notificationSeq.append(Func(addNotification,"""
        If you just see a blank color,
        it means you are facing a wall :)"""))
        notificationSeq.append(Wait(8))
        notificationSeq.append(Func(deleteNotifications))
        notificationSeq.start()

    def promptMode(self):
        #prompts for the mode
        modeScreen = SplashScreen()
        modeScreen.mode()

    def setMode(self, mode):
        #sets the mode of the game
        self.mode = mode
        
        if self.mode == "timer":
            self.setTimer()

    ###################### Initialization Helper Functions #####################

    def createBackground(self):
        #black feautureless space
        base.win.setClearColor(Vec4(0,0,0,1))

    def loadWallModel(self):
        #loads the wall model (the maze) 
        wallScale = 0.3
        wallModelName = self.randomWallModel()
            #randomly select a maze

        self.wallModel = loader.loadModel(wallModelName)
        self.wallModel.setScale(wallScale)
        self.wallModel.setPos(0, 0, 0)
        self.wallModel.setCollideMask(BitMask32.allOff())
        self.wallModel.reparentTo(render)

        ### Setting Texture ###
        texScale = 0.08
        self.wallModel.setTexGen(TextureStage.getDefault(),
                                   TexGenAttrib.MWorldNormal)
        self.wallModel.setTexProjector(TextureStage.getDefault(),
                                         render, self.wallModel)
        self.wallModel.setTexScale(TextureStage.getDefault(), texScale)
        tex = loader.load3DTexture('/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/wallTex/wallTex_#.png')
        self.wallModel.setTexture(tex)

        #creating visual geometry collision
        self.wallModel.setCollideMask(BitMask32.bit(0))

    def randomWallModel(self):
        #generates a random wall in the library of mazes that were 
        #randomly generated by the Blender script "mazeGenerator"
        #and exported to this computer
        numMazes = 10

        name = str(random.randint(0, numMazes))
            #randomly selects a number saved in the computer

        path = "/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/mazeModels/maze"

        path += name 

        return path
        
    def loadBallModel(self):
        #loads the character, a ball model

        #ballModelStartPos = (-8, -8, 0.701) #THIS IS THE END
        ballModelStartPos = (8, 8, 13.301) #level 0 
        ballScale = 0.01
        self.ballModel = loader.loadModel("/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/ball")
        self.ballModel.reparentTo(render)
        self.ballModel.setScale(ballScale)
        self.ballModel.setPos(ballModelStartPos)


        ### Setting ball texture ###
        texScale = 0.08
        self.ballModel.setTexGen(TextureStage.getDefault(),
                                   TexGenAttrib.MWorldPosition)
        self.ballModel.setTexProjector(TextureStage.getDefault(), 
                                         render, self.ballModel)
        self.ballModel.setTexScale(TextureStage.getDefault(), texScale)
        tex = loader.load3DTexture('/Users/jianwei/Documents/School/Freshman/Semester1/15-112/TERMPROJECT/Project/ballTex/ballTex_#.png')
        self.ballModel.setTexture(tex)

    def setCamera(self):
        #sets up the initial camera location
        #camera will follow the sphere 
        followLength = 2
        camHeight = 0.2

        base.disableMouse()
        base.camera.setPos(self.ballModel.getX(),
                                self.ballModel.getY() - followLength,
                                self.ballModel.getZ() + camHeight)
        base.camLens.setNear(0.4)

        #creates a floater object - will look at the floater object 
        #above the sphere, so you can get a better view
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

    def createKeyControls(self):
        #creates the controllers for the keys
        #event handler
        #describes what each key does when pressed and unpressed

        self.accept("escape", sys.exit)

        self.accept("arrow_left", self.turnLeft)
        self.accept("arrow_right", self.turnRight)
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("arrow_down", self.setKey, ["backward",1])
        self.accept("space", self.nowDropping)

        #unpressed event handlers
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("arrow_down-up", self.setKey, ["backward",0])
        self.accept("space_up", self.setKey, ["drop", 0])

        #views
        self.accept('x', self.toggle_xray_mode)
        self.accept('c', self.toggle_collision_mode)
        self.accept('z', self.toggle_wireframe)

        #information
        self.accept('i', self.postInstructions)
        self.accept('i-up', self.deleteInstructions)

        #restart
        self.accept('r', self.restart)

        #modes
        self.accept("t", self.setMode, ["timer"])
        self.accept("m", self.setMode, ["marathon"])

    def createBallColliderModel(self):
        #creates the collider sphere around the ball
        cSphereRad = 9.9
        self.cTrav = CollisionTraverser() #moves over all possible collisions

        self.ballModelSphere = CollisionSphere(0, 0, 0, cSphereRad)
            #collision mesh around ball is a simple sphere
        self.ballModelCol = CollisionNode('ballModelSphere')
        self.ballModelCol.addSolid(self.ballModelSphere)
        self.ballModelCol.setFromCollideMask(BitMask32.bit(0))
        self.ballModelCol.setIntoCollideMask(BitMask32.allOff())
        self.ballModelColNp = self.ballModel.attachNewNode(self.ballModelCol)
        self.ballModelGroundHandler = CollisionHandlerQueue()
            #collision handler queue stores all collision points
        self.cTrav.addCollider(self.ballModelColNp, self.ballModelGroundHandler)

    def createLighting(self):
        #creates lighting for the scene
        aLightVal = 0.3
        dLightVal1 = -5
        dLightVal2 = 5

        #set up the ambient light
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1))
        ambientLight1 = AmbientLight("ambientLight1")
        ambientLight1.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1))
        ambientLight2 = AmbientLight("ambientLight2")
        ambientLight2.setColor(Vec4(aLightVal, aLightVal, aLightVal, 1))

        #sets a directional light
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(dLightVal1, dLightVal1, dLightVal1))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(0, 0, 0, 1))

        #sets a directional light
        directionalLight1 = DirectionalLight("directionalLight2")
        directionalLight1.setDirection(Vec3(dLightVal2, dLightVal1, dLightVal1))
        directionalLight1.setColor(Vec4(1, 1, 1, 1))
        directionalLight1.setSpecularColor(Vec4(1, 1, 1, 1))


        #attaches lights to scene
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(ambientLight1))
        render.setLight(render.attachNewNode(ambientLight1))
        render.setLight(render.attachNewNode(directionalLight))
        render.setLight(render.attachNewNode(directionalLight1))

###################### COLLISION DETECTION #####################################

    def traverseTask(self, task=None):
        # handles collisions with collision handers and a 
        # collision queue
        # essentially checks region of potential collision for collisions
        # and stops the ball if a collision is triggered
        # called by task manager
        self.ballModelGroundHandler.sortEntries()
        for i in range(self.ballModelGroundHandler.getNumEntries()):
            entry = self.ballModelGroundHandler.getEntry(i)

            if self.drop == True:
                #we cant drop in this situation
                self.ballModel.setZ(self.currentHeight)

                dropFailWait = 4
                dropFailSeq = Sequence()
                dropFailSeq.append(Func(addNotification,"Whoops! You can't drop here!"))
                dropFailSeq.append(Wait(dropFailWait))
                dropFailSeq.append(Func(deleteNotifications))
                dropFailSeq.start()

                self.drop = False

            elif self.direction == "N":
                self.northDisableMovements()

            elif self.direction == "S":
                self.southDisableMovements()

            elif self.direction == "E":
                self.eastDisableMovements()

            elif self.direction == "W":
                self.westDisableMovements()

            if task: return task.cont #exit task

        # If there are no collisions
        
        if task: return task.cont

    def northDisableMovements(self):
        #disables movements when direction is north
        if self.keyMap["forward"] != 0: #if the ball was moving foward
            self.disableForwardMovement = True #disable forward movement
        if self.keyMap["backward"] != 0:
            self.disableBackwardMovement = True

    def southDisableMovements(self):
        #disables movements when direction is south
        if self.keyMap["forward"] != 0: 
            self.disableBackwardMovement = True 
        if self.keyMap["backward"] != 0:
            self.disableForwardMovement = True

    def eastDisableMovements(self):
        #disables movements when direction is east
        if self.keyMap["forward"] != 0: 
            self.disableRightMovement = True 
        if self.keyMap["backward"] != 0:
            self.disableLeftMovement = True

    def westDisableMovements(self):
        #disables movements when direction is west
        if self.keyMap["forward"] != 0: 
            self.disableLeftMovement = True 
        if self.keyMap["backward"] != 0:
            self.disableRightMovement = True

    def checkCollisions(self):
        #checks for collisions
        self.cTrav.traverse(render)

    def enableAllWalls(self):
        #enables all walls by disabling all the disable wall functions
        self.disableLeftMovement = False
        self.disableRightMovement = False 
        self.disableForwardMovement = False
        self.disableBackwardMovement = False

    def inCollision(self):
        #return true if we are in a collision right now, false otherwise
        if (self.disableForwardMovement == True
            or self.disableBackwardMovement == True 
            or self.disableRightMovement == True 
            or self.disableLeftMovement):
            return True
        return False

    def checkForWin(self):
        #checks for a win, toggles win splash sceen if we win
        yLoc = self.ballModel.getY()
        exitBound = -9.1

        if yLoc < exitBound: 
            winScreen = SplashScreen()
            winScreen.win()

        if self.mode == "timer":
            self.checkForTimerLoss()

    def checkForTimerLoss(self):
        #checks to see the time, will lose if past 5 minutes
        
        if self.timer == "0:05:00":
            loseScreen = SplashScreen()
            loseScreen.lose()

###################### MOVEMENTS ###############################################

    def move(self, task):
        # Accepts arrow keys to move the player front and back
        # Also deals with grid checking and collision detection

        step = 0.03

        #movement animation
        self.movementAnimation(step)
        #rotation animation
        self.rotationAnimation()

        base.camera.setX(self.ballModel.getX() + math.sin(self.camAngle))
        base.camera.setY(self.ballModel.getY() + math.cos(self.camAngle))

        self.resetCamDist()
        self.checkCollisions()
        self.lookAtFloater()

        self.checkForWin()

        return task.cont

    def resetCamDist(self):
        #resets the camera distance to a specific distance
        #keeps distance relatively constant
        camFarDist = 0.75
        camCloseDist = 0.7

        camvec = self.ballModel.getPos() - base.camera.getPos()
            #vector between ball and camera
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()

        if (camdist > camFarDist):
            base.camera.setPos(base.camera.getPos() + 
                                    camvec*(camdist-camFarDist))
            camdist = camFarDist

        if (camdist < camCloseDist):
            base.camera.setPos(base.camera.getPos() -
                                    camvec*(camCloseDist-camdist))
            camdist = camCloseDist

        base.camera.lookAt(self.ballModel)

    def lookAtFloater(self):
        #looks at the floater above the sphere
        floaterHeight = 0.23
        self.floater.setPos(self.ballModel.getPos())
        self.floater.setZ(self.ballModel.getZ() + floaterHeight)
        base.camera.lookAt(self.floater)

    ####################### Movement Animation #################################

    def ballIsMoving(self):
        #notes if the ball is moving or not with self.isMoving variable
        if (self.keyMap["forward"]!=0) or (self.keyMap["backward"]!=0):
            if self.isMoving == False:
                self.isMoving = True

        elif self.keyMap["forward"] == 0 and self.keyMap["backward"] == 0:
            self.isMoving = False

    def movementAnimation(self, step):
        #describes the movement animation
        if self.drop == True:
            self.dropMovementAnimation(step)
        elif self.direction == "N":
            self.northMovementAnimation(step)

        elif self.direction == "S":
            self.southMovementAnimation(step)

        elif self.direction == "E":
            self.eastMovementAnimation(step)

        elif self.direction == "W":
            self.westMovementAnimation(step)

    def northMovementAnimation(self, step):
        #describes animation when direction is north
        if (self.keyMap["forward"]!=0):
            #if you are pressing forward
            if self.disableForwardMovement == False:
                #if you are just moving through space...
                self.ballModel.setY(self.ballModel.getY() + step)
            if self.disableBackwardMovement == True:
                #if you had moved backwards into a wall
                #and you want to move forward again
                self.ballModel.setY(self.ballModel.getY() + step)
                self.disableBackwardMovement = False
                

        if (self.keyMap["backward"]!=0):
            #if you are pressing backwards
            if self.disableBackwardMovement == False:
                #if you are just moving backwards through space...
                self.ballModel.setY(self.ballModel.getY() - step)
            if self.disableForwardMovement == True:
                #if you had moved forward into a wall
                #and want to back away from the wall
                self.ballModel.setY(self.ballModel.getY() - step)
                self.disableForwardMovement = False        

    def southMovementAnimation(self, step):
        #describes animation when direction is north
        #same relative set of animations to northMovementAnimation
        #but opposite
        if (self.keyMap["forward"]!=0):
            if self.disableBackwardMovement == False:
                self.ballModel.setY(self.ballModel.getY() - step)
            if self.disableForwardMovement == True:
                self.ballModel.setY(self.ballModel.getY() - step)
                self.disableForwardMovement = False

        if (self.keyMap["backward"]!=0):
            if self.disableForwardMovement == False:
                self.ballModel.setY(self.ballModel.getY() + step)
            if self.disableBackwardMovement == True:
                self.ballModel.setY(self.ballModel.getY() + step)
                self.disableBackwardMovement = False        

    def eastMovementAnimation(self, step):
        #describes animation when direction is east
        #same relative as north and south movement animations
        #but relative to the x axis
        #and disabling/enabling right and left movement at collisions
        if (self.keyMap["forward"]!=0):
            if self.disableRightMovement == False:
                self.ballModel.setX(self.ballModel.getX() + step)
            if self.disableLeftMovement == True:
                self.ballModel.setX(self.ballModel.getX() + step)
                self.disableLeftMovement = False

        if (self.keyMap["backward"]!=0):
            if self.disableLeftMovement == False:
                self.ballModel.setX(self.ballModel.getX() - step)
            if self.disableRightMovement == True:
                self.ballModel.setX(self.ballModel.getX() - step)
                self.disableRightMovement = False

    def westMovementAnimation(self, step):
        #describes animation when direction is west
        #relatively same animations as the east movement animations
        #exact opposite
        if (self.keyMap["forward"]!=0):
            if self.disableLeftMovement == False:
                self.ballModel.setX(self.ballModel.getX() - step)
            if self.disableRightMovement == True:
                self.ballModel.setX(self.ballModel.getX() - step)
                self.disableRightMovement = False

        if (self.keyMap["backward"]!=0):
            if self.disableRightMovement == False:
                self.ballModel.setX(self.ballModel.getX() + step)
            if self.disableLeftMovement == True:
                self.ballModel.setX(self.ballModel.getX() + step)
                self.disableLeftMovement = False

    def turnRight(self):
        #turns right in the animation

        #uses an interval to slowly rotate camera around
        initial = self.camAngle
        final = self.camAngle + math.pi/2

        #turn animation
        turnTime = 0.2
        turnRightSeq = Sequence()
        turnRightSeq.append(LerpFunc(self.changeCamAngle, turnTime, initial,
                                                         final, 'easeInOut'))
        turnRightSeq.start()

        self.setKey("right", 1) #notes that the right key is pressed

        #changes the direction right, based on current direction
        if self.direction == "N":
            self.direction = "E"
        elif self.direction == "E":
            self.direction = "S"
        elif self.direction == "S":
            self.direction = "W"
        else:
            self.direction = "N"

        #when you turn, all the collision disablements should be True
        #just checking
        #self.enableAllWalls()

        #update the label
        self.updateDirectionText()

    def turnLeft(self):
        #turns left

        initial = self.camAngle
        final = self.camAngle - math.pi/2

        #turn animation
        turnTime = 0.2
        turnRightSeq = Sequence()
        turnRightSeq.append(LerpFunc(self.changeCamAngle, turnTime, initial,
                                                         final, 'easeInOut'))
        turnRightSeq.start()


        self.setKey("left", 1) #notes that left key is pressed

        #changes the direction left, based on current direction
        if self.direction == "N":
            self.direction = "W"
        elif self.direction == "W":
            self.direction = "S"
        elif self.direction == "S":
            self.direction = "E"
        else:
            self.direction = "N"

        #when you turn, all the collision disablements should be True
        #just checking
        #self.enableAllWalls()

        #update the label
        self.updateDirectionText()

    def changeCamAngle(self, angle):
        #changes the camAngle to angle
        self.camAngle = angle

    def dropMovementAnimation(self, step):
        #describes movement when drop is hit

        a = 0.1

        if self.keyMap["drop"] != 0:
            if self.ballModel.getZ() > self.currentHeight - self.levelHeight+ a:
                self.ballModel.setZ(self.ballModel.getZ() - step)
            else:
                self.currentHeight -= self.levelHeight
                self.level += 1
                self.updateLevelText()
                self.drop = False
                base.camera.setZ(self.ballModel.getZ() + self.cameraHeight)

    def nowDropping(self):
        #toggles isDropping boolean
        self.drop = True
        self.setKey("drop", 1)
        
    ################## Ball Rotation Animation #################################

    def rotationAnimation(self):
        #describes the rotation movement of sphere
        self.ballIsMoving()
        speed=300
        inCollision = self.inCollision()

        if self.isMoving and not inCollision:
            if self.direction == "N":
                self.northRotationAnimation(speed)
            if self.direction == "S":
                self.southRotationAnimation(speed)
            if self.direction == "E":
                self.eastRotationAnimation(speed)
            if self.direction == "W":
                self.westRotationAnimation(speed)

    def northRotationAnimation(self, speed):
        #describes the rotation animation if direction is north
        if self.keyMap["forward"] != 0:
            self.ballModel.setP(self.ballModel.getP()-speed*globalClock.getDt())
        elif self.keyMap["backward"] != 0:
            self.ballModel.setP(self.ballModel.getP()+speed*globalClock.getDt())

    def southRotationAnimation(self, speed):
        #describes the rotaiton animation if the direction is south
        if self.keyMap["backward"] != 0:
            self.ballModel.setP(self.ballModel.getP()-speed*globalClock.getDt())
        elif self.keyMap["forward"] != 0:
            self.ballModel.setP(self.ballModel.getP()+speed*globalClock.getDt())

    def eastRotationAnimation(self, speed):
        #describes the rotation animation if the direction is east
        if self.keyMap["backward"] != 0:
            self.ballModel.setR(self.ballModel.getR()-speed*globalClock.getDt())
        elif self.keyMap["forward"] != 0:
            self.ballModel.setR(self.ballModel.getR()+speed*globalClock.getDt())

    def westRotationAnimation(self, speed):
        #describes the rotation animation if the direction is west
        if self.keyMap["forward"] != 0:
            self.ballModel.setR(self.ballModel.getR()-speed*globalClock.getDt())
        elif self.keyMap["backward"] != 0:
            self.ballModel.setR(self.ballModel.getR()+speed*globalClock.getDt())

###################### VIEWS ###################################################

    def toggle_xray_mode(self):
        #Toggle X-ray mode on and off.
        #Note: slows down program considerably
        xRayA = 0.5
        self.xray_mode = not self.xray_mode
        if self.xray_mode:
            self.wallModel.setColorScale((1, 1, 1, xRayA))
            self.wallModel.setTransparency(TransparencyAttrib.MDual)
        else:
            self.wallModel.setColorScaleOff()
            self.wallModel.setTransparency(TransparencyAttrib.MNone)

    def toggle_collision_mode(self):
        #Toggle collision mode on and off
        #Shows visual representation of the collisions occuring
        self.collision_mode = not self.collision_mode
        if self.collision_mode == True:
            # Note: Slows the program down considerably
            self.cTrav.showCollisions(render)
        else:
            self.cTrav.hideCollisions()

    def toggle_wireframe(self):
        #toggles wireframe view
        self.wireframe = not self.wireframe
        if self.wireframe:
            self.wallModel.setRenderModeWireframe()
        else:
            self.wallModel.setRenderModeFilled()

##################### RESTART ##################################################
    
    def restart(self):
        #restarts the game
        loading = SplashScreen()
        loading.loading()
        self.reset()

    def reset(self):
        #resets the maze, resets the location of the character

        #removes all notes
        self.wallModel.removeNode()
        self.ballModel.removeNode()

        #resets notes
        self.loadWallModel()
        self.loadBallModel()
        self.createBallColliderModel()
        self.resetCamDist()

        #resets timers
        taskMgr.remove("timerTask")
        self.timer = ""
        self.timerText.destroy()

        self.promptMode()

#################### TIMER #####################################################

    def setTimer(self):
        #code from panda.egg user on Panda3D, 
        #"How to use Timer, a small example maybe?" forum
        #creates a timer
        self.timer = DirectLabel(pos=Vec3(1, 0.85),scale=0.08)

        taskMgr.add(self.timerTask, "timerTask")

    def dCharstr(self, theString):
        #code from panda.egg user on Panda3D, 
        #"How to use Timer, a small example maybe?" forum
        #turns time string into a readable clock string
        if len(theString) != 2:
            theString = '0' + theString
        return theString

    def timerTask(self, task):
        #code from panda.egg user on Panda3D, 
        #"How to use Timer, a small example maybe?" forum
        #task for resetting timer in timer mode
        secondsTime = int(task.time)
        minutesTime = int(secondsTime/60)
        hoursTime = int(minutesTime/60)
        self.timer = (str(hoursTime) + ':' 
                            + self.dCharstr(str(minutesTime%60)) + ':' 
                            + self.dCharstr(str(secondsTime%60)))

        self.updateTimerText()
        
        return Task.cont