Ejemplo n.º 1
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)
Ejemplo n.º 2
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')
Ejemplo n.º 3
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()
Ejemplo n.º 4
0
class Swifter:
    def __init__(self, model, run, walk, idle, jump, crouch, crouchWalk, startPos, scale):
         #(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)
                   
        """
        
        #Define movement map and speeds
        self.speedSprint = 20
        self.speedWalk = 7
        self.speedCrouch = 5
        self.speed = self.speedWalk
        #Capture control status
        self.isMoving = False
        self.isJumping = False
        self.isIdle = False
        self.isCrouching = False
        
        self.movementMap = {"forward":Vec3(0,-self.speed,0), "back":Vec3(0,self.speed,0), \
                            "left":Vec3(self.speed,0,0), "right":Vec3(-self.speed,0,0), \
                            "crouch":0, "sprint":0, "jump":1, "punch":0, "kick":0, "stop":Vec3(0), "changeView":0}
        
        #Set up key state variables
        self.strafe_left = self.movementMap["stop"]
        self.strafe_right = self.movementMap["stop"]
        self.forward = self.movementMap["stop"]
        self.back = self.movementMap["stop"]
        self.jump = False
        self.sprint = False
        self.crouch = False
        
        #Stop player by default
        self.walk = self.movementMap["stop"]
        self.strafe = self.movementMap["stop"]
           
        #Define the actor and his animations
        self.actor = Actor(model,
                           {"run":run,
                            "walk":walk,
                            "idle":idle,
                            "jump":jump,
                            "crouch":crouch,
                            "crouchWalk":crouchWalk})
        
        
        #self.actor.enableBlend()
       
        self.actor.setBlend(frameBlend = True)#Enable interpolation
        self.actor.reparentTo(render)
        self.actor.setScale(scale)
        self.actor.setPos(startPos)
        
        #Set up FSM controller
        self.FSM = ActorFSM(self.actor)
        
        
        
        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
        
        

        # 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('actorRay')
        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 jumpUpdate(self,task):
        # this task simulates gravity and makes the player jump 
        # get the highest Z from the down casting ray
        
        highestZ = -100
        for i in range(self.nodeGroundHandler.getNumEntries()):
            entry = self.nodeGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(self.render).getZ()
            if z > highestZ and entry.getIntoNode().getName() == "Cube":
                highestZ = z
        # gravity effects and jumps
        self.node.setZ(self.node.getZ()+self.jump*globalClock.getDt())
        self.jump -= 1*self.globalClock.getDt()
        if highestZ > self.node.getZ()-.3:
            self.jump = 0
            self.node.setZ(highestZ+.3)
            if self.readyToJump:
                self.jump = 1
        return task.cont    
    """
    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()
 

        #Calculate stateful movement
        
        self.walk = self.forward + self.back
        self.strafe = self.strafe_left + self.strafe_right

        
        # move the character if any of the move controls are activated.
        self.actor.setPos(self.actor,self.walk*globalClock.getDt()*self.speed)
        self.actor.setPos(self.actor,self.strafe*globalClock.getDt()*self.speed)
        
        #If strafing rotate the model -90 / 90 degrees to go in the direction specified
        #if going backwards rotate model 180 degrees

        # If the character is moving, loop the run animation.
        # If he is standing still, stop the animation.
        
        ##CALLL CONTROLLER CLASS AND CALL FSM's INSTEAD OF DOING IT HERE
        
        #Decide what type of movement anim to use
        
        if(self.sprint is True):
            #If we are sprinting..
            self.walkAnim = 'Run'
            self.speed = self.speedSprint
        elif(self.crouch is True): # Can't sprint while crouching ;)
            #If we are crouching..
            print ("Crouching!")
            self.walkAnim = "CrouchWalk"
            self.idleAnim = "Crouch"
            self.speed = self.speedCrouch
        else:
            #Otherwise were walking..
            self.walkAnim = 'Walk'
            self.idleAnim = 'Idle'
            self.speed = self.speedWalk
            
            
        #Idling
        if(self.isJumping is False and self.isMoving is False and self.isIdle is True and self.FSM.state != self.idleAnim):
            #If were not moving and not jumping and were supposed to be idle, play the idle anim if we aren't already
            self.FSM.request(self.idleAnim,1)
            
            #We are idle, feel free to do something else, setting isIdle = False.
            print ("We are Idle but ready to do something: isIdle = False")
            
        elif(self.isJumping is False and self.isMoving is False and self.isIdle is False):
            #If were not moving or jumping, were not  doing anything, we should probably be idle if we aren't already          
            self.isIdle = True

        
        #locomotion           
        #TODO: Separate out into animations for forward, back and side stepping
        if( (self.walk != self.movementMap["stop"] or self.strafe != self.movementMap["stop"]) and self.isJumping is False):
            #Check if actor is walking forward/back
            if(self.walk != self.movementMap["stop"]):
                if(self.isMoving is False or self.FSM.state != self.walkAnim):
                    self.isMoving = True # were now moving
                    self.isIdle = False # were not idle right now 
                    self.FSM.request(self.walkAnim,1)
                    print ("Started running or walking")
            #Check if actor is strafing
            if(self.strafe != self.movementMap["stop"]):
                if(self.isMoving is False or self.FSM.state != self.walkAnim):
                    #MAKE THE NODE ROTATE SO THE LEGS POINT THE DIRECTION MOVING
                    #myLegRotate = actor.controlJoint(None,"modelRoot",)
                    #http://www.panda3d.org/manual/index.php/Controlling_a_Joint_Procedurally
                    self.isMoving = True # were now moving
                    self.isIdle = False # were not idle right now 
                    self.FSM.request(self.walkAnim,1)
                    print ("Started running or walking")    
        elif(self.isMoving is True and self.isIdle is False):
            #Only switch of isMoving if we were moving and not idle
            self.isMoving = False
            print ("Finished walking")
            
                  
            #if were moving, set isMoving = 1 and call walking FSM
        
            
        '''
        Jumping
        
        Check if the user is jumping, if they currently aren't jumping:
        make them not idle and mark them as jumping and request the Jump FSM.
        
        If the jump anim isn't playing but we were jumping, mark actor as not jumping.
        
        '''     
        if(self.jump is True):
            #if user pressed jump and were not already jumping, jump
            if(self.isJumping is False and self.FSM.state != 'Jump'):
                self.isJumping = True # were jumping 
                self.isIdle = False # were not idle right now
                self.FSM.request('Jump',1)
                print ("Started jumping")
        
        #if we are jumping, check the anim has finished and stop jumping
        self.JumpQuery = self.actor.getAnimControl('jump')
        if(self.isJumping is True and self.JumpQuery.isPlaying() is False):
            self.isJumping = False # finished jumping
            print ("Finished Jumping")
        
                

        # 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 setMove(self, key, moveType):
        """ Used by keyboard setup 
            This gets the input from keyBoardSetup and will capture inputs
        """
        if (moveType == "strafe_left"):
            self.strafe_left = self.movementMap[key]
        if (moveType == "strafe_right"):
            self.strafe_right = self.movementMap[key]
        if (moveType == "forward"):
            self.forward = self.movementMap[key]
        if (moveType == "back"):
            self.back = self.movementMap[key]
        if (moveType == "sprint"):
            self.sprint = key
        if (moveType == "jump"):
            self.jump = key
        if (moveType == "crouch"):
            self.crouch = key
Ejemplo n.º 5
0
class MyApp(ShowBase):
    def addTitle(self,text):
        return OnscreenText(text=text, style=1, fg=(1,1,1,1), pos=(0,-0.95), align=TextNode.ACenter, scale = .07)

    def makeStatusLabel(self, i):
        return OnscreenText(style=1, fg=(1,1,0,1), pos=(-1.3 + (i*0.8), -0.95 ), align=TextNode.ALeft, scale = .05, mayChange = 1)

    def __init__(self):
        #base = ShowBase()
        ShowBase.__init__(self)
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))
        self.texto1 = OnscreenText(text="Collect 8 balls and meet Sonic behind the building", style=1, fg=(1,1,1,1), pos=(0,-0.1), align=TextNode.ACenter, scale = .07)
        self.texto2 = OnscreenText(text="Eat bananas for energy and avoid green stones", style=1, fg=(1,1,1,1), pos=(0,-0.2), align=TextNode.ACenter, scale = .07)
        self.texto3 = OnscreenText(text="Arrow keys move the player", style=1, fg=(1,1,1,1), pos=(0,-0.3), align=TextNode.ACenter, scale = .07)
        self.texto4 = OnscreenText(text="a and s help you view the scene", style=1, fg=(1,1,1,1), pos=(0,-0.4), align=TextNode.ACenter, scale = .07)

        
        mySound = base.loader.loadSfx("models/Theme_song.ogg")
        mySound.setLoop(True)
        mySound.play()
		#mySound.setLoop(true)
        self.noOfbanana = self.makeStatusLabel(0)
        self.noOfBalls = self.makeStatusLabel(1)
        self.points = self.makeStatusLabel(2)
            
        self.environ = self.loader.loadModel("models/moonsurface.egg")
        self.environ.reparentTo(self.render)
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, -3)
        self.environ1 = self.loader.loadModel("models/env")
        self.environ1.reparentTo(self.render)
        self.environ1.setScale(50,50,30)
        self.environ1.setPos(0, -170, -3)
        #self.environ1.setHpr(90,0,0)
		
        self.chair1=self.loader.loadModel("models/BeachChair")
        #self.chair1=self.reaparentTo(self.render)
        #self.setScale(1000)
        #self.setPos(25,-160,-3)
        #self.chair1.setHpr(90,0,0)
        self.house1 = self.loader.loadModel("models/houses/church")
        self.house1.reparentTo(self.render)
        self.house1.setScale(0.30)
        self.house1.setPos(25, -150, -3)
        self.house1.setHpr(90,0,0)
        self.house2 = self.loader.loadModel("models/houses/building")
        self.house2.reparentTo(self.render)
        self.house2.setScale(0.30)
        self.house2.setPos(18, -200, -3)
        self.house2.setHpr(180,0,0)
        self.house3 = self.loader.loadModel("models/houses/farmhouse")
        self.house3.reparentTo(self.render)
        self.house3.setScale(0.30)
        self.house3.setPos(20, -130, -3)
        self.house3.setHpr(90,0,0)
        self.house4 = self.loader.loadModel("models/houses/dojo")
        self.house4.reparentTo(self.render)
        self.house4.setScale(0.05)
        self.house4.setPos(5, -220, -3)
        self.house5 = self.loader.loadModel("models/houses/beachhouse2")
        self.house5.reparentTo(self.render)
        self.house5.setScale(0.30)
        self.house5.setPos(-10, -180, -3)
        self.house5.setHpr(-90,0,0)

        self.house6 = self.loader.loadModel("models/houses/gazebo")
        self.house6.reparentTo(self.render)
        self.house6.setScale(0.50)
        self.house6.setPos(-10, -200, -3)
        self.house7 = self.loader.loadModel("models/houses/building")
        self.house7.reparentTo(self.render)
        self.house7.setScale(0.30)
        self.house7.setPos(-10, -120, -3)

        '''  for x in range(0,8):
            self.load4 = loader.loadModel("models/fence")
            self.load4.reparentTo(render)
            self.load4.setScale(.5, .5, 1.3)
            self.load4.setPos(28-x*7,0,1.8)
            cp = self.load4.attachNewNode(CollisionNode('box'))
            cp.node().addSolid(CollisionPolygon(
            Point3(-10.0,0.0,4),Point3(10,0,4),
            Point3(10,-1,-2),Point3(-10,-1,-2))) '''

        self.tunnel = [None for i in range(10)]
    
        for x in range(10):
          #Load a copy of the tunnel
          self.tunnel[x] = loader.loadModel('models/tunnel')
          self.tunnel[x].setHpr(0,90,0)
          self.tunnel[x].setScale(0.5)
          self.tunnel[x].setPos(0,177.5 + 25*x, 0)
          self.tunnel[x].reparentTo(self.render)
##        ###World specific-code
##    
##        #Create an instance of fog called 'distanceFog'.
##        #'distanceFog' is just a name for our fog, not a specific type of fog.
##        self.fog = Fog('distanceFog')
##        #Set the initial color of our fog to black.
##        self.fog.setColor(0, 0, 0)
##        #Set the density/falloff of the fog.  The range is 0-1.
##        #The higher the numer, the "bigger" the fog effect.
##        self.fog.setExpDensity(.08)
##        #We will set fog on render which means that everything in our scene will
##        #be affected by fog. Alternatively, you could only set fog on a specific
##        #object/node and only it and the nodes below it would be affected by
##        #the fog.
##        render.setFog(self.fog)
        self.banana = [None for i in range(20)]
        self.flag = [0 for i in range(20)]
        self.fla = [0 for i in range(5)]
        self.fl = [0 for i in range(8)]
        for x in range(10):
          #Load a copy of the tunnel
          self.banana[x] = loader.loadModel('models/banana/banana')
          #self.banana[x].setHpr(0,90,0)
          self.banana[x].setScale(0.7)
          if(x%2==0):
              self.banana[x].setPos(-1,180 + 25*x, -2)
          else:
              self.banana[x].setPos(1,177.5 + 25*x, -2)
          self.banana[x].reparentTo(self.render)

        self.banana[11] = self.loader.loadModel("models/banana/banana")
        self.banana[11].reparentTo(self.render)
        self.banana[11].setPos(12, 8, -2)
        self.banana[12] = self.loader.loadModel("models/banana/banana")
        self.banana[12].reparentTo(self.render)
        self.banana[12].setPos(0, 120, -2)
        self.banana[13] = self.loader.loadModel("models/banana/banana")
        self.banana[13].reparentTo(self.render)
        self.banana[13].setPos(12, 100, -2)
        self.banana[14] = self.loader.loadModel("models/banana/banana")
        self.banana[14].reparentTo(self.render)
        self.banana[14].setPos(22, 80, -2)
        self.banana[15] = self.loader.loadModel("models/banana/banana")
        self.banana[15].reparentTo(self.render)
        self.banana[15].setPos(12, 50, -2)
        self.banana[16] = self.loader.loadModel("models/banana/banana")
        self.banana[16].reparentTo(self.render)
        self.banana[16].setPos(15, 30, -2)
        self.banana[17] = self.loader.loadModel("models/banana/banana")
        self.banana[17].reparentTo(self.render)
        self.banana[17].setPos(-10, 8, -2)
        self.banana[18] = self.loader.loadModel("models/banana/banana")
        self.banana[18].reparentTo(self.render)
        self.banana[18].setPos(-20, -30, -2)
        self.banana[19] = self.loader.loadModel("models/banana/banana")
        self.banana[19].reparentTo(self.render)
        self.banana[19].setPos(-50, -50, -2)
        
        self.candy = self.loader.loadModel("models/candy/candycane2")
        self.candy.reparentTo(self.render)
        self.candy.setScale(0.001)
        self.candy.setPos(-6, 10, -2)

        self.fire = self.loader.loadModel("models/candy/candycane2")
        self.fire.reparentTo(self.render)
        self.fire.setScale(0.001)
        self.fire.setPos(0, 2, -2)

        self.ball = [None for i in range(8)]
        self.ball[0] = self.loader.loadModel("models/ball/soccerball")
        self.ball[0].reparentTo(self.render)
        self.ball[0].setPos(-6, 6, -2)
        self.ball[0].setScale(0.7)
        self.ball[1] = self.loader.loadModel("models/ball/soccerball")
        self.ball[1].reparentTo(self.render)
        self.ball[1].setPos(-6, -6, -2)
        self.ball[1].setScale(0.7)
        self.ball[2] = self.loader.loadModel("models/ball/soccerball")
        self.ball[2].reparentTo(self.render)
        self.ball[2].setPos(-15, 10, -2)
        self.ball[2].setScale(0.7)
        self.ball[3] = self.loader.loadModel("models/ball/soccerball")
        self.ball[3].reparentTo(self.render)
        self.ball[3].setPos(-19, 0, -2)
        self.ball[3].setScale(0.7)
        self.ball[4] = self.loader.loadModel("models/ball/soccerball")
        self.ball[4].reparentTo(self.render)
        self.ball[4].setPos(-6, -20, -2)
        self.ball[4].setScale(0.7)
        self.ball[5] = self.loader.loadModel("models/ball/soccerball")
        self.ball[5].reparentTo(self.render)
        self.ball[5].setPos(6, 6, -2)
        self.ball[5].setScale(0.7)
        self.ball[6] = self.loader.loadModel("models/ball/soccerball")
        self.ball[6].reparentTo(self.render)
        self.ball[6].setPos(19, 10, -2)
        self.ball[6].setScale(0.7)
        self.ball[7] = self.loader.loadModel("models/ball/soccerball")
        self.ball[7].reparentTo(self.render)
        self.ball[7].setPos(-15, 12, -2)
        self.ball[7].setScale(0.7)

        self.rock = [None for i in range(8)]
        self.rock[0] = self.loader.loadModel("models/greencrystal")
        self.rock[0].reparentTo(self.render)
        self.rock[0].setPos(0,306, -4)
        self.rock[0].setScale(0.007)
        self.rock[0].setHpr(90,0,0)
        self.rock[1] = self.loader.loadModel("models/greencrystal")
        self.rock[1].reparentTo(self.render)
        self.rock[1].setPos(-2, 150, -3)
        self.rock[1].setScale(0.007)
        self.rock[1].setHpr(90,0,0)
        self.rock[2] = self.loader.loadModel("models/greencrystal")
        self.rock[2].reparentTo(self.render)
        self.rock[2].setPos(-10, 10, -3)
        self.rock[2].setScale(0.007)
        self.rock[2].setHpr(90,0,0)
        self.rock[3] = self.loader.loadModel("models/greencrystal")
        self.rock[3].reparentTo(self.render)
        self.rock[3].setPos(5, 0, -3)
        self.rock[3].setScale(0.007)
        self.rock[3].setHpr(90,0,0)
        self.rock[4] = self.loader.loadModel("models/greencrystal")
        self.rock[4].reparentTo(self.render)
        self.rock[4].setPos(-2, -120, -3)
        self.rock[4].setScale(0.007)
        self.rock[4].setHpr(90,0,0)

        self.tire = self.loader.loadModel("models/tire/tire")
        self.tire.reparentTo(self.render)
        self.tire.setScale(0.25, 0.25, 0.25)
        self.tire.setPos(-20, 3, -2)
        
        self.bunny1 = self.loader.loadModel("models/bunny")
        self.bunny1.reparentTo(self.render)
        self.bunny1.setScale(0.2)
        self.bunny1.setPos(15, -160, -3)
        self.bunny1.setHpr(-60,0,0)
        self.bunny2 = self.loader.loadModel("models/bunny")
        self.bunny2.reparentTo(self.render)
        self.bunny2.setScale(0.2)
        self.bunny2.setPos(15, -161, -3)
        self.bunny2.setHpr(-145,0,0)
        # Add the spinCameraTask procedure to the task manager.
        #self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
 
 
        
        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        #self.pandaActor.setPos(0,100,-3)
        self.pandaActor.reparentTo(self.render)
        # Loop its animation.
        self.pandaActor.loop("walk")
 
        # Create the four lerp intervals needed for the panda to
        # walk back and forth.
        pandaPosInterval1 = self.pandaActor.posInterval(20,
                                                        Point3(0, -110, -3),
                                                        startPos=Point3(0, -90, -3))
        pandaPosInterval2 = self.pandaActor.posInterval(20,
                                                        Point3(0, -90, -3),
                                                        startPos=Point3(0, -110, -3))
        pandaHprInterval1 = self.pandaActor.hprInterval(3,
                                                        Point3(180, 0, 0),
                                                        startHpr=Point3(0, 0, 0))
        pandaHprInterval2 = self.pandaActor.hprInterval(3,
                                                        Point3(0, 0, 0),
                                                        startHpr=Point3(180, 0, 0))
 
        # Create and play the sequence that coordinates the intervals.
        self.pandaPace = Sequence(pandaPosInterval1,
                                  pandaHprInterval1,
                                  pandaPosInterval2,
                                  pandaHprInterval2,
                                  name="pandaPace")
        self.pandaPace.loop()
        self.eve = Actor("models/eve",
                                {"walk": "models/eve-walk"})
        self.eve.setScale(0.5, 0.5, 0.5)
        self.eve.setPos(-1,-140,-3)
        self.eve.reparentTo(self.render)
        # Loop its animation.
        self.eve.loop("walk")
 
        # Create the four lerp intervals needed for the panda to
        # walk back and forth.
        evePosInterval1 = self.eve.posInterval(20,
                                                        Point3(-1, -160, -3),
                                                        startPos=Point3(-1, -140, -3))
        evePosInterval2 = self.eve.posInterval(20,
                                                        Point3(-1, -140, -3),
                                                        startPos=Point3(-1, -160, -3))
        eveHprInterval1 = self.eve.hprInterval(3,
                                                        Point3(180, 0, 0),
                                                        startHpr=Point3(0, 0, 0))
        eveHprInterval2 = self.eve.hprInterval(3,
                                                        Point3(0, 0, 0),
                                                        startHpr=Point3(180, 0, 0))
 
        # Create and play the sequence that coordinates the intervals.
        self.evePace = Sequence(evePosInterval1,eveHprInterval1,evePosInterval2,eveHprInterval2,name="evePace")
        self.evePace.loop()
        self.ralph = Actor("models/r/ralph",
                                {"run":"models/ralph-run",
                                 "walk": "models/ralph-walk"})
        self.ralph.setScale(0.5, 0.5, 0.5)
        self.ralph.setPos(0, 420, -3)
        self.ralph.reparentTo(self.render)
        self.boy = Actor("models/soni/sonic",
                                {"anim":"models/soni/sonic-win"})
        self.boy.setScale(0.05, 0.05, 0.05)
        self.boy.setPos(33, -203, -2)
        self.boy.setHpr(-90,0,0)
        self.boy.reparentTo(self.render)
        self.boy.loop("anim")

        self.boy1 = Actor("models/boy/boymodel",
                                {"anim":"models/boy/boyanimation"})
        self.boy1.setScale(0.007)
        self.boy1.setPos(-5, -200, -2)
        self.boy1.setHpr(180,0,0)
        self.boy1.reparentTo(self.render)
        self.boy1.loop("anim")

        self.character=Actor()
        self.character.loadModel('models/dancer')
        self.character.setPos(3,150,-3)
        self.character.reparentTo(render)
        self.character.setHpr(180,0,0)
        self.character.setScale(0.6)
        self.character.loadAnims({'win':'models/dancer'})
        self.character.loop('win')

        self.character1=Actor()
        self.character1.loadModel('models/gorillawalking')
        self.character1.setPos(2,-13,-3)
        self.character1.setScale(0.6)
        self.character1.reparentTo(render)
        self.character1.setHpr(180,0,0)
        self.character1.loadAnims({'win':'models/gorillawalking'})
        self.character1.loop('win')
        
        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        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("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")
        taskMgr.add(self.find,"fisdTask")
        taskMgr.add(self.potask,"potaskTask")
        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,-1)
        #print self.ralph.getX(), self.ralph.getY()

        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(-5, -5, -5))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))
        self.updateStatusLabel()
		
        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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
        
    def potask(self,task):
        global points
        if(self.ralph.getY()<410):
            self.texto1.destroy()
            self.texto2.destroy()
            self.texto3.destroy()
            self.texto4.destroy()
        if(points<0):
            OnscreenText(text="Game Over", style=1, fg=(1,1,1,1), pos=(0,0), align=TextNode.ACenter, scale = 0.4)
            OnscreenText(text="You are out of energy", style=1, fg=(1,1,1,1), pos=(0,-0.20), align=TextNode.ACenter, scale = 0.05)
        return Task.cont
        
        
    def find(self,task):
        global nob, points, noba
        #print self.ralph.getX(),self.ralph.getY()
        if ((self.ralph.getX()>=-3 and self.ralph.getX()<=-1) and (self.ralph.getY()>=145 and self.ralph.getY()<=165) and self.fla[1] == 0):
            self.rock[1].removeNode()
            points= points - 20
            self.fla[1]=1
        elif((self.ralph.getX()>=-11 and self.ralph.getX()<=-9) and (self.ralph.getY()>=9 and self.ralph.getY()<=11) and self.fla[2] == 0):
            self.rock[2].removeNode()
            points= points - 20
            self.fla[2]=1
        elif((self.ralph.getX()>=4 and self.ralph.getX()<=6) and (self.ralph.getY()>=-1 and self.ralph.getY()<=1) and self.fla[3] == 0):
            self.rock[3].removeNode()
            points= points - 20
            self.fla[3]=1
        elif((self.ralph.getX()>=-1 and self.ralph.getX()<=1) and (self.ralph.getY()>=305 and self.ralph.getY()<=307) and self.fla[0] == 0):
            self.rock[0].removeNode()
            points= points - 20
            self.fla[0]=1
        elif((self.ralph.getX()>=-3 and self.ralph.getX()<=-1) and (self.ralph.getY()>=-121 and self.ralph.getY()<=-119) and self.fla[4] == 0):
            self.rock[4].removeNode()
            points= points - 20
            self.fla[4]=1

            
        if ((self.ralph.getX()>=-7.5 and self.ralph.getX()<=-6.5) and (self.ralph.getY()>=-7.5 and self.ralph.getY()<=-6.5) and self.fl[1] == 0):
            self.ball[1].removeNode()
            noba= noba + 1
            self.fl[1]=1
        elif((self.ralph.getX()>=-15.5 and self.ralph.getX()<=-14.5) and (self.ralph.getY()>=9.5 and self.ralph.getY()<=10.5) and self.fl[2] == 0):
            self.ball[2].removeNode()
            noba= noba + 1
            self.fl[2]=1
        elif((self.ralph.getX()>=-19.5 and self.ralph.getX()<=-18.5) and (self.ralph.getY()>=-0.5 and self.ralph.getY()<=0.5) and self.fl[3] == 0):
            self.ball[3].removeNode()
            noba= noba + 1
            self.fl[3]=1
        elif((self.ralph.getX()>=-6.5 and self.ralph.getX()<=-5.5) and (self.ralph.getY()>=5.5 and self.ralph.getY()<=6.5) and self.fl[0] == 0):
            self.ball[0].removeNode()
            noba= noba + 1
            self.fl[0]=1
        elif((self.ralph.getX()>=-6.5 and self.ralph.getX()<=-5.5) and (self.ralph.getY()>=-20.5 and self.ralph.getY()<=-19.5) and self.fl[4] == 0):
            self.ball[4].removeNode()
            noba= noba + 1
            self.fl[4]=1
        elif((self.ralph.getX()>=5.5 and self.ralph.getX()<=6.5) and (self.ralph.getY()>=5.5 and self.ralph.getY()<=6.5) and self.fl[5] == 0):
            self.ball[5].removeNode()
            noba= noba + 1
            self.fl[5]=1
        elif((self.ralph.getX()>=18.5 and self.ralph.getX()<=19.5) and (self.ralph.getY()>=9.5 and self.ralph.getY()<=10.5) and self.fl[6] == 0):
            self.ball[6].removeNode()
            noba= noba + 1
            self.fl[6]=1
        elif((self.ralph.getX()>=-15.5 and self.ralph.getX()<=-14.5) and (self.ralph.getY()>=11.5 and self.ralph.getY()<=12.5) and self.fl[7] == 0):
            self.ball[7].removeNode()
            noba= noba + 1
            self.fl[7]=1
        

        if ((self.ralph.getX()>=11.5 and self.ralph.getX()<=12.5) and (self.ralph.getY()>=7.5 and self.ralph.getY()<=8.5) and self.flag[11]==0):
            self.banana[11].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[11]=1
        elif ((self.ralph.getX()>=0.5 and self.ralph.getX()<=1.5) and (self.ralph.getY()>=404.5 and self.ralph.getY()<=405.5) and self.flag[9]==0):
            self.banana[9].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[9]=1
        elif ((self.ralph.getX()>=0.5 and self.ralph.getX()<=1.5) and (self.ralph.getY()>=354.5 and self.ralph.getY()<=355.5) and self.flag[7]==0):
            self.banana[7].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[7]=1
        elif ((self.ralph.getX()>=0.5 and self.ralph.getX()<=1.5) and (self.ralph.getY()>=304.5 and self.ralph.getY()<=305.5) and self.flag[5]==0):
            self.banana[5].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[5]=1
        elif ((self.ralph.getX()>=0.5 and self.ralph.getX()<=1.5) and (self.ralph.getY()>=254.5 and self.ralph.getY()<=255.5) and self.flag[3]==0):
            self.banana[3].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[3]=1
        elif ((self.ralph.getX()>=0.5 and self.ralph.getX()<=1.5) and (self.ralph.getY()>=204.5 and self.ralph.getY()<=205.5) and self.flag[1]==0):
            self.banana[1].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[1]=1
        elif ((self.ralph.getX()>=-1.5 and self.ralph.getX()<=-0.5) and (self.ralph.getY()>=379.5 and self.ralph.getY()<=380.5) and self.flag[8]==0):
            self.banana[8].removeNode()
            #print 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
            nob= nob + 1
            points= points + 10
            self.flag[8]=1
        elif ((self.ralph.getX()>=-1.5 and self.ralph.getX()<=-0.5) and (self.ralph.getY()>=329.5 and self.ralph.getY()<=330.5) and self.flag[6]==0):
            self.banana[6].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[6]=1
        elif ((self.ralph.getX()>=-1.5 and self.ralph.getX()<=-0.5) and (self.ralph.getY()>=279.5 and self.ralph.getY()<=280.5) and self.flag[4]==0):
            self.banana[4].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[4]=1
        elif ((self.ralph.getX()>=-1.5 and self.ralph.getX()<=-0.5) and (self.ralph.getY()>=229.5 and self.ralph.getY()<=230.5) and self.flag[2]==0):
            self.banana[2].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[2]=1
        elif ((self.ralph.getX()>=-1.5 and self.ralph.getX()<=-0.5) and (self.ralph.getY()>=179.5 and self.ralph.getY()<=180.5) and self.flag[0]==0):
            self.banana[0].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[0]=1
        elif ((self.ralph.getX()>=-0.5 and self.ralph.getX()<=0.5) and (self.ralph.getY()>=119.5 and self.ralph.getY()<=120.5) and self.flag[12]==0):
            self.banana[12].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[12]=1
        elif ((self.ralph.getX()>=11.5 and self.ralph.getX()<=12.5) and (self.ralph.getY()>=99.5 and self.ralph.getY()<=100.5) and self.flag[13]==0):
            self.banana[13].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[13]=1
        elif ((self.ralph.getX()>=21.5 and self.ralph.getX()<=22.5) and (self.ralph.getY()>=79.5 and self.ralph.getY()<=80.5) and self.flag[14]==0):
            self.banana[14].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[14]=1
        elif ((self.ralph.getX()>=11.5 and self.ralph.getX()<=12.5) and (self.ralph.getY()>=49.5 and self.ralph.getY()<=50.5) and self.flag[15]==0):
            self.banana[15].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[15]=1
        elif ((self.ralph.getX()>=14.5 and self.ralph.getX()<=15.5) and (self.ralph.getY()>=29.5 and self.ralph.getY()<=30.5) and self.flag[16]==0):
            self.banana[16].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[16]=1
        elif ((self.ralph.getX()>=-10.5 and self.ralph.getX()<=-9.5) and (self.ralph.getY()>=7.5 and self.ralph.getY()<=8.5) and self.flag[17]==0):
            self.banana[17].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[17]=1
        elif ((self.ralph.getX()>=-20.5 and self.ralph.getX()<=-19.5) and (self.ralph.getY()>=-30.5 and self.ralph.getY()<=-29.5) and self.flag[18]==0):
            self.banana[18].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[18]=1
        elif ((self.ralph.getX()>=-50.5 and self.ralph.getX()<=-49.5) and (self.ralph.getY()>=-50.5 and self.ralph.getY()<=-49.5) and self.flag[19]==0):
            self.banana[19].removeNode()
            nob= nob + 1
            points= points + 10
            self.flag[19]=1
        
        if(self.ralph.getX()>30 and self.ralph.getY()<-200 and noba <8):
            self.boy.loop("anim")
            #self.ralph.removeNode()
            OnscreenText(text="Game Over (n)-Sad!", style=1, fg=(1,1,1,1), pos=(0,0), align=TextNode.ACenter, scale = 0.4)
            OnscreenText(text="You've Failed this City! \nTask not Completed", style=1, fg=(1,1,1,1), pos=(0,-0.20), align=TextNode.ACenter, scale = 0.05)
            OnscreenText(text="This is a Akshay Arun Shubham Production!", style=1, fg=(1,1,1,1), pos=(0,-0.40), align=TextNode.ACenter, scale = 0.05)
        elif(self.ralph.getX()>30 and self.ralph.getY()<-200 and noba ==8):
            #self.ralph.removeNode()
            OnscreenText(text="Game Over", style=1, fg=(1,1,1,1), pos=(0,0), align=TextNode.ACenter, scale = 0.4)
            OnscreenText(text="Congratulations, Task Completed", style=1, fg=(1,1,1,1), pos=(0,-0.20), align=TextNode.ACenter, scale = 0.05)
            OnscreenText(text="This is a Akshay Arun Shubham Production!", style=1, fg=(1,1,1,1), pos=(0,-0.40), align=TextNode.ACenter, scale = 0.05)
        self.updateStatusLabel()  
        return Task.cont
         
 
    

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

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        
        if(self.ralph.getY()<160):
            
            
            # If the camera-left key is pressed, move camera left.
            # If the camera-right key is pressed, move camera right.
            base.camera.lookAt(self.ralph)
            if (self.keyMap["cam-left"]!=0):
                base.camera.setX(base.camera, -20 * globalClock.getDt())
            if (self.keyMap["cam-right"]!=0):
                base.camera.setX(base.camera, +20 * 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() + 300 * globalClock.getDt())
            if (self.keyMap["right"]!=0):
                self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
            if (self.keyMap["forward"]!=0):
                self.ralph.setY(self.ralph, -25 * globalClock.getDt())

            # If ralph is moving, loop the run animation.
            # If he is standing still, stop the animation.

            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
            else:
                if self.isMoving:
                    self.ralph.stop()
                    self.ralph.pose("walk",5)
                    self.isMoving = False
        else:
            # If the camera-left key is pressed, move camera left.
            # If the camera-right key is pressed, move camera right.
            base.camera.lookAt(self.ralph)
            startpos = self.ralph.getPos()

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

            if ((self.keyMap["left"]!=0) and self.ralph.getX()<2.5):
                self.ralph.setH(self.ralph.getH() + 200 * globalClock.getDt())
            if ((self.keyMap["right"]!=0) and self.ralph.getX()>-2.5):
                self.ralph.setH(self.ralph.getH() - 200 * globalClock.getDt())
            if ((self.keyMap["forward"]!=0) and self.ralph.getX()>-3 and self.ralph.getX()<3):
                self.ralph.setY(self.ralph, -25 * globalClock.getDt())
            elif (self.ralph.getX()<-3):
                self.ralph.setX(-2.9)
            elif  (self.ralph.getX()>3):
                self.ralph.setX(2.9)

            # If ralph is moving, loop the run animation.
            # If he is standing still, stop the animation.

            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
            else:
                if self.isMoving:
                    self.ralph.stop()
                    self.ralph.pose("walk",5)
                    self.isMoving = False


        camvec = self.ralph.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
            camdist = 5.0

        return task.cont

    def updateStatusLabel( self ):
        global nob, points
        self.noOfbanana.setText("Bananas Taken: " + str(nob))
        self.points.setText("Energy Meter: " + str(points))
        self.noOfBalls.setText("Balls found: " + str(noba))
class CogdoFlyingCameraManager:
    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

    def enable(self):
        if self._enabled:
            return
        self._toon.detachCamera()
        self._prevToonY = 0.0
        levelBounds = self._level.getBounds()
        l = Globals.Camera.LevelBoundsFactor
        self._bounds = (
            (levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]),
            (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]),
            (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2]),
        )
        self._lookAtZ = self._toon.getHeight() + Globals.Camera.LookAtToonHeightOffset
        self._camParent = NodePath("CamParent")
        self._camParent.reparentTo(self._parent)
        self._camParent.setPos(self._toon, 0, 0, 0)
        self._camParent.setHpr(180, Globals.Camera.Angle, 0)
        self._camera.reparentTo(self._camParent)
        self._camera.setPos(0, Globals.Camera.Distance, 0)
        self._camera.lookAt(self._toon, 0, 0, self._lookAtZ)
        self._cameraLookAtNP = NodePath("CameraLookAt")
        self._cameraLookAtNP.reparentTo(self._camera.getParent())
        self._cameraLookAtNP.setPosHpr(self._camera.getPos(), self._camera.getHpr())
        self._levelBounds = self._level.getBounds()
        self._enabled = True
        self._frozen = False
        self._initCollisions()

    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 _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

    def disable(self):
        if not self._enabled:
            return
        self._destroyCollisions()
        self._camera.wrtReparentTo(render)
        self._cameraLookAtNP.removeNode()
        del self._cameraLookAtNP
        self._camParent.removeNode()
        del self._camParent
        del self._prevToonY
        del self._lookAtZ
        del self._bounds
        del self._frozen
        self._enabled = False

    def update(self, dt=0.0):
        self._updateCam(dt)
        self._updateCollisions()

    def _updateCam(self, dt):
        toonPos = self._toon.getPos()
        camPos = self._camParent.getPos()
        x = camPos[0]
        z = camPos[2]
        toonWorldX = self._toon.getX(render)
        maxX = Globals.Camera.MaxSpinX
        toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX)
        spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (maxX * maxX)
        newH = 180.0 + spinAngle
        self._camParent.setH(newH)
        spinAngle = spinAngle * (pi / 180.0)
        distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle)
        distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle)
        d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0])
        if abs(d) > Globals.Camera.LeewayX:
            if d > Globals.Camera.LeewayX:
                x = toonPos[0] + Globals.Camera.LeewayX
            else:
                x = toonPos[0] - Globals.Camera.LeewayX
        x = self._toon.getX(render) + distToRightOfToon
        boundToonZ = min(toonPos[2], self._bounds[2][1])
        d = z - boundToonZ
        if d > Globals.Camera.MinLeewayZ:
            if self._player.velocity[2] >= 0 and toonPos[1] != self._prevToonY or self._player.velocity[2] > 0:
                z = boundToonZ + d * INVERSE_E ** (dt * Globals.Camera.CatchUpRateZ)
            elif d > Globals.Camera.MaxLeewayZ:
                z = boundToonZ + Globals.Camera.MaxLeewayZ
        elif d < -Globals.Camera.MinLeewayZ:
            z = boundToonZ - Globals.Camera.MinLeewayZ
        if self._frozen:
            y = camPos[1]
        else:
            y = self._toon.getY(render) - distBehindToon
        self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z))
        if toonPos[2] < self._bounds[2][1]:
            h = self._cameraLookAtNP.getH()
            if d >= Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ)
            elif d <= -Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._camParent, 0, 0, self._lookAtZ)
            self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0)
            self._camera.setHpr(smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr()))
        self._prevToonY = toonPos[1]

    def _updateCollisions(self):
        pos = self._toon.getPos(self._camera) + self._collOffset
        self._camCollRay.setOrigin(pos)
        direction = -Vec3(pos)
        direction.normalize()
        self._camCollRay.setDirection(direction)
        self._collTrav.traverse(render)
        nodesInBetween = {}
        if self._collHandler.getNumEntries() > 0:
            self._collHandler.sortEntries()
            for entry in self._collHandler.getEntries():
                name = entry.getIntoNode().getName()
                if name.find("col_") >= 0:
                    np = entry.getIntoNodePath().getParent()
                    if not nodesInBetween.has_key(np):
                        nodesInBetween[np] = np.getParent()

        for np in nodesInBetween.keys():
            if self._betweenCamAndToon.has_key(np):
                del self._betweenCamAndToon[np]
            else:
                np.setTransparency(True)
                np.wrtReparentTo(self._transNP)
                if np.getName().find("lightFixture") >= 0:
                    if not np.find("**/*floor_mesh").isEmpty():
                        np.find("**/*floor_mesh").hide()
                elif np.getName().find("platform") >= 0:
                    if not np.find("**/*Floor").isEmpty():
                        np.find("**/*Floor").hide()

        for np, parent in self._betweenCamAndToon.items():
            np.wrtReparentTo(parent)
            np.setTransparency(False)
            if np.getName().find("lightFixture") >= 0:
                if not np.find("**/*floor_mesh").isEmpty():
                    np.find("**/*floor_mesh").show()
            elif np.getName().find("platform") >= 0:
                if not np.find("**/*Floor").isEmpty():
                    np.find("**/*Floor").show()

        self._betweenCamAndToon = nodesInBetween
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
class World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "shoot":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions
        self.inst6 = addInstructions(0.95, "Mad Max's Revenge!")
        self.inst1 = addInstructions(0.90, "[ESC]: Quit")
        self.inst2 = addInstructions(0.85, "[a]: Left Turn")
        self.inst3 = addInstructions(0.80, "[d]: Right Turn")
        self.inst4 = addInstructions(0.75, "[w]: Drive Forward")
        self.inst4 = addInstructions(0.70, "[s]: Reverse")
        self.inst5 = addInstructions(0.65, "[mouse]: Fire Rocket")
        
        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.  

        self.environ = loader.loadModel("Assets/Models/env")    #models/environment  
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        self.sky = loader.loadModel("Assets/Models/sky")    #models/environment  
        self.sky.reparentTo(render)
        self.sky.setPos(0,0,0)
        
        # Create the main character, player

        playerStartPos = Point3(8,14,1) #self.environ.find("**/start_point").getPos()
        enemyStartPos = Point3(-7,-8,1) #self.environ.find("**/start_point").getPos()
        #~ print enemyStartPos
        enemyStartPos.addX(1.0)
        enemyStartPos.addY(1.0)
        #~ print enemyStartPos

        
        self.player = Actor("Assets/Models/player_model", {"drive":"Assets/Models/player_drive", "fire":"Assets/Models/player_turret", "drivefire":"Assets/Models/player_both"})
        self.player.reparentTo(render)
        self.player.setScale(0.1)
        self.player.setPos(playerStartPos)
        #~ self.playerdrive=self.player.actorInterval("drive")
        #~ self.playerfire=self.player.actoraaaaaaaInterval("fire")
        #~ self.playerdrivefire=self.player.actorInterval("drivefire")
        
        # Create the enemy, Enemy
        self.enemy = Actor("Assets/Models/enemy_model", {"drive":"Assets/Models/enemy_drive", "fire":"Assets/Models/enemy_turret", "drivefire":"Assets/Models/enemy_both"})
        self.enemy.reparentTo(render)
        self.enemy.setScale(0.1)
        tex = loader.loadTexture("Assets/Models/cartexture1.png")
        self.enemy.setTexture(tex, 1)
        self.enemy.setPos(enemyStartPos)
        self.enemyrockettiming = globalClock.getFrameTime()
        #print self.enemy.getCurrentAnim()

        #print self.enemy.getCurrentAnim()
        #~ self.enemydrive=self.enemy.actorInterval("drive")
        #~ self.enemyfire=self.enemy.actorInterval("fire")
        #~ self.enemydrivefire=self.enemy.actorInterval("drivefire")
        
        self.music = loader.loadMusic("Assets/Sound/music.mp3")
        SoundInterval(self.music).loop()

        audio3d.attachSoundToObject(EnemyRunning, self.enemy)
        audio3d.attachSoundToObject(EnemyIdling, self.enemy)

        backward = self.enemy.getNetTransform().getMat().getRow3(1)
        backward.setZ(0)
        backward.normalize()
        #self.enemy.setPos(self.enemy.getPos() - backward*(50))

        #Set up the lighting
        self.playerleftlight=self.player.attachNewNode(Spotlight("playerheadleft"))
        self.playerleftlight.node().setColor(Vec4(0.75, 0.75, 0.75, 1))
        self.playerleftlight.node().setLens( PerspectiveLens() )
        self.playerleftlight.node().getLens().setFov( 50, 50)
        self.playerleftlight.node().setAttenuation( Vec3( 0.1, 0.005, 0.0 ) )
        self.playerleftlight.node().setExponent( 60.0 )
        self.playerleftlight.setPos(-1, -0.1, 1.5)
        self.playerleftlight.setHpr(180, -10, 0)
        render.setLight(self.playerleftlight)
        
        self.playerrightlight=self.player.attachNewNode(Spotlight("playerheadright"))
        self.playerrightlight.node().setColor(Vec4(0.75, 0.75, 0.75, 1))
        self.playerrightlight.node().setLens( PerspectiveLens() )
        self.playerrightlight.node().getLens().setFov( 50, 50)
        self.playerrightlight.node().setAttenuation( Vec3( 0.1, 0.005, 0.0 ) )
        self.playerrightlight.node().setExponent( 60.0 )
        self.playerrightlight.setPos(1, -0.1, 1.5)
        self.playerrightlight.setHpr(180, -10, 0)
        render.setLight(self.playerrightlight)

        self.playerlightson=1

        self.enemyleftlight=self.enemy.attachNewNode(Spotlight("enemyheadleft"))
        self.enemyleftlight.node().setColor(Vec4(0.75, 0.75, 0.75, 1))
        self.enemyleftlight.node().setLens( PerspectiveLens() )
        self.enemyleftlight.node().getLens().setFov( 50, 50)
        self.enemyleftlight.node().setAttenuation( Vec3( 0.1, 0.005, 0.0 ) )
        self.enemyleftlight.node().setExponent( 60.0 )
        self.enemyleftlight.setPos(-1, -0.1, 1.5)
        self.enemyleftlight.setHpr(180, -10, 0)
        render.setLight(self.enemyleftlight)
        
        self.enemyrightlight=self.enemy.attachNewNode(Spotlight("enemyheadright"))
        self.enemyrightlight.node().setColor(Vec4(0.75, 0.75, 0.75, 1))
        self.enemyrightlight.node().setLens( PerspectiveLens() )
        self.enemyrightlight.node().getLens().setFov( 50, 50)
        self.enemyrightlight.node().setAttenuation( Vec3( 0.1, 0.005, 0.0 ) )
        self.enemyrightlight.node().setExponent( 60.0 )
        self.enemyrightlight.setPos(1, -0.1, 1.5)
        self.enemyrightlight.setHpr(180, -10, 0)
        render.setLight(self.enemyrightlight)
        
        self.enemylightson=1
        
        self.spotlight=camera.attachNewNode(PointLight("spotlight"))
        #self.spotlight.setPos(0, 3, 0.5)
        #self.spotlight.setHpr(0, 0, 0)
        self.spotlight.node().setColor(Vec4(1, 1, 1, 1))
        #self.spotlight.node().setLens( PerspectiveLens() )
        #self.spotlight.node().getLens().setFov( 180, 120)
        self.spotlight.node().setAttenuation( Vec3( 1, 0, 0.05 ))
        #self.spotlight.node().setExponent( 60.0 )
        render.setLight(self.spotlight)
        
        self.playerlight=self.player.attachNewNode(PointLight("spotlight"))
        self.playerlight.node().setColor(Vec4(1, 1, 1, 1))
        #self.spotlight.node().setLens( PerspectiveLens() )
        #self.spotlight.node().getLens().setFov( 180, 120)
        self.playerlight.node().setAttenuation( Vec3( 1, 0, 0.05 ))
        #self.spotlight.node().setExponent( 60.0 )
        render.setLight(self.playerlight)
        
        
        self.ambientlight=self.sky.attachNewNode(AmbientLight("ambientLight"))
        self.ambientlight.node().setColor(Vec4(1, 1, 1, 1))
        self.sky.setLight(self.ambientlight)

        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("a", self.setKey, ["left",1])
        self.accept("d", self.setKey, ["right",1])
        self.accept("w", self.setKey, ["forward",1])
        self.accept("s", self.setKey, ["backward",1])
        self.accept("a-up", self.setKey, ["left",0])
        self.accept("d-up", self.setKey, ["right",0])
        self.accept("w-up", self.setKey, ["forward",0])
        self.accept("s-up", self.setKey, ["backward",0])
        self.accept("l", self.playerLights,[])
        
        self.accept("mouse1", self.setKey, ["shoot", 1])
        self.accept("mouse1-up", self.setKey, ["shoot", 0]) #self.shootRocketshootRocket

        taskMgr.add(self.playerMove,"moveTask")
        taskMgr.add(self.enemyMove,"moveTask")
        taskMgr.add(self.shoot,"shootTask")
        taskMgr.add(self.rocketCollision,"rocketCollision")

        # Game state variables
        self.prevtime = 0
        self.isMoving = False
        self.prevShotTime = 0
        self.prevEnemyMoveTime = 0

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.player.getX(),self.player.getY()+10,2)
        
        # 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 player'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.playerGroundRay = CollisionRay()
        self.playerGroundRay.setOrigin(0,0,1000)
        self.playerGroundRay.setDirection(0,0,-1)
        self.playerGroundCol = CollisionNode('playerRay')
        self.playerGroundCol.addSolid(self.playerGroundRay)
        self.playerGroundCol.setFromCollideMask(BitMask32.bit(3))
        self.playerGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.playerGroundColNp = self.player.attachNewNode(self.playerGroundCol)
        self.playerGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.playerGroundColNp, self.playerGroundHandler)

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

        # Uncomment this line to see the collision rays
        #self.playerGroundColNp.show()
        #self.camGroundColNp.show()
       
        #Uncomment this line to show a visual representation of the 
        #collisions occuring
        #self.cTrav.showCollisions(render)
        
        #Code for Enemy player
        self.enemyGroundRay = CollisionRay()
        self.enemyGroundRay.setOrigin(0,0,1000)
        self.enemyGroundRay.setDirection(0,0,-1)
        self.enemyGroundCol = CollisionNode('enemyRay')
        self.enemyGroundCol.addSolid(self.enemyGroundRay)
        self.enemyGroundCol.setFromCollideMask(BitMask32.bit(3))
        self.enemyGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.enemyGroundColNp = self.enemy.attachNewNode(self.enemyGroundCol)
        self.enemyGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.enemyGroundColNp, self.enemyGroundHandler)
        
        self.cRocketHandler = CollisionHandlerQueue()
        
        self.worldEdge = CollisionInvSphere(0, 0, 0, 50)
        
        cNode = CollisionNode("worldEdge")
        cNode.addSolid(self.worldEdge)
        cNode.setFromCollideMask(BitMask32.allOff())
        cNode.setIntoCollideMask(BitMask32.allOn())
        self.worldEdgeNp=self.environ.attachNewNode(cNode)
        #self.cTrav.addCollider(self.worldEdgeNp, self.cRocketHandler)
        #cNP = render.attachNewNode(cNode)
        
        cNode2 = CollisionNode("wall")
        cNode2.addSolid(CollisionPlane(Plane(Vec3(-1,0,0), Point3(22.5,0,0))))
        cNode2.addSolid(CollisionPlane(Plane(Vec3(1,0,0), Point3(-22.5,0,0))))
        cNode2.addSolid(CollisionPlane(Plane(Vec3(0,-1,0), Point3(0,22.5,0))))
        cNode2.addSolid(CollisionPlane(Plane(Vec3(0,1,0), Point3(0,-22.5,0))))
        cNode2.setFromCollideMask(BitMask32.allOff())
        cNode2.setIntoCollideMask(BitMask32.allOn())
        cNP2=self.environ.attachNewNode(cNode2)
        
        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.allOn())
        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.playerrocket = None
        self.enemyrocket = None
        
        self.enemyTurn = 0
        self.enemyDestAng = 180

        
        self.enemyHp = 3
        self.playerHp = 3
        
        #Collisions
        self.setupCollisions()
        
        self.playermoving = False
        
        
        #setup hud
        self.drawHud()
        
    def drawHud(self):
        
        #Player
        OnscreenText(text="Player Health", style=1, fg=(1,1,1,1), pos=(0.85, 0.9), align=TextNode.ALeft, scale = .08)
        
        self.playerHealthImg = OnscreenImage(image = 'Assets/Images/healthFull.png', pos = (1.05, 0, .84), scale = .12)
        self.playerHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        
        
        #Enemy
        OnscreenText(text="Enemy Health", style=1, fg=(1,1,1,1), pos=(0.85, 0.7), align=TextNode.ALeft, scale = .08)
        
        self.enemyHealthImg = OnscreenImage(image = 'Assets/Images/healthFull.png', pos = (1.05, 0, .64), scale = .12)
        self.enemyHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        

    def updateGui(self):
    
        #player bar
        if self.playerHp == 2:
            self.playerHealthImg.setImage('Assets/Images/healthMedium.png')
            self.playerHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        elif self.playerHp == 1:
            self.playerHealthImg.setImage('Assets/Images/healthLow.png')
            self.playerHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        
        #enemy bar
        if self.enemyHp == 2:
            self.enemyHealthImg.setImage('Assets/Images/healthMedium.png')
            self.enemyHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        elif self.enemyHp == 1:
            self.enemyHealthImg.setImage('Assets/Images/healthLow.png')
            self.enemyHealthImg.setTransparency(TransparencyAttrib.MAlpha)
        


    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)
        #self.cTrav.addCollider(cEnemyNP, self.cRocketHandler)
        #cEnemyNP.show()
        

    def rocketCollision(self, task):
        """Check for rocket collisions with players and objects"""
        
        toRemove = []
        
        for i in range(self.cRocketHandler.getNumEntries()):
            entry = self.cRocketHandler.getEntry(i)
            #~ print entry		
            
            if entry.getFromNode().getName() == "PlayerRocket" and entry.getIntoNode().getName() == "Enemy":
                self.enemyHp -= 1
                self.updateGui()
                if self.enemyHp == 0:
                    print "Victory!"
                    OnscreenText(text="Victory!", style=2, fg=(0,1,0,1),
                    pos=(-0.6, 0), align=TextNode.ALeft, scale = .5, shadow=(0,0,0,0))
                    self.playerHp += 5
		    #LerpFunc(end_game, fromData = 0, toData = 1, duration = 3.0,
			#blendType = 'noBlend', extraArgs = [], name = None)
                    taskMgr.remove("moveTask")
                    taskMgr.remove("shootTask")
                    #print "GAME OVER, YOU WIN"
                    #sys.exit(0) 
            elif entry.getFromNode().getName() == "EnemyRocket" and entry.getIntoNode().getName() == "Player":
                self.playerHp -= 1
                self.updateGui()
                if self.playerHp == 0:
                    #~ print "GAME OVER, YOU LOSE"
                    OnscreenText(text="Failure!", style=2, fg=(1,0,0,1),
                    pos=(-0.6, 0), align=TextNode.ALeft, scale = .5, shadow=(0,0,0,0))
                    self.enemyHp += 5
                    taskMgr.remove("moveTask")
                    taskMgr.remove("shootTask")
            
            #Add to remove list
            if entry.getFromNodePath() not in toRemove:
                toRemove.append(entry.getFromNodePath())

        #remove
        for np in toRemove:
        
            if np.getNode(0).getName() == "PlayerRocket":
                if self.playerrocket:
                    self.playerrocket.kill_light()
                    #~ print "BOOM!, PLAYER ROCKET EXPLODED"
                    BoomSound.play()
                    RocketFire.stop()
                    Explosion.Explosion(self.playerrocket.rocket.getPos(), render)
                    self.playerrocket = None
                np.getParent().remove()
            
            else:
                if self.enemyrocket:
                    self.enemyrocket.kill_light()
                    #~ print "BOOM!, ENEMY ROCKET EXPLODED"
                    BoomSound.play()
                    RocketFire.stop()
                    Explosion.Explosion(self.enemyrocket.rocket.getPos(), render)
                    self.enemyrocket = None
                np.getParent().remove()
            
        self.cRocketHandler.clearEntries()
        
        return Task.cont
    
    def shootPlayerRocket(self):
        """Shoot a player rocket"""
        
        #Check to see if we can access the mouse. We need it to do anything else
        if base.mouseWatcherNode.hasMouse():
            #get the mouse position
            mpos = base.mouseWatcherNode.getMouse()
          
            #Set the position of the ray based on the mouse position
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            #Do the actual collision pass
            pickerpoint=Point3(0,0,0)
            self.picker.traverse(render)

            for i in range(self.pq.getNumEntries()):
                entry = self.pq.getEntry(i)
                if entry.getFromNode().getName() == "mouseRay" and entry.getIntoNode().getName()=="terrain":
                    pickerpoint=entry.getSurfacePoint(render)
            direction=pickerpoint-Point3(self.player.getX(), self.player.getY(), self.player.getZ()+0.5)
            #~ if self.playerrocket is None:
                #~ angle = math.radians(self.player.getH())
            playerpos=self.player.getPos()
            self.playerrocket = Rocket.Rocket(Point3(playerpos.getX(), playerpos.getY(), playerpos.getZ()+0.5), direction, "PlayerRocket", render)
            self.playerrocket.setupCollision(self.cTrav, self.cRocketHandler)
            RocketFire.play()
            
            if self.player.getCurrentAnim()=="drive":
                self.player.play("drivefire")
            else:
                self.player.play("fire")
            
    def shootEnemyRocket(self):
        """Shoot a enemy rocket"""
   
        if not (self.enemyrocket) and self.enemyrockettiming <= globalClock.getFrameTime() :
            #~ angle = math.radians(self.enemy.getH())
            #~ self.enemyrocket = Rocket.Rocket(self.enemy.getPos(), angle, "EnemyRocket", render)
            #~ self.enemyrocket.setupCollision(self.cTrav, self.cRocketHandler)
            direction = self.player.getPos() - self.enemy.getPos()
            enemyPos = self.enemy.getPos()
            self.enemyrocket = Rocket.Rocket(enemyPos + Point3(0,0,.5),direction,"EnemyRocket",render)
            self.enemyrocket.setupCollision(self.cTrav, self.cRocketHandler)
            RocketFire.play()
            self.enemy.play("drivefire")
            self.enemyrockettiming = globalClock.getFrameTime() + 2.0
        
    
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    
    def shoot(self, task):
        elapsed = task.time - self.prevShotTime
        if(self.keyMap["shoot"]!=0 and elapsed > 1):
            self.shootPlayerRocket()
            self.prevShotTime = task.time
            
        return Task.cont
    
    def playerLights(self):
        if self.playerlightson:
            self.playerleftlight.node().setColor(Vec4(0,0,0,1))
            self.playerrightlight.node().setColor(Vec4(0,0,0,1))
            self.playerlightson=0
        else:
            self.playerleftlight.node().setColor(Vec4(0.75,0.75,0.75,1))
            self.playerrightlight.node().setColor(Vec4(0.75,0.75,0.75,1))
            self.playerlightson=1
    def enemyLights(self):
        if self.enemylightson:
            self.enemyleftlight.node().setColor(Vec4(0,0,0,1))
            self.enemyrightlight.node().setColor(Vec4(0,0,0,1))
            self.enemylightson=0
        else:
            self.enemyleftlight.node().setColor(Vec4(0.75,0.75,0.75,1))
            self.enemyrightlight.node().setColor(Vec4(0.75,0.75,0.75,1))
            self.enemylightson=1
        
    def enemyMove(self, task):
        elapsed = task.time - self.prevEnemyMoveTime

        startpos = self.enemy.getPos()
        
        #Calculate distance to the enemy
        distvec = self.player.getPos() - self.enemy.getPos()
        distvec.setZ(0)
        dist = distvec.length()
        
        backward = self.enemy.getNetTransform().getMat().getRow3(1)
        backward.setZ(0)
        backward.normalize()
        
        #Drive!
        if self.enemy.getCurrentAnim() is None:
            self.enemy.loop("drive")
            
        #Find the vector from the enemy to the player, then find the angle of that vector
        vec = self.enemy.getPos() - self.player.getPos()
        angle = math.degrees(math.atan2(vec.getX(), vec.getY()))

        #Find the angle left to turn according to the enemy's current angle
        angleToPlayer = (-self.enemy.getH() - angle) % 360
        
        #Fire rocket if within 60 degree arc of player
        #~ print angleToPlayer
        if angleToPlayer < 30 or angleToPlayer > 330:
            self.shootEnemyRocket()
        
        #AI control code starts here
        
        #enemyTurn is zero for heading straight, -1 to turn full left, +1 to turn full right
        #Turning rate is currently maxed at 100 degrees per second
        #drivedir is for forward (1) or backward (-1)
        #Wall avoidance stuff
        enemyTurn=0
        myh=self.player.getH()%360
        print myh
        if abs(self.enemy.getPos().getX())>19 or abs(self.enemy.getPos().getX())>19:
            drivedir=-1.0
        else:
            drivedir=1.0
        if self.playerrocket:
            playerpos=self.player.getPos()
            if playerpos.getX()>12.5 and (myh<90 or myh>270):
                self.enemyTurn = -(0.5+0.05*(self.enemy.getX()-12.5))*sign(myh-180)
                print 1
            elif playerpos.getX()<12.5 and not (myh<90 or myh>270):
                self.enemyTurn = -(0.5+0.05*(12.5-self.enemy.getX()))*sign(myh-180)
                print 2
            elif playerpos.getY()>12.5 and myh<180:
                self.enemyTurn = -(0.5+0.05*(self.enemy.getY()-12.5))*sign(myh-90)
                print 3
            elif playerpos.getY()<12.5 and myh>180:
                self.enemyTurn = -(0.5+0.05*(12.5-self.enemy.getY()))*sign(myh-270)
                print 4
        elif self.enemy.getPos().getX()>12.5 and (myh<90 or myh>270):
            self.enemyTurn = -(0.5+0.05*(self.enemy.getX()-12.5))*sign(myh-180)
            print 5
        elif self.enemy.getPos().getX()<-12.5 and not (myh<90 or myh>270):
            self.enemyTurn = -(0.5+0.05*(12.5-self.enemy.getX()))*sign(myh-180)
            print 6
        elif self.enemy.getPos().getY()>12.5 and myh<180:
            self.enemyTurn = -(0.5+0.05*(self.enemy.getY()-12.5))*sign(myh-90)
            print 7
        elif self.enemy.getPos().getY()<-12.5 and myh>180:
            self.enemyTurn = -(0.5+0.05*(12.5-self.enemy.getY()))*sign(myh-270)
            print 8
        elif not(math.fabs(self.enemyDestAng - angleToPlayer) > 3 and math.fabs(self.enemyDestAng - angleToPlayer) < 357):
            print 9
            self.enemyTurn = 0
        else:
            print 10
            if dist > 5:
                self.enemyDestAng = 0
                if angleToPlayer  > 1  and angleToPlayer <= 180:
                    #Turn left
                    self.enemyTurn = -0.5
                elif angleToPlayer > 180 and angleToPlayer < 359:
                    #Turn right
                    self.enemyTurn = 0.5
                
            elif dist < 5:
                self.enemyDestAng = 180
                if angleToPlayer  >= 0  and angleToPlayer < 179:
                    #Turn left
                    self.enemyTurn = 0.5
                elif angleToPlayer > 181 and angleToPlayer < 360:
                    #Turn right
                    self.enemyTurn = -0.5
        #Replace later
        #drivedir=1.0
        
        #End of AI code
        
        #Enemy always tries to move forward, regardless of where the player is
        self.enemy.setPos(self.enemy.getPos() - backward*(drivedir*elapsed*5))
        self.enemy.setH(self.enemy.getH() - elapsed *100.0*self.enemyTurn)
        EnemyRunning.play()
        
        
        self.cTrav.traverse(render)
        
        entries = []
        terrain = []
        for i in range(self.enemyGroundHandler.getNumEntries()):
            entry = self.enemyGroundHandler.getEntry(i)
            if entry.getFromNode().getName() == "enemyRay":
                terrain.append(entry)
            elif entry.getFromNode().getName() == "Enemy" and entry.getIntoNode().getName() != "terrain":
                entries.append(entry)
        terrain.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))

        if (len(entries)>0):
            self.enemy.setPos(startpos)
        if (len(terrain)>0) and (terrain[0].getIntoNode().getName() == "terrain"):
            self.enemy.setZ(terrain[0].getSurfacePoint(render).getZ()+.5)
        else:
            self.enemy.setPos(startpos)
            
        # Store the task time and continue.
        self.prevEnemyMoveTime = task.time
        return Task.cont

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def playerMove(self, task):
        
        elapsed = task.time - self.prevtime
        
        base.camera.lookAt(self.player)
        camright = base.camera.getNetTransform().getMat().getRow3(0)
        camright.normalize()
            

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

        startpos = self.player.getPos()
        
        
        # If a move-key is pressed, move player in the specified direction.

        if ((self.keyMap["left"]!=0) & (self.keyMap["forward"]!=0)):
            self.player.setH(self.player.getH() + elapsed*50)
            Idling.stop()
            Running.play()
            self.playermoving = True
        elif((self.keyMap["left"]!=0) & (self.keyMap["backward"]!=0)):
            self.player.setH(self.player.getH() - elapsed*50)
            Idling.stop()
            Running.play()
            self.playermoving = True
        if ((self.keyMap["right"]!=0) & (self.keyMap["forward"]!=0)):
            self.player.setH(self.player.getH() - elapsed*50)
            Idling.stop()
            Running.play()
            self.playermoving = True
        elif ((self.keyMap["right"]!=0) & (self.keyMap["backward"]!=0)):
            self.player.setH(self.player.getH() + elapsed*50)
            Idling.stop()
            Running.play()
            self.playermoving = True
        if (self.keyMap["forward"]!=0):
            backward = self.player.getNetTransform().getMat().getRow3(1)
            backward.setZ(0)
            backward.normalize()
            self.player.setPos(self.player.getPos() - backward*(elapsed*5))
            Running.play()
            Idling.stop()
            self.playermoving = True
        if (self.keyMap["backward"]!=0):
            backward = self.player.getNetTransform().getMat().getRow3(1)
            backward.setZ(0)
            backward.normalize()
            self.player.setPos(self.player.getPos() + backward*(elapsed*5))
            Idling.stop()
            Running.play()
            self.playermoving = True
        if (self.keyMap["backward"]==0 and self.keyMap["forward"]==0 and self.keyMap["left"]==0 and self.keyMap["right"]==0):
            Running.stop()
            Idling.play() 
            self.playermoving = False
            if self.player.getCurrentAnim()=="drive":
                self.player.stop()
                #print "STOP MOVING"
                
        
        #DRIVE!
        if self.player.getCurrentAnim() is None and self.playermoving:
            self.player.loop("drive")
            #print "DRIVE ON!"

            
        dist = 10.0
        angle = math.radians(self.player.getH()) + math.pi
        dx = dist * math.sin(angle)
        dy = dist * -math.cos(angle)
        dest = Point3(self.player.getX() + dx, self.player.getY() + dy, self.player.getZ()+1)
        base.camera.setPos(dest)

        # If player is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                #self.player.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                #self.player.stop()
                #self.player.pose("walk",5)
                self.isMoving = False

        # If the camera is too far from player, move it closer.
        # If the camera is too close to player, move it farther.
        
        camvec = self.player.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 20.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-20))
            camdist = 20.0
        if (camdist < 10.0):
            base.camera.setPos(base.camera.getPos() - camvec*(10-camdist))
            camdist = 10.0

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Adjust player's Z coordinate.  If player'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.
        
        terrain = []
        entries = []
        for i in range(self.playerGroundHandler.getNumEntries()):
            entry = self.playerGroundHandler.getEntry(i)
            if entry.getFromNode().getName() == "playerRay":
                terrain.append(entry)
            elif entry.getFromNode().getName() == "Player" and entry.getIntoNode().getName() != "terrain":
                entries.append(entry)
        terrain.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))     
        
        if (len(entries)>0):
            self.player.setPos(startpos)
        elif (len(terrain)>0) and (terrain[0].getIntoNode().getName() == "terrain"):
            self.player.setZ(terrain[0].getSurfacePoint(render).getZ()+.5)
        else:
            self.player.setPos(startpos)
            
        # Keep the camera at one foot above the terrain,
        # or two feet above player, whichever is greater.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.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"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+ 1.5)
        if (base.camera.getZ() < self.player.getZ() + 2.5):
            base.camera.setZ(self.player.getZ() + 2.5)
            
        # The camera should look in player's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above player's head.
        
        self.floater.setPos(self.player.getPos())
        self.floater.setZ(self.floater.getZ()+1)
        base.camera.lookAt(self.floater)

        # Store the task time and continue.
        self.prevtime = task.time
        
        return Task.cont
Ejemplo n.º 9
0
class Camera: 
    
    """A floating 3rd person camera that follows an actor around, and can be 
    turned left or right around the actor. 

    Public fields: 
    self.controlMap -- The camera's movement controls. 
    actor -- The Actor object that the camera will follow. 
    
    Public functions: 
    init(actor) -- Initialise the camera. 
    move(task) -- Move the camera each frame, following the assigned actor. 
                  This task is called every frame to update the camera. 
    setControl -- Set the camera's turn left or turn right control on or off. 
    
    """ 

    def __init__(self,actor): 
        """Initialise the camera, setting it to follow 'actor'. 
        
        Arguments: 
        actor -- The Actor that the camera will initially follow. 
        
        """ 
        
        self.actor = actor 
        self.prevtime = 0 

        # The camera's controls: 
        # "left" = move the camera left, 0 = off, 1 = on 
        # "right" = move the camera right, 0 = off, 1 = on 
        self.controlMap = {"left":0, "right":0} 

        taskMgr.add(self.move,"cameraMoveTask") 

        # Create a "floater" object. It is used to orient the camera above the 
        # target actor's head. 
        
        self.floater = NodePath(PandaNode("floater")) 
        self.floater.reparentTo(render)        

        # Set up the camera. 

        base.disableMouse() 
        base.camera.setPos(self.actor.getX(),self.actor.getY()+2, 2)
        # uncomment for topdown
        #base.camera.setPos(self.actor.getX(),self.actor.getY()+10,2) 
        #base.camera.setHpr(180, -50, 0)
        
        # A CollisionRay beginning above the camera and going down toward the 
        # ground is used to detect camera collisions and the height of the 
        # camera above the ground. A ray may hit the terrain, or it may hit a 
        # rock or a tree.  If it hits the terrain, we detect the camera's 
        # height.  If it hits anything else, the camera is in an illegal 
        # position. 

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

        # Uncomment this line to see the collision rays 
        #self.groundColNp.show() 
      
    def move(self,task): 
        """Update the camera's position before rendering the next frame. 
        
        This is a task function and is called each frame by Panda3D. The 
        camera follows self.actor, and tries to remain above the actor and 
        above the ground (whichever is highest) while looking at a point 
        slightly above the actor's head. 
        
        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. 
        
        """ 

        # FIXME: There is a bug with the camera -- if the actor runs up a 
        # hill and then down again, the camera's Z position follows the actor 
        # up the hill but does not come down again when the actor goes down 
        # the hill. 

        elapsed = task.time - self.prevtime 

        # If the camera-left key is pressed, move camera left. 
        # If the camera-right key is pressed, move camera right. 
        
        # comment out for topdown  
        base.camera.lookAt(self.actor) 
        
        camright = base.camera.getNetTransform().getMat().getRow3(0) 
        camright.normalize() 
        if (self.controlMap["left"]!=0): 
            base.camera.setPos(base.camera.getPos() - camright*(elapsed*20)) 
        if (self.controlMap["right"]!=0): 
            base.camera.setPos(base.camera.getPos() + camright*(elapsed*20)) 

        # If the camera is too far from the actor, move it closer. 
        # If the camera is too close to the actor, move it farther.

        camvec = self.actor.getPos() - base.camera.getPos() 
        camvec.setZ(0) 
        camdist = camvec.length() 
        camvec.normalize() 
        if (camdist > 10.0): 
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) 
            camdist = 10.0 
        if (camdist < 5.0): 
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) 
            camdist = 5.0 

        # Now check for collisions. 

        self.cTrav.traverse(render) 

        # Keep the camera at one foot above the terrain, 
        # or two feet above the actor, whichever is greater. 
        # comment out for topdown
        
        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"): 
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) 
        if (base.camera.getZ() < self.actor.getZ() + 2.0): 
            base.camera.setZ(self.actor.getZ() + 2.0) 
            
        # The camera should look in the player's direction, 
        # but it should also try to stay horizontal, so look at 
        # a floater which hovers above the player's head. 
        
        self.floater.setPos(self.actor.getPos()) 
        self.floater.setZ(self.actor.getZ() + 2.0)
        
        #self.floater.setZ(self.actor.getZ() + 10.0) 
        #self.floater.setY(self.actor.getY() + 7.0)
        
        # comment out for topdown
        base.camera.lookAt(self.floater) 
        
        base.camera.setPos(self.floater.getPos())
        
        # 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 camera'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 
Ejemplo n.º 10
0
class Unit(Actor):
	gravity = 30
	
	def __init__(self, models = None, anims = None, sphereString = "**/CollisionSphere", game = None, xStart = 0, yStart = 0, zStart = 0, radius = 3):
		Actor.__init__(self, models, anims)
		
		self.game = game
		
		self.health = 10
		self.heightOffset = 3
		
		#set up the position
		self.setPos(xStart, yStart, zStart)
		self.prevPosition = self.getPos()
		#self.lastPosition = Point3()
		self.vel = Vec3()
		self.accel = Vec3(0, 0, -Unit.gravity)
		#define the position that will be treated as the center of the map
		self.wCenter = Point3(0, 0, 0)
		
		#the radius of the sphere around this
		self.radius = 3.5
		
		#the base damage this unit deals upon collision
		self.collisionAttackPower = 2.5
		
		#set up Panda's collisions
		#first the pusher
		
		cSphere = CollisionSphere((0, 0, 1), 2)
		cNode = CollisionNode("unit")
		cNode.addSolid(cSphere)
		cNode.setIntoCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS))
		cNode.setFromCollideMask(BitMask32(PLAYER_ENEMY_OBJECTS))
		self.collisionNodePath = self.attachNewNode(cNode)
		#self.collisionNodePath.show()
		
		#set pattern for event sent on collision
		# "%in" is substituted with the name of the into object, "%fn" is substituted with the name of the from object
		#do the collision pusher
		self.collisionPusher = CollisionHandlerPusher()
		self.collisionPusher.addCollider(self.collisionNodePath, self)
		self.collisionPusher.addInPattern("%fn-into-%in")
		self.collisionPusher.addOutPattern("fn-out-%in")
		game.cTrav.addCollider(self.collisionNodePath, self.collisionPusher)
		
		#check for colllisions with the ground
		self.groundRay = CollisionRay()
		self.groundRay.setOrigin(0, 0, 4000)
		self.groundRay.setDirection(0, 0, -1)
		self.groundCol = CollisionNode('unitRay')
		self.groundCol.addSolid(self.groundRay)
		self.groundCol.setFromCollideMask(BitMask32(TERRAIN_RAY_MASK))
		self.groundCol.setIntoCollideMask(BitMask32.allOff())
		self.groundColNode = self.attachNewNode(self.groundCol)
		self.groundHandler = CollisionHandlerQueue()
		game.cTrav.addCollider(self.groundColNode, self.groundHandler)
		
		#can be thought of as the inverse of the unit's mass
		self.accelMultiplier = 45
		self.friction = 1.7
		self.disableFriction = False
		
		self.nodePath = None
		self.shootable = True
		
		#finally set the python tag
		self.setPythonTag("unit", self)
	
	def applyForceFrom(self, magnitude, sourcePosition):
		forceVector = self.getPos() - sourcePosition
		forceVector.normalize()
		forceVector *= magnitude
		
		self.applyForce(forceVector)
	
	def applyForce(self, forceVector):
		self.accel += forceVector * self.accelMultiplier
	
	def applyConstantVelocityFrom(self, magnitude, sourcePosition):
		velVector = self.getPos() - sourcePosition
		velVector.normalize()
		velVector *= magnitude
		
		self.applyConstantVelocity(velVector)
	
	def applyConstantVelocity(self, velVector):
		self.vel = velVector

	def takeDamage(self, num):
		self.health -= num
		
		if self.health <= 0:
			self.die()
	
	def die(self):
		self.game.actors[self.getName()] = None
		self.delete()
	
	def turn(self, magnitude):
		pass
	
	def update(self, time):
		self.vel += self.accel * time
		self.accel.set(0, 0, -Unit.gravity)
		
		if not self.disableFriction:
			self.vel -= self.vel * (self.friction * time)
		
		self.setFluidPos(self.getPos() + self.vel * time)
		self.setZ(max(-100, self.getZ()))
	
	def collideWithUnit(self, other):
		velDiff = self.vel - other.vel
		
		if velDiff.lengthSquared() > 450:
			Unit.takeDamage(self, other.collisionAttackPower)
			Unit.takeDamage(other, self.collisionAttackPower)
		
		self.vel *= 0.8
		other.vel *= 0.8
	
	def collideWithObstacle(self):
		if self.vel.lengthSquared() > 500:
			Unit.takeDamage(self, max(1, self.collisionAttackPower))
		self.vel *= 0.5
	
	def terrainCollisionCheck(self):
		entries = []
		length = self.groundHandler.getNumEntries()
		for i in range(length):
			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):
			for entry in entries:
				if entry.getIntoNode().getName() == "craterCollisionPlane":
					zVal = entry.getSurfacePoint(render).getZ()
					if zVal >= MAX_HEIGHT:#apply a force toward the center
						self.applyForce(self.wCenter - Point3((self.getX() * GROUND_REPULSION_MULTIPLIER), (self.getY() * GROUND_REPULSION_MULTIPLIER), 0))
						'''
						this is a little bit hackish, what is done is that a force in the x and y direction is created proportional to your distance from the origin.  this will only 
						work effectively if the crater is xy centered in the environment
						'''
					else:
						self.setZ(max(zVal, self.getZ()))
					break
Ejemplo n.º 11
0
class BallPlateWorld(WorldBase):
    
  def __init__(self, controller, log_2_memory, display_categories):    
    WorldBase.__init__(self, controller, log_2_memory, display_categories)
    self.display_categories = display_categories
    self.last_time = time.time()
    self.step = 0
    self.__init_kepler_scene()
    
      
    
  
  def set_3d_scene(self, x,y,z, alpha, beta, dt):
    new_position = Point3(x,y,z)
    self.maze.setP(-self.alpha)
    self.maze.setR(-self.beta)
    self.ballRoot.setPos(new_position)

    #This block of code rotates the ball. It uses a quaternion
    #to rotate the ball around an arbitrary axis. That axis perpendicular to
    #the balls rotation, and the amount has to do with the size of the ball
    #This is multiplied on the previous rotation to incrimentally turn it.
    prevRot = LRotationf(self.ball.getQuat())
    axis = UP.cross(self.ballV)
    newRot = LRotationf(axis, 45.5 * dt * self.ballV.length())
    self.ball.setQuat(prevRot * newRot)

 
  def __init_kepler_scene(self):
    self.hud_count_down = 0
    self.alpha = 0.
    self.beta = 0.  
    self._set_title("Hugomatic 3D sim")
    self.alpha_rot_speed = 0.
    self.beta_rot_speed = 0.
    
    #This code puts the standard title and instruction text on screen
    self.title = OnscreenText(text="Kepler simulation tool 1",
                              style=1, fg=(1,1,1,1),
                              pos=(0.7,-0.95), scale = .07, font = font)
    
    self.instructions = OnscreenText(text="alpha: 0.000\nbeta: 0.000",
                                     pos = (-1.3, .95), fg=(1,1,1,1), font = font,
                                     align = TextNode.ALeft, scale = .05)
    
    if DISABLE_MOUSE:
        base.disableMouse()                    #Disable mouse-based camera control
    camera.setPosHpr(-10, -10, 25, 0, -90, 0)  #Place the camera

    #Load the maze and place it in the scene
    self.maze = loader.loadModel("models/maze")
    process_model(self.maze)
    self.maze.reparentTo(render)

    #Most times, you want collisions to be tested against invisible geometry
    #rather than every polygon. This is because testing against every polygon
    #in the scene is usually too slow. You can have simplified or approximate
    #geometry for the solids and still get good results.
    #
    #Sometimes you'll want to create and position your own collision solids in
    #code, but it's often easier to have them built automatically. This can be
    #done by adding special tags into an egg file. Check maze.egg and ball.egg
    #and look for lines starting with <Collide>. The part is brackets tells
    #Panda exactly what to do. Polyset means to use the polygons in that group
    #as solids, while Sphere tells panda to make a collision sphere around them
    #Keep means to keep the polygons in the group as visable geometry (good
    #for the ball, not for the triggers), and descend means to make sure that
    #the settings are applied to any subgroups.
    #
    #Once we have the collision tags in the models, we can get to them using
    #NodePath's find command

    #Find the collision node named wall_collide
    self.walls = self.maze.find("**/wall_collide")

    #Collision objects are sorted using BitMasks. BitMasks are ordinary numbers
    #with extra methods for working with them as binary bits. Every collision
    #solid has both a from mask and an into mask. Before Panda tests two
    #objects, it checks to make sure that the from and into collision masks
    #have at least one bit in common. That way things that shouldn't interact
    #won't. Normal model nodes have collision masks as well. By default they
    #are set to bit 20. If you want to collide against actual visible polygons,
    #set a from collide mask to include bit 20
    #
    #For this example, we will make everything we want the ball to collide with
    #include bit 0
    self.walls.node().setIntoCollideMask(BitMask32.bit(0))
    #CollisionNodes are usually invisible but can be shown. Uncomment the next
    #line to see the collision walls
    if VISIBLE_WALLS:
        self.walls.show()

    #Ground_collide is a single polygon on the same plane as the ground in the
    #maze. We will use a ray to collide with it so that we will know exactly
    #what height to put the ball at every frame. Since this is not something
    #that we want the ball itself to collide with, it has a different
    #bitmask.
    self.mazeGround = self.maze.find("**/ground_collide")
    self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1))
    
    #Load the ball and attach it to the scene
    #It is on a root dummy node so that we can rotate the ball itself without
    #rotating the ray that will be attached to it
    self.ballRoot = render.attachNewNode("ballRoot")
    self.ball = loader.loadModel("models/ball")
    self.ball.reparentTo(self.ballRoot)

    #Find the collison sphere for the ball which was created in the egg file
    #Notice that it has a from collision mask of bit 0, and an into collison
    #mask of no bits. This means that the ball can only cause collisions, not
    #be collided into
    self.ballSphere = self.ball.find("**/ball")
    self.ballSphere.node().setFromCollideMask(BitMask32.bit(0))
    self.ballSphere.node().setIntoCollideMask(BitMask32.allOff())

    #No we create a ray to start above the ball and cast down. This is to
    #Determine the height the ball should be at and the angle the floor is
    #tilting. We could have used the sphere around the ball itself, but it
    #would not be as reliable
    self.ballGroundRay = CollisionRay()     #Create the ray
    self.ballGroundRay.setOrigin(0,0,10)    #Set its origin
    self.ballGroundRay.setDirection(0,0,-1) #And its direction
    #Collision solids go in CollisionNode
    self.ballGroundCol = CollisionNode('groundRay') #Create and name the node
    self.ballGroundCol.addSolid(self.ballGroundRay) #Add the ray
    self.ballGroundCol.setFromCollideMask(BitMask32.bit(1)) #Set its bitmasks
    self.ballGroundCol.setIntoCollideMask(BitMask32.allOff())
    #Attach the node to the ballRoot so that the ray is relative to the ball
    #(it will always be 10 feet over the ball and point down)
    self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol)
    #Uncomment this line to see the ray
    self.ballGroundColNp.show()

    #Finally, we create a CollisionTraverser. CollisionTraversers are what
    #do the job of calculating collisions
    self.cTrav = CollisionTraverser()
    #Collision traverservs tell collision handlers about collisions, and then
    #the handler decides what to do with the information. We are using a
    #CollisionHandlerQueue, which simply creates a list of all of the
    #collisions in a given pass. There are more sophisticated handlers like
    #one that sends events and another that tries to keep collided objects
    #apart, but the results are often better with a simple queue
    self.cHandler = CollisionHandlerQueue()
    #Now we add the collision nodes that can create a collision to the
    #traverser. The traverser will compare these to all others nodes in the
    #scene. There is a limit of 32 CollisionNodes per traverser
    #We add the collider, and the handler to use as a pair
    self.cTrav.addCollider(self.ballSphere, self.cHandler)
    self.cTrav.addCollider(self.ballGroundColNp, self.cHandler)

    #Collision traversers have a built in tool to help visualize collisions.
    #Uncomment the next line to see it.
    if VISIBLE_WALLS:
        self.cTrav.showCollisions(render)
    
    #This section deals with lighting for the ball. Only the ball was lit
    #because the maze has static lighting pregenerated by the modeler
    lAttrib = LightAttrib.makeAllOff()
    ambientLight = AmbientLight( "ambientLight" )
    ambientLight.setColor( Vec4(.55, .55, .55, 1) )
    lAttrib = lAttrib.addLight( ambientLight )
    directionalLight = DirectionalLight( "directionalLight" )
    directionalLight.setDirection( Vec3( 0, 0, -1 ) )
    directionalLight.setColor( Vec4( 0.375, 0.375, 0.375, 1 ) )
    directionalLight.setSpecularColor(Vec4(1,1,1,1))
    lAttrib = lAttrib.addLight( directionalLight )
    self.ballRoot.node().setAttrib( lAttrib )
    
    #This section deals with adding a specular highlight to the ball to make
    #it look shiny
    m = Material()
    m.setSpecular(Vec4(1,1,1,1))
    m.setShininess(96)
    self.ball.setMaterial(m, 1)

    #Finally, we call start for more initialization
    # self.start()
  
      
    #def start(self):
    #The maze model also has a locator in it for where to start the ball
    #To access it we use the find command
    startPos = (0,0,0)#= self.maze.find("**/start").getPos()
    self.ballRoot.setPos(startPos)   #Set the ball in the starting position
    self.ballV = Vec3(0,0,0)         #Initial velocity is 0
    self.accelV = Vec3(0,0,0)        #Initial acceleration is 0
    
    #For a traverser to actually do collisions, you need to call
    #traverser.traverse() on a part of the scene. Fortunatly, base has a
    #task that does this for the entire scene once a frame. This sets up our
    #traverser as the one to be called automatically
    base.cTrav = self.cTrav

  #This function handles the collision between the ray and the ground
  #Information about the interaction is passed in colEntry
  def groundCollideHandler(self, colEntry):
    #Set the ball to the appropriate Z value for it to be exactly on the ground
    newZ = colEntry.getSurfacePoint(render).getZ()
    self.ballRoot.setZ(newZ + .4)

    #Find the acceleration direction. First the surface normal is crossed with
    #the up vector to get a vector perpendicular to the slope
    norm = colEntry.getSurfaceNormal(render)
    accelSide = norm.cross(UP)
    #Then that vector is crossed with the surface normal to get a vector that
    #points down the slope. By getting the acceleration in 3D like this rather
    #than in 2D, we reduce the amount of error per-frame, reducing jitter
    self.accelV = norm.cross(accelSide)

  #This function handles the collision between the ball and a wall
  def wallCollideHandler(self, colEntry):
    #First we calculate some numbers we need to do a reflection
    norm = colEntry.getSurfaceNormal(render) * -1 #The normal of the wall
    curSpeed = self.ballV.length()                #The current speed
    inVec = self.ballV / curSpeed                 #The direction of travel
    velAngle = norm.dot(inVec)                    #Angle of incidance
    hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
    hitDir.normalize()                            
    hitAngle = norm.dot(hitDir)   #The angle between the ball and the normal

    #Ignore the collision if the ball is either moving away from the wall
    #already (so that we don't accidentally send it back into the wall)
    #and ignore it if the collision isn't dead-on (to avoid getting caught on
    #corners)
    if velAngle > 0 and hitAngle > .995:
      #Standard reflection equation
      reflectVec = (norm * norm.dot(inVec * -1) * 2) + inVec
        
      #This makes the velocity half of what it was if the hit was dead-on
      #and nearly exactly what it was if this is a glancing blow
      self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))
      #Since we have a collision, the ball is already a little bit buried in
      #the wall. This calculates a vector needed to move it so that it is
      #exactly touching the wall
      disp = (colEntry.getSurfacePoint(render) -
              colEntry.getInteriorPoint(render))
      newPos = self.ballRoot.getPos() + disp
      self.ballRoot.setPos(newPos)

  def update_hud(self):
    self.hud_count_down -= 1
    if self.hud_count_down <= 0:
        self.hud_count_down = 5
        p1, p2 = self.get_ball_position()
        text =  "\nalpha: %.5f\nbeta: %.5f\npos [%.05f,%.05f]\n" % (self.alpha, self.beta, p1,p2)
        self.instructions.setText(text) 
    
  def control_task(self,task):
        delta_time = task.time - self.last_time
        self.last_time = task.time
        self.step += 1
        if self.controller:
            self.controller.loop(self.step, task.time, delta_time)     

        if self.logging:
            data = self.controller.get_display_data()
            self.log.snapshot(get_data_logger(), self.step, task.time, data, ('self'))        
 
  def get_table_inclination(self):
      angle1 = math.radians(self.alpha)
      angle2 = math.radians(self.beta)
      return (angle1, angle2)
  
  def set_table_rotation_speed(self, alpha_rot_speed, beta_rot_speed):
      self.alpha_rot_speed = alpha_rot_speed
      self.beta_rot_speed = beta_rot_speed
  
  def get_ball_position(self):
      p = self.ballRoot.getPos()
      p1 = p[0]
      p2 = p[1]
      #print "ball position [%s, %s]" % (p1, p2)
      return (p1, p2)
Ejemplo n.º 12
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)))
Ejemplo n.º 13
0
class Camera:
    def __init__(self,actor):

        self.actor = actor
        self.prevtime = 0
        self.controlMap = {"left":0, "right":0}

        taskMgr.add(self.move,"cameraMoveTask")
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        base.disableMouse()
        #base.camera.setPos(self.actor.getX(),self.actor.getY()+10,2)
        base.camera.setPos(self.actor.getX()-30,self.actor.getY()-10,self.actor.getZ()+7)
        camera.setHpr(-60,0,0)

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

        self.groundColNp.show()

    def move(self,task):
        elapsed = task.time - self.prevtime

        base.camera.lookAt(self.actor)
        camright = base.camera.getNetTransform().getMat().getRow3(0)
        camright.normalize()
        if (self.controlMap["left"]!=0):
            base.camera.setPos(base.camera.getPos() - camright*(elapsed*50))
        if (self.controlMap["right"]!=0):
            base.camera.setPos(base.camera.getPos() + camright*(elapsed*50))


        camvec = self.actor.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        #print(camdist)
        camvec.normalize()
        if (camdist > 30.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-30))
            camdist = 30.0
        if (camdist < 15.0):
            base.camera.setPos(base.camera.getPos() - camvec*(15-camdist))
            camdist = 15.0

        self.cTrav.traverse(render)

        entries = []
        for i in range(self.groundHandler.getNumEntries()):
            entry = self.groundHandler.getEntry(i)
            entries.append(entry)
            #print(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"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+4.0)
        if (base.camera.getZ() < self.actor.getZ() + 8.0):
            base.camera.setZ(self.actor.getZ() + 8.0)

        self.floater.setPos(self.actor.getPos())
        self.floater.setZ(self.actor.getZ() + 8.0)

        base.camera.lookAt(self.floater)
        #print("camer1" ,camera.getHpr())
        self.prevtime = task.time
        return Task.cont

    def setControl(self, control, value):

        self.controlMap[control] = value
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
class Myclass(ShowBase):
    """docstring for Myclass"""
    def __init__(self):
        ShowBase.__init__(self)

        self.playerGUI = gameGUI()
        self.numObjects = 200;
        self.again = 0
        
        self.setBackgroundColor(.6, .6, 1)
        self.evrn = self.loader.loadModel(MYDIR+"/world/world")
        self.evrn.reparentTo(self.render)
        self.evrn.setScale(3)
        self.evrn.setPos(0,0,0)
        self.evrn.setCollideMask(BitMask32.bit(1))
        
        self.sky = self.loader.loadModel(MYDIR+"/alice-skies--happysky/happysky")
        self.sky.reparentTo(self.render)
        self.sky.setScale(3)
        self.sky.setPos(-10,-50,5)   

        self.house = self.loader.loadModel(MYDIR+"/dojo/dojo")
        self.house.reparentTo(self.evrn)
        self.house.setScale(0.032)
        self.house.setPos(30,30,4)
        self.house.setHpr(90,0,0)

        self.house.setCollideMask(BitMask32.bit(1))
        self.rect = CollisionSphere(0,0,0,300)
        self.rectnode = CollisionNode('houserect')
        self.rectnode.addSolid(self.rect)
        self.rectnode.setCollideMask(BitMask32.bit(1))
        self.houserectad = self.house.attachNewNode(self.rectnode)
        #self.houserectad.show()

        self.placeCollectibles()
        self.loadMenu()
        self.loadcharacter()
        
       
        
    def loadcharacter(self):

        self.ralphstartpos = Point3(-350,-150,9)
        self.player = Character(MYDIR+"/ralph/ralph",MYDIR+"/ralph/ralph-run",MYDIR+"/ralph/ralph-walk",self.ralphstartpos, 1.2,1,self.playerGUI)
        ralph = self.player.getactor()

        self.accept("j", self.player.setControl, ["left",1])
        self.accept("l",  self.player.setControl, ["right",1])
        self.accept("i",  self.player.setControl, ["forward",1])
        self.accept("j-up",  self.player.setControl, ["left",0])
        self.accept("l-up", self.player.setControl, ["right",0])
        self.accept("i-up", self.player.setControl, ["forward",0])

        camera = Camera(self.player.actor)

        self.accept("a-up", camera.setControl, ["left",0])
        self.accept("s-up", camera.setControl, ["right",0])
        self.accept("a", camera.setControl, ["left",1])
        self.accept("s", camera.setControl, ["right",1])
        
        self.dino = Agent(MYDIR+"/trex/trex",MYDIR+"/trex/trex-run",MYDIR+"/trex/trex-run",(-350,120,3),1.2,2,ralph,self.playerGUI)

        

    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 placeItem(self, item):
        # Add ground collision detector to the health item
        self.cTrav1 = CollisionTraverser()

        self.collectGroundRay = CollisionRay()
        self.collectGroundRay.setOrigin(0,0,300)
        self.collectGroundRay.setDirection(0,0,-1)
        self.collectGroundCol = CollisionNode('colRay')
        self.collectGroundCol.addSolid(self.collectGroundRay)
        self.collectGroundCol.setFromCollideMask(BitMask32.bit(1))
        self.collectGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.collectGroundColNp = item.attachNewNode(self.collectGroundCol)
        self.collectGroundHandler = CollisionHandlerQueue()
        base.cTrav1.addCollider(self.collectGroundColNp, self.collectGroundHandler)
        
        placed = False;
        while placed == False:
            # re-randomize position
            item.setPos(-random.randint(-350,300),-random.randint(-100,150),0)
            
            base.cTrav1.traverse(render)
            
            # Get Z position from terrain collision
            entries = []
            for j in range(self.collectGroundHandler.getNumEntries()):
                entry = self.collectGroundHandler.getEntry(j)
                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"):
                item.setZ(entries[0].getSurfacePoint(render).getZ()+4)
                placed = True
                
        # remove placement collider
        #self.collectGroundColNp.removeNode()

    def start(self):
        self.playerGUI.runralph = 1
        self.playerGUI.setgamepausevalue(1)
        taskMgr.add(self.movement, "Movement")
        self.playerGUI.playend()
        self.playerGUI.initTimer()


        #Start music
        #soundMgr.playBG()

    def movement(self,task):
        '''
        taskMgr.add(self.finishGame, "Finish Game")
        Task.again
        '''
        global finishme
        if self.playerGUI.runralph == 1 and finishme == 0:
            return Task.again
        else:
            self.player.getactor().stop()
            self.dino.getactor().stop()
            taskMgr.doMethodLater(2, self.finishGame, "Finish Game")
            return Task.done
        


    def loadMenu(self):
        #Load main menu
        #Add play icon
        click = loader.loadSfx("./sounds/correct.ogg")
        self.playicon = DirectButton(image="./GUI/cloud.png", scale=.3, pos=(-0.38,0,0.21), relief=None, state=DGG.NORMAL, command=self.playGame, clickSound=click)
        self.playicon.setScale(0.3)
        self.playicon.setTransparency(TransparencyAttrib.MAlpha)

        #Play text
        play = TextNode('Play')
        play.setText("\1menu\1 Play! \2")
        self.playNP = aspect2d.attachNewNode(play)
        self.playNP.setScale(0.18)
        self.playNP.setPos(-0.7,0,0.13)

        self.playerGUI.controls()

        #Exit text and icon
        self.exiticon = DirectButton(image="./GUI/cloud.png", scale=.3, pos=(0.48,0,0.21), relief=None, state=DGG.NORMAL, command=exit, clickSound=click)
        self.exiticon.setScale(0.3)
        self.exiticon.setTransparency(TransparencyAttrib.MAlpha)
        exitx = TextNode('Exit')
        exitx.setText("\1menu\1 Exit \2")
        self.exitxNP = aspect2d.attachNewNode(exitx)
        self.exitxNP.setScale(0.18)
        self.exitxNP.setPos(0.22,0,0.13)

    def playGame(self):
        #Unload menu
        
        self.playicon.destroy()
        self.exiticon.destroy()
        self.playNP.removeNode()
        self.exitxNP.removeNode()
        self.playerGUI.controlsleftNP.removeNode()
        self.playerGUI.controlsrightNP.removeNode()
        self.playerGUI.controlsforwardNP.removeNode()
        self.playerGUI.controlscameraaNP.removeNode()
        self.playerGUI.controlscamerasNP.removeNode()
        self.playerGUI.instructions1NP.removeNode()

        if self.again:
            self.playerGUI.reset()
            #self.restartgame()
            self.player.getactor().cleanup()
            self.player.getactor().removeNode()
            self.dino.getactor().cleanup()
            self.dino.getactor().removeNode()

            self.loadcharacter()
            
        #Start game
        self.countdw = 3
        taskMgr.doMethodLater(1, self.countDown, "Count Down")

    def restartgame(self):
        self.numObjects = 200;
        self.player.getactor().setPos(self.ralphstartpos)
        self.dino.getactor().setPos(-350,120,3)
        self.time = 0
        base.camera.setPos(self.player.getactor().getX()-30,self.player.getactor().getY()-10,self.player.getactor().getZ()+7)
        camera.setHpr(-60,0,0)
        #self.placeHealthItems()
        self.placeCollectibles()
        #taskMgr.add(self.move,"moveTask")
        #taskMgr.doMethodLater(0.5, self.healthDec, "healthTask")

    
    def finishGame(self, task):
        global finishme
        #if finishme == 0 and self.playerGUI.runralph == 1:
         # Task.cont
        #check if finish global is 1 toh continue else return task.cont
        #Check if there's a new record
        if self.playerGUI.points > self.playerGUI.record:
            self.playerGUI.setRecord(self.playerGUI.points)
        #else:
            #soundMgr.playSnd("./sounds/opening.ogg",1,False)
        self.again = 1
        self.playerGUI.setgamepausevalue(0)

        #self.player.getactor().stop()
        #self.dino.getactor().stop()

        taskMgr.remove("moveTask")
        taskMgr.remove("AIUpdate")
        taskMgr.remove("cameraMoveTask")
        #taskMgr.remove("TicTac")
        finishme = 0
        self.playerGUI.picked = 0
        self.loadMenu()

    def countDown(self, task):
        #Start countdown
        if self.countdw >= -1:
           if self.countdw == 0:
               self.start()
           self.playerGUI.setCount(self.countdw)
           self.countdw -= 1
           return Task.again
        else:
            return Task.done
Ejemplo n.º 16
0
class ObjectGravitySimulator:
	"""
	"""
	falling_velocity = 10.0  # Z units per second
	
	def __init__(self, attach_object, object_bottom_buffer_distance = 0.1):
		#print "creating ObjectGravitySimulator for " + attach_object.name + ".\n"
		self.attach_object = attach_object
		self.object_bottom_buffer_distance = object_bottom_buffer_distance
		self.initialize_collision_handling()
	
	def initialize_collision_handling(self):
		self.collision_handling_mutex = Lock()
		
		self.cTrav = CollisionTraverser()
		
		self.groundRay = CollisionRay()
		self.groundRay.setOrigin(0,0,1000)
		self.groundRay.setDirection(0,0,-1)
		self.groundCol = CollisionNode(self.attach_object.name + "_collision_node")
		self.groundCol.setIntoCollideMask(BitMask32.bit(0))
		self.groundCol.setFromCollideMask(BitMask32.bit(0))
		self.groundCol.addSolid(self.groundRay)
		self.groundColNp = self.attach_object.render_model.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 destroy_collision_handling(self):
		self.collision_handling_mutex.acquire()
    
	def handle_collisions(self, seconds):
		self.collision_handling_mutex.acquire()
		self.groundCol.setIntoCollideMask(BitMask32.bit(0))
		self.groundCol.setFromCollideMask(BitMask32.bit(1))
		
		# Now check for collisions.
		self.cTrav.traverse(render)
		
		# Adjust the object's Z coordinate.  If the object's ray hit anything,
		# update its Z.
		
		current_z = self.attach_object.render_model.getZ() - self.object_bottom_buffer_distance
		entries = []
		for i in range(self.groundHandler.getNumEntries()):
			entry = self.groundHandler.getEntry(i)
			if (entry.getSurfacePoint(render).getZ() - 0.001 < current_z):
				entries.append(entry)

		entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
					     x.getSurfacePoint(render).getZ()))
		if (len(entries)>0):
			surface_z = entries[0].getSurfacePoint(render).getZ()
			#print "> " + self.attach_object.name + " is falling toward " + entries[0].getIntoNode().getName() + "\n"
			new_z = current_z - (self.falling_velocity * seconds)
			if (new_z < surface_z):
				new_z = surface_z
			if ((new_z > current_z + 0.00001) or (new_z < current_z - 0.00001)):
				self.attach_object.render_model.setZ(new_z + self.object_bottom_buffer_distance)
		
		self.groundCol.setIntoCollideMask(BitMask32.bit(0))
		self.groundCol.setFromCollideMask(BitMask32.bit(0))
		self.collision_handling_mutex.release()


	def step_simulation_time(self, seconds):
		#print "stepping object."
		self.handle_collisions(seconds)
Ejemplo n.º 17
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, agent_simulator, model, actions, startPos, scale):
        """Initialize 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.agent_simulator = agent_simulator
	
        self.controlMap = {"turn_left":0, "turn_right":0, "move_forward":0, "move_backward":0,\
                           "look_up":0, "look_down":0, "look_left":0, "look_right":0}

        self.actor = Actor(model,actions)
        self.actor.reparentTo(render)
        self.actor.setScale(scale)
        self.actor.setPos(startPos)
        
        self.actor.setHpr(0,0,0)
    

        # Expose agent's right hand joint to attach objects to 
        self.actor_right_hand = self.actor.exposeJoint(None, 'modelRoot', 'RightHand')
        self.actor_left_hand  = self.actor.exposeJoint(None, 'modelRoot', 'LeftHand')
        
        self.right_hand_holding_object = False
        self.left_hand_holding_object  = False

        # speech bubble
        self.last_spoke = 0
        self.speech_bubble=DirectLabel(parent=self.actor, text="", text_wordwrap=10, pad=(3,3), relief=None, text_scale=(.5,.5), pos = (0,0,6), frameColor=(.6,.2,.1,.5), textMayChange=1, text_frame=(0,0,0,1), text_bg=(1,1,1,1))
        self.speech_bubble.component('text0').textNode.setCardDecal(1)
        self.speech_bubble.setBillboardAxis()
        
        # visual processing
        self.actor_eye = self.actor.exposeJoint(None, 'modelRoot', 'LeftEyeLid')
        # put a camera on ralph
        self.fov = NodePath(Camera('RaphViz'))
        self.fov.reparentTo(self.actor_eye)
        self.fov.setHpr(180,0,0)
        #lens = OrthographicLens()
        #lens.setFilmSize(20,15)
        #self.fov.node().setLens(lens)
        lens = self.fov.node().getLens()
        lens.setFov(60) #  degree field of view (expanded from 40)
        lens.setNear(0.2)
        #self.fov.node().showFrustum() # displays a box around his head


        self.actor_neck = self.actor.controlJoint(None, 'modelRoot', 'Neck')
	
        # Define subpart of agent for when he's standing around
        self.actor.makeSubpart("arms", ["LeftShoulder", "RightShoulder"])
        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
	
        self.current_frame_count = 0.0
	
        # 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.initialize_collision_handling()

    def initialize_collision_handling(self):
        self.collision_handling_mutex = Lock()
        
        self.cTrav = CollisionTraverser()
        
        self.groundRay = CollisionRay()
        self.groundRay.setOrigin(0,0,1000)
        self.groundRay.setDirection(0,0,-1)
        self.groundCol = CollisionNode('ralphRay')
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(0))
        self.groundCol.addSolid(self.groundRay)
        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 destroy_collision_handling(self):
        self.collision_handling_mutex.acquire()
    
    def handle_collisions(self):
        self.collision_handling_mutex.acquire()
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(1))

        # 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(self.startpos)
        
        self.groundCol.setIntoCollideMask(BitMask32.bit(0))
        self.groundCol.setFromCollideMask(BitMask32.bit(0))
        self.collision_handling_mutex.release()

    def position(self):
        return self.actor.getPos()
	
    def forward_normal_vector(self):
        backward = self.actor.getNetTransform().getMat().getRow3(1)
        backward.setZ(0)
        backward.normalize()
        return -backward

    def step_simulation_time(self, seconds):
        # save the character's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        self.startpos = self.actor.getPos()

        def bound(i, mn = -1, mx = 1): return min(max(i, mn), mx) # enforces bounds on a numeric value
        # move the character if any of the move controls are activated.

        if (self.controlMap["turn_left"]!=0):
            self.actor.setH(self.actor.getH() + seconds*30)
        if (self.controlMap["turn_right"]!=0):
            self.actor.setH(self.actor.getH() - seconds*30)
        if (self.controlMap["move_forward"]!=0):
            self.actor.setPos(self.actor.getPos() + self.forward_normal_vector() * (seconds*0.5))
        if (self.controlMap["move_backward"]!=0):
            self.actor.setPos(self.actor.getPos() - self.forward_normal_vector() * (seconds*0.5))
        if (self.controlMap["look_left"]!=0):
            self.actor_neck.setP(bound(self.actor_neck.getP(),-60,60)+1*(seconds*50))
        if (self.controlMap["look_right"]!=0):
            self.actor_neck.setP(bound(self.actor_neck.getP(),-60,60)-1*(seconds*50))
        if (self.controlMap["look_up"]!=0):
            self.actor_neck.setH(bound(self.actor_neck.getH(),-60,80)+1*(seconds*50))
        if (self.controlMap["look_down"]!=0):
            self.actor_neck.setH(bound(self.actor_neck.getH(),-60,80)-1*(seconds*50))

        # allow dialogue window to gradually decay (changing transparancy) and then disappear
        self.last_spoke += seconds
        self.speech_bubble['text_bg']=(1,1,1,1/(2*self.last_spoke+0.01))
        self.speech_bubble['frameColor']=(.6,.2,.1,.5/(2*self.last_spoke+0.01))
        if self.last_spoke > 2:
            self.speech_bubble['text'] = ""

        # If the character is moving, loop the run animation.
        # If he is standing still, stop the animation.
	
        if (self.controlMap["move_forward"]!=0) or (self.controlMap["move_backward"]!=0):
            if self.isMoving is False:
                self.isMoving = True
        else:
            if self.isMoving:
                self.current_frame_count = 5.0
                self.isMoving = False
	
	total_frame_num = self.actor.getNumFrames('walk')
	if self.isMoving:
		self.current_frame_count = self.current_frame_count + (seconds*10.0)
		while (self.current_frame_count >= total_frame_num + 1):
			self.current_frame_count -= total_frame_num
		while (self.current_frame_count < 0):
			self.current_frame_count += total_frame_num
	self.actor.pose('walk', self.current_frame_count)
	
        self.handle_collisions()

    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

        # 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

    # these are simple commands that can be exported over xml-rpc (or attached to the keyboard)


    def get_objects(self):
        """ Looks up all of the model nodes that are 'isInView' of the camera
        and returns them in the in_view dictionary (as long as they are also
        in the self.world_objects -- otherwise this includes points defined
        within the environment/terrain). 

        TODO:  1) include more geometric information about the object (size, mass, etc)
        """

        def map3dToAspect2d(node, point):
            """Maps the indicated 3-d point (a Point3), which is relative to 
            the indicated NodePath, to the corresponding point in the aspect2d 
            scene graph. Returns the corresponding Point3 in aspect2d. 
            Returns None if the point is not onscreen. """ 
            # Convert the point to the 3-d space of the camera 
            p3 = self.fov.getRelativePoint(node, point) 

            # Convert it through the lens to render2d coordinates 
            p2 = Point2()
            if not self.fov.node().getLens().project(p3, p2):
                return None 
            r2d = Point3(p2[0], 0, p2[1])
            # And then convert it to aspect2d coordinates 
            a2d = aspect2d.getRelativePoint(render2d, r2d)
            return a2d

        objs = render.findAllMatches("**/+ModelNode")
        in_view = {}
        for o in objs:
            o.hideBounds() # in case previously turned on
            o_pos = o.getPos(self.fov)
            if self.fov.node().isInView(o_pos):
                if self.agent_simulator.world_objects.has_key(o.getName()):
                    b_min, b_max =  o.getTightBounds()
                    a_min = map3dToAspect2d(render, b_min)
                    a_max = map3dToAspect2d(render, b_max)
                    if a_min == None or a_max == None:
                        continue
                    x_diff = math.fabs(a_max[0]-a_min[0])
                    y_diff = math.fabs(a_max[2]-a_min[2])
                    area = 100*x_diff*y_diff  # percentage of screen
                    object_dict = {'x_pos': (a_min[2]+a_max[2])/2.0,\
                                   'y_pos': (a_min[0]+a_max[0])/2.0,\
                                   'distance':o.getDistance(self.fov), \
                                   'area':area,\
                                   'orientation': o.getH(self.fov)}
                    in_view[o.getName()]=object_dict
                    print o.getName(), object_dict
        return in_view

    def control__turn_left__start(self):
        self.setControl("turn_left",  1)
        self.setControl("turn_right", 0)

    def control__turn_left__stop(self):
        self.setControl("turn_left",  0)

    def control__turn_right__start(self):
        self.setControl("turn_left",  0)
        self.setControl("turn_right", 1)

    def control__turn_right__stop(self):
        self.setControl("turn_right", 0)

    def control__move_forward__start(self):
        self.setControl("move_forward",  1)
        self.setControl("move_backward", 0)

    def control__move_forward__stop(self):
        self.setControl("move_forward",  0)

    def control__move_backward__start(self):
        self.setControl("move_forward",  0)
        self.setControl("move_backward", 1)

    def control__move_backward__stop(self):
        self.setControl("move_backward", 0)

    def control__look_left__start(self):
        self.setControl("look_left",  1)
        self.setControl("look_right", 0)

    def control__look_left__stop(self):
        self.setControl("look_left",  0)

    def control__look_right__start(self):
        self.setControl("look_right",  1)
        self.setControl("look_left", 0)

    def control__look_right__stop(self):
        self.setControl("look_right",  0)

    def control__look_up__start(self):
        self.setControl("look_up",  1)
        self.setControl("look_down", 0)

    def control__look_up__stop(self):
        self.setControl("look_up",  0)
    
    def control__look_down__start(self):
        self.setControl("look_down",  1)
        self.setControl("look_up",  0)
    
    def control__look_down__stop(self):
        self.setControl("look_down",  0)

    def can_grasp(self, object_name):
        objects = self.get_objects()
        if objects.has_key(object_name):
            object_view = objects[object_name]
            distance = object_view['distance']
            if (distance < 5.0):
                return True
        return False

    def control__say(self, message):
       self.speech_bubble['text'] = message
       self.last_spoke = 0

    def control__pick_up_with_right_hand(self, pick_up_object):
        print "attempting to pick up " + pick_up_object + " with right hand.\n"
        if self.right_hand_holding_object:
            return 'right hand is already holding ' + self.right_hand_holding_object.getName() + '.'
	if self.can_grasp(pick_up_object):
	    world_object = self.agent_simulator.world_objects[pick_up_object]
	    object_parent = world_object.getParent()
	    if (object_parent == self.agent_simulator.env):
		world_object.wrtReparentTo(self.actor_right_hand)
		world_object.setPos(0, 0, 0)
		world_object.setHpr(0, 0, 0)
		self.right_hand_holding_object = world_object
		return 'success'
	    else:
		return 'object (' + pick_up_object + ') is already held by something or someone.'
	else:
	    return 'object (' + pick_up_object + ') is not graspable (i.e. in view and close enough).'

    def put_object_in_empty_left_hand(self, object_name):
	if (self.left_hand_holding_object is not False):
	    return False
	world_object = self.agent_simulator.world_objects[object_name]
	world_object.wrtReparentTo(self.actor_left_hand)
	world_object.setPos(0, 0, 0)
	world_object.setHpr(0, 0, 0)
	self.left_hand_holding_object = world_object
	return True
    
    def control__pick_up_with_left_hand(self, pick_up_object):
        print "attempting to pick up " + pick_up_object + " with left hand.\n"
        if self.left_hand_holding_object:
            return 'left hand is already holding ' + self.left_hand_holding_object.getName() + '.'
        if self.can_grasp(pick_up_object):
	    world_object = self.agent_simulator.world_objects[pick_up_object]
	    object_parent = world_object.getParent()
	    if (object_parent == self.agent_simulator.env):
		self.put_object_in_empty_left_hand(pick_up_object)
		return 'success'
	    else:
		return 'object (' + pick_up_object + ') is already held by something or someone.'
        else:
            return 'object (' + pick_up_object + ') is not graspable (i.e. in view and close enough).'

    def control__drop_from_right_hand(self):
        print "attempting to drop object from right hand.\n"
        if self.right_hand_holding_object is False:
            return 'right hand is not holding an object.'
        world_object = self.right_hand_holding_object
        self.right_hand_holding_object = False
        world_object.wrtReparentTo(self.agent_simulator.env)
        world_object.setHpr(0, 0, 0)
        world_object.setPos(self.position() + self.forward_normal_vector() * 0.5)
        world_object.setZ(world_object.getZ() + 1.0)
        return 'success'
    
    def control__drop_from_left_hand(self):
        print "attempting to drop object from left hand.\n"
        if self.left_hand_holding_object is False:
            return 'left hand is not holding an object.'
        world_object = self.left_hand_holding_object
        self.left_hand_holding_object = False
        world_object.wrtReparentTo(self.agent_simulator.env)
        world_object.setHpr(0, 0, 0)
        world_object.setPos(self.position() + self.forward_normal_vector() * 0.5)
        world_object.setZ(world_object.getZ() + 1.0)
	return 'success'

    def is_holding(self, object_name):
	return ((self.left_hand_holding_object  and (self.left_hand_holding_object.getName()  == object_name)) or
		(self.right_hand_holding_object and (self.right_hand_holding_object.getName() == object_name)))
    
    def empty_hand(self):
        if (self.left_hand_holding_object is False):
            return self.actor_left_hand
        elif (self.right_hand_holding_object is False):
            return self.actor_right_hand
        return False

    def has_empty_hand(self):
        return (self.empty_hand() is not False)

    def control__use_object_with_object(self, use_object, with_object):
	if ((use_object == 'knife') and (with_object == 'loaf_of_bread')):
	    if self.is_holding('knife'):
		if self.can_grasp('loaf_of_bread'):
		    if self.has_empty_hand():
			empty_hand      = self.empty_hand()
			new_object_name = self.agent_simulator.create_object__slice_of_bread([float(x) for x in empty_hand.getPos()])
			if (empty_hand == self.actor_left_hand):
			    self.put_object_in_empty_left_hand(new_object_name)
			elif (empty_hand == self.actor_right_hand):
			    self.put_object_in_empty_right_hand(new_object_name)
			else:
			    return "simulator error: empty hand is not left or right.  (are there others?)"
			return 'success'
		    else:
			return 'failure: one hand must be empty to hold loaf_of_bread in place while using knife.'
		else:
		    return 'failure: loaf of bread is not graspable (in view and close enough)'
	    else:
		return 'failure: must be holding knife object to use it.'
        return 'failure: don\'t know how to use ' + use_object + ' with ' + with_object + '.'
Ejemplo n.º 18
0
Archivo: fpsTest.py Proyecto: croza/RR2
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
Ejemplo n.º 19
0
class World(DirectObject):

    def __init__(self):
        
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))

        # Post the instructions

        self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")
        
        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.  

        self.environ = loader.loadModel("models/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        
        # Create the main character, Ralph

        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor("models/ralph",
                                 {"run":"models/ralph-run",
                                  "walk":"models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos)

        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        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("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # 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.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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # 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)
       

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

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time elapsed since last frame. We need this
        # for framerate-independent movement.
        elapsed = globalClock.getDt()

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        base.camera.lookAt(self.ralph)
        if (self.keyMap["cam-left"]!=0):
            base.camera.setX(base.camera, -(elapsed*20))
        if (self.keyMap["cam-right"]!=0):
            base.camera.setX(base.camera, +(elapsed*20))

        # 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*25))

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        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
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False

        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.

        camvec = self.ralph.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
            camdist = 5.0

        # 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() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.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"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.ralph.getZ() + 2.0):
            base.camera.setZ(self.ralph.getZ() + 2.0)
            
        # The camera should look in ralph's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above ralph's head.
        
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ() + 2.0)
        base.camera.lookAt(self.floater)

        return Task.cont
Ejemplo n.º 20
0
class CogdoFlyingCameraManager:
    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

    def enable(self):
        if self._enabled:
            return
        self._toon.detachCamera()
        self._prevToonY = 0.0
        levelBounds = self._level.getBounds()
        l = Globals.Camera.LevelBoundsFactor
        self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]),
                        (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]),
                        (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2]))
        self._lookAtZ = self._toon.getHeight(
        ) + Globals.Camera.LookAtToonHeightOffset
        self._camParent = NodePath('CamParent')
        self._camParent.reparentTo(self._parent)
        self._camParent.setPos(self._toon, 0, 0, 0)
        self._camParent.setHpr(180, Globals.Camera.Angle, 0)
        self._camera.reparentTo(self._camParent)
        self._camera.setPos(0, Globals.Camera.Distance, 0)
        self._camera.lookAt(self._toon, 0, 0, self._lookAtZ)
        self._cameraLookAtNP = NodePath('CameraLookAt')
        self._cameraLookAtNP.reparentTo(self._camera.getParent())
        self._cameraLookAtNP.setPosHpr(self._camera.getPos(),
                                       self._camera.getHpr())
        self._levelBounds = self._level.getBounds()
        self._enabled = True
        self._frozen = False
        self._initCollisions()

    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 _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

    def disable(self):
        if not self._enabled:
            return
        self._destroyCollisions()
        self._camera.wrtReparentTo(render)
        self._cameraLookAtNP.removeNode()
        del self._cameraLookAtNP
        self._camParent.removeNode()
        del self._camParent
        del self._prevToonY
        del self._lookAtZ
        del self._bounds
        del self._frozen
        self._enabled = False

    def update(self, dt=0.0):
        self._updateCam(dt)
        self._updateCollisions()

    def _updateCam(self, dt):
        toonPos = self._toon.getPos()
        camPos = self._camParent.getPos()
        x = camPos[0]
        z = camPos[2]
        toonWorldX = self._toon.getX(render)
        maxX = Globals.Camera.MaxSpinX
        toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX)
        spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (
            maxX * maxX)
        newH = 180.0 + spinAngle
        self._camParent.setH(newH)
        spinAngle = spinAngle * (pi / 180.0)
        distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle)
        distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle)
        d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0])
        if abs(d) > Globals.Camera.LeewayX:
            if d > Globals.Camera.LeewayX:
                x = toonPos[0] + Globals.Camera.LeewayX
            else:
                x = toonPos[0] - Globals.Camera.LeewayX
        x = self._toon.getX(render) + distToRightOfToon
        boundToonZ = min(toonPos[2], self._bounds[2][1])
        d = z - boundToonZ
        if d > Globals.Camera.MinLeewayZ:
            if self._player.velocity[2] >= 0 and toonPos[
                    1] != self._prevToonY or self._player.velocity[2] > 0:
                z = boundToonZ + d * INVERSE_E**(dt *
                                                 Globals.Camera.CatchUpRateZ)
            elif d > Globals.Camera.MaxLeewayZ:
                z = boundToonZ + Globals.Camera.MaxLeewayZ
        elif d < -Globals.Camera.MinLeewayZ:
            z = boundToonZ - Globals.Camera.MinLeewayZ
        if self._frozen:
            y = camPos[1]
        else:
            y = self._toon.getY(render) - distBehindToon
        self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z))
        if toonPos[2] < self._bounds[2][1]:
            h = self._cameraLookAtNP.getH()
            if d >= Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ)
            elif d <= -Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._camParent, 0, 0,
                                            self._lookAtZ)
            self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0)
            self._camera.setHpr(
                smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr()))
        self._prevToonY = toonPos[1]

    def _updateCollisions(self):
        pos = self._toon.getPos(self._camera) + self._collOffset
        self._camCollRay.setOrigin(pos)
        direction = -Vec3(pos)
        direction.normalize()
        self._camCollRay.setDirection(direction)
        self._collTrav.traverse(render)
        nodesInBetween = {}
        if self._collHandler.getNumEntries() > 0:
            self._collHandler.sortEntries()
            for entry in self._collHandler.getEntries():
                name = entry.getIntoNode().getName()
                if name.find('col_') >= 0:
                    np = entry.getIntoNodePath().getParent()
                    if not np in nodesInBetween:
                        nodesInBetween[np] = np.getParent()

        for np in nodesInBetween.keys():
            if np in self._betweenCamAndToon:
                del self._betweenCamAndToon[np]
            else:
                np.setTransparency(True)
                np.wrtReparentTo(self._transNP)
                if np.getName().find('lightFixture') >= 0:
                    if not np.find('**/*floor_mesh').isEmpty():
                        np.find('**/*floor_mesh').hide()
                elif np.getName().find('platform') >= 0:
                    if not np.find('**/*Floor').isEmpty():
                        np.find('**/*Floor').hide()

        for np, parent in self._betweenCamAndToon.items():
            np.wrtReparentTo(parent)
            np.setTransparency(False)
            if np.getName().find('lightFixture') >= 0:
                if not np.find('**/*floor_mesh').isEmpty():
                    np.find('**/*floor_mesh').show()
            elif np.getName().find('platform') >= 0:
                if not np.find('**/*Floor').isEmpty():
                    np.find('**/*Floor').show()

        self._betweenCamAndToon = nodesInBetween
Ejemplo n.º 21
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 
Ejemplo n.º 22
0
class Input1(DirectObject):
    def __init__(self,model):
        # 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.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.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # 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)
       

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

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        # Get the time elapsed since last frame. We need this
        # for framerate-independent movement.
        elapsed = globalClock.getDt()       #Has a Change in time from 0.04 to 0.09 constantly changes
        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        base.camera.lookAt(self.model.getX(),self.model.getY(),0)
        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.model.getPos()

        # If a move-key is pressed, move ralph in the specified direction.
                
        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.

        camvec = self.model.getPos() - base.camera.getPos()
        camvec.setZ(5)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 30.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-30))
            camdist = 30.0
        if (camdist < 15.0):
            base.camera.setPos(base.camera.getPos() - camvec*(15-camdist))
            camdist = 15.0
            
        # The camera should look in ralph's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above ralph's head.
        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.
        self.floater.setPos(self.model.getPos())
        base.camera.lookAt(self.floater)        
        # 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() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(startpos)

        
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.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"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.ralph.getZ() + 2.0):
            base.camera.setZ(self.ralph.getZ() + 2.0)
            
        
        return Task.cont
Ejemplo n.º 23
0
class AreaMapper(object):
    def __init__(self, environment):
        '''
        Create a map of the free space in a given area.
        '''
        self.csRadius = 1
        self.csHeight = 2
        self.avatarRadius = 1.4
        self.cs = CollisionSphere(0, 0, 0, 1)

        self.csNode = CollisionNode("AreaMapperCollisionSphere")
        self.csNode.setFromCollideMask(OTPGlobals.WallBitmask)
        self.csNode.setIntoCollideMask(BitMask32.allOff())
        self.csNode.addSolid(self.cs)

        self.environment = environment

        self.csNodePath = self.environment.getTop().attachNewNode(self.csNode)

        self.floorRay = CollisionRay()
        self.floorRay.setDirection(0, 0, -1)
        self.floorRay.setOrigin(0, 0, 0)

        self.floorRayNode = CollisionNode("AreaMapperFloorRay")
        self.floorRayNode.setFromCollideMask(OTPGlobals.FloorBitmask)
        self.floorRayNode.setIntoCollideMask(BitMask32.allOff())
        self.floorRayNode.addSolid(self.floorRay)

        self.floorRayNodePath = self.environment.getTop().attachNewNode(
            self.floorRayNode)

        self.chq = CollisionHandlerQueue()
        self.traverser = CollisionTraverser()

        self.startX = 0
        self.startY = 0
        self.startZ = 0

        self.frontierSquares = {(0, 0): 1}
        self.frontierSquaresQueue = [(0, 0)]
        self.walkableSquares = {(0, 0): 1}
        self.blockedSquares = {}

        self.setSquareSize(2)
        self.startAtPlayerSpawn()

        self.visGeom = None
        self.visGN = None
        self.visNodePath = None

        self.triVertexLookup = {}
        self.triList = []

        self.minX = 500
        self.maxX = -500
        self.minY = 500
        self.maxY = -500

        self.quadTree = QuadTree(width=1024)
        self.squares = []

        self.runDiscovery(100000)

        self._subdivide()

        #self._fixZValues()

        self.csNodePath.removeNode()
        self.floorRayNodePath.removeNode()

##     def _unstashEnvironment(self):
##         # Would be nice if we could just do this  :(
##         #for np in self.environment.findAllMatches("**/+CollisionNode;+s"):
##         #    np.unstash()
##         b = self.environment.builder
##         for s in b.sections.values():
##             s.unstash()
##         for o in b.largeObjects.values():
##             o.unstash()

    def setStart(self, x, y):
        self.startX = x
        self.startY = y
        self.startZ = self.findFloor(x, y)

    def startAtLocalAvatar(self):
        startPos = localAvatar.getPos(self.environment)
        self.setStart(startPos.getX(), startPos.getY())

    def startAtPlayerSpawn(self):
        # XXX Bleugh, this is really pirates-specific.  Nasty.
        for spawnPt in self.environment.world.getAllPlayerSpawnPts():
            parentDoId = self.environment.world.uidMgr.getDoId(spawnPt[1])
            if parentDoId == self.environment.doId:
                # Sweet, we found a spawn point for this grid's gamearea.  Use it!

                z = self.findFloor(spawnPt[0][0], spawnPt[0][1])
                if not self.isSphereBlocked(spawnPt[0][0], spawnPt[0][1], z):
                    self.setStart(spawnPt[0][0], spawnPt[0][1])
                    return

        raise "No player spawn points found for the given game area!  D:"

    def setSquareSize(self, size):
        self.squareSize = size
        self.csRadius = math.sqrt(
            2 * (self.squareSize * self.squareSize / 4)) + self.avatarRadius
        self.csNodePath.setScale(self.environment, self.csRadius,
                                 self.csRadius, self.csRadius)
        self.csHeight = self.csRadius * 2

    def findFloor(self, x, y):
        self.floorRayNodePath.setPos(self.environment, x, y, 50000)

        self.chq.clearEntries()

        self.traverser.clearColliders()
        self.traverser.addCollider(self.floorRayNodePath, self.chq)
        self.traverser.traverse(self.environment)

        highestZ = -50000

        for e in self.chq.getEntries():
            assert e.hasInto()
            assert e.getInto().isTangible()
            assert e.hasSurfacePoint()

            z = e.getSurfacePoint(self.environment).getZ()

            if z > highestZ:
                highestZ = z

        return highestZ

    def isSphereBlocked(self, x, y, z):
        if z < self.csHeight:
            return True

        self.csNodePath.setPos(self.environment, x, y, z)

        self.chq.clearEntries()

        self.traverser.clearColliders()
        self.traverser.addCollider(self.csNodePath, self.chq)
        self.traverser.traverse(self.environment)

        for entry in self.chq.getEntries():
            if entry.hasInto():
                if entry.getInto().isTangible():
                    return True

        return False

    def _neighbors(self, x, y):
        return [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]

    def _explore(self, p):
        x, y = p
        x1 = self.startX + self.squareSize * x
        y1 = self.startY + self.squareSize * y
        z1 = self.findFloor(x1, y1)
        if self.isSphereBlocked(x1, y1, z1 + self.csHeight):
            self.blockedSquares[p] = z1
            return
        else:
            self.walkableSquares[p] = z1
            self.quadTree.fill(x, y)
            for n in self._neighbors(x, y):
                if not (n in self.frontierSquares or n in self.walkableSquares
                        or n in self.blockedSquares):
                    self.frontierSquares[n] = 1
                    self.frontierSquaresQueue.append(n)

    def _exploreFrontier(self):
        if len(self.frontierSquaresQueue) == 0:
            assert len(self.frontierSquares.keys()) == 0
            return 0
        else:
            qlen = len(self.frontierSquaresQueue)
            for i in xrange(qlen):
                p = self.frontierSquaresQueue.pop(0)
                del self.frontierSquares[p]
                self._explore(p)
            return qlen

    def runDiscovery(self, maxSquares):
        print "Discovering walkable space (this will take 30-60 seconds)..."
        #self._unstashEnvironment()
        squaresExplored = 1

        self.walkableSquares[(0, 0)] = self.findFloor(self.startX, self.startY)

        while (squaresExplored < maxSquares) and (len(
                self.frontierSquaresQueue) > 0):
            squaresExplored += self._exploreFrontier()

##     def visualize(self):
##         gFormat = GeomVertexFormat.getV3cp()
##         self.vertexData = GeomVertexData("OMGVERTEXDATA", gFormat, Geom.UHDynamic)
##         self.vertexWriter = GeomVertexWriter(self.vertexData, "vertex")
##         self.colorWriter = GeomVertexWriter(self.vertexData, "color")

##         numVerts = 0

##         for xa,ya,xb,yb in self.squares:
##             x1 = self.startX + self.squareSize*(xa) - self.squareSize*0.5
##             y1 = self.startY + self.squareSize*(ya) - self.squareSize*0.5

##             x2 = self.startX + self.squareSize*(xb) + self.squareSize*0.5
##             y2 = self.startY + self.squareSize*(yb) + self.squareSize*0.5

##             self.vertexWriter.addData3f(x1,y1,self.findFloor(x1,y1)+0.1)
##             self.colorWriter.addData4f(0.0, 1.0, 0.0, 0.5)

##             self.vertexWriter.addData3f(x2,y1,self.findFloor(x2,y1)+0.1)
##             self.colorWriter.addData4f(0.0, 1.0, 0.0, 0.5)

##             self.vertexWriter.addData3f(x2,y2,self.findFloor(x2,y2)+0.1)
##             self.colorWriter.addData4f(0.0, 1.0, 0.0, 0.5)

##             self.vertexWriter.addData3f(x1,y2,self.findFloor(x1,y2)+0.1)
##             self.colorWriter.addData4f(0.0, 1.0, 0.0, 0.5)

##             numVerts += 4

##         print "NUMVERTS: ", numVerts

##         self.pointVis = GeomLinestrips(Geom.UHStatic)

##         for i in xrange(numVerts/4):
##             self.pointVis.addVertex(i*4)
##             self.pointVis.addVertex(i*4+1)
##             self.pointVis.addVertex(i*4+2)
##             self.pointVis.addVertex(i*4+3)
##             self.pointVis.addVertex(i*4)
##             self.pointVis.closePrimitive()

##         self.visGeom = Geom(self.vertexData)
##         self.visGeom.addPrimitive(self.pointVis)

##         self.visGN = GeomNode("NavigationGridVis")
##         self.visGN.addGeom(self.visGeom)

##         self.visNodePath = self.environment.attachNewNode(self.visGN)

##         self.visNodePath.setTwoSided(True)
##         self.visNodePath.setRenderModeThickness(4)
##         #self.visNodePath.setTransparency(1)

# ---------- Begin Triangulation Code ------------

##     def _addTriVertex(self,x,y):
##         '''
##         lookup[(x,y)] is a reference to the vert located to the UPPER-LEFT of grid square (x,y)
##         '''
##         if (x,y) not in self.gridCoordToVertexId:
##             vId = self.vertexCounter
##             self.vertexCounter += 1

##             self.gridCoordToVertexId[(x,y)] = vId

##             x1 = self.startX + self.squareSize*x - (0.5 * self.squareSize)
##             y1 = self.startY + self.squareSize*y - (0.5 * self.squareSize)
##             z1 = self.findFloor(x1,y1)
##             self.vertexIdToXYZ[vId] = (x1,y1,z1)

##             self.vertexToTris[vId] = []

##         return self.gridCoordToVertexId[(x,y)]

##     def _triangulateGridSquare(self,x,y,left=True):
##         a = self._addTriVertex(x,y)
##         b = self._addTriVertex(x+1,y)
##         c = self._addTriVertex(x+1,y+1)
##         d = self._addTriVertex(x,y+1)

##         if x < self.minX:
##             self.minX = x
##         if x > self.maxX:
##             self.maxX = x
##         if y < self.minY:
##             self.minY = y
##         if y > self.maxY:
##             self.maxY = y

##         if left:
##             self.triToVertices[self.triCounter] = [a,b,d]
##             self.triToAngles[self.triCounter] = [90,45,45]

##             self.triToVertices[self.triCounter+1] = [b,c,d]
##             self.triToAngles[self.triCounter+1] = [45,90,45]

##             self.vertexToTris[a].append(self.triCounter)
##             self.vertexToTris[b].append(self.triCounter)
##             self.vertexToTris[b].append(self.triCounter+1)
##             self.vertexToTris[c].append(self.triCounter+1)
##             self.vertexToTris[d].append(self.triCounter)
##             self.vertexToTris[d].append(self.triCounter+1)
##         else:
##             self.triToVertices[self.triCounter] = [a,b,c]
##             self.triToAngles[self.triCounter] = [45,90,45]

##             self.triToVertices[self.triCounter+1] = [a,c,d]
##             self.triToAngles[self.triCounter+1] = [45,45,90]

##             self.vertexToTris[a].append(self.triCounter)
##             self.vertexToTris[a].append(self.triCounter+1)
##             self.vertexToTris[b].append(self.triCounter)
##             self.vertexToTris[c].append(self.triCounter)
##             self.vertexToTris[c].append(self.triCounter+1)
##             self.vertexToTris[d].append(self.triCounter+1)

##         self.triCounter += 2

##     def countCruft(self):
##         count = 0
##         for s in self.squares:
##             if (s[0] == s[2]) and (s[1] == s[3]):
##                 x = s[0]
##                 y = s[1]
##                 numNeighbors = 0
##                 for (x1,y1) in [(x+1,y),(x-1,y),(x,y+1),(x,y-1)]:
##                     if (x1,y1) in self.walkableSquares:
##                         numNeighbors += 1
##                 if numNeighbors < 3:
##                     count += 1
##         return count

##     def killCruft(self):
##         for i in xrange(len(self.squares)):
##             s = self.squares[i]
##             if (s[0] == s[2]) and (s[1] == s[3]):
##                 x = s[0]
##                 y = s[1]
##                 numNeighbors = 0
##                 for (x1,y1) in [(x+1,y),(x-1,y),(x,y+1),(x,y-1)]:
##                     if (x1,y1) in self.walkableSquares:
##                         numNeighbors += 1
##                 if numNeighbors < 3:
##                     self.squares[i] = None

##         self.squares = [s for s in self.squares if s != None]

    def _addVertexByGridCoords(self, x, y):
        '''
        lookup[(x,y)] is a reference to the vert located at (-0.5,-0.5) from grid square (x,y)
        '''
        if (x, y) not in self.gridCoordToVertexId:
            vId = self.vertexCounter
            self.vertexCounter += 1

            self.gridCoordToVertexId[(x, y)] = vId

            x1 = self.startX + self.squareSize * x - (0.5 * self.squareSize)
            y1 = self.startY + self.squareSize * y - (0.5 * self.squareSize)
            z1 = self.findFloor(x1, y1)
            self.vertexIdToXYZ[vId] = (x1, y1, z1)

            self.vertToPolys[vId] = []

        return self.gridCoordToVertexId[(x, y)]

    def _addOpenSquare(self, gridX1, gridY1, gridX2, gridY2):
        curSpot = [gridX1, gridY1]

        verts = []
        angles = []

        while curSpot[0] <= gridX2:
            verts.append(self._addVertexByGridCoords(curSpot[0], curSpot[1]))
            if curSpot[0] == gridX1:
                angles.append(90)
            else:
                angles.append(180)
            self.vertToPolys[verts[-1]].append(self.polyCounter)
            curSpot[0] += 1

        while curSpot[1] <= gridY2:
            verts.append(self._addVertexByGridCoords(curSpot[0], curSpot[1]))
            if curSpot[1] == gridY1:
                angles.append(90)
            else:
                angles.append(180)
            self.vertToPolys[verts[-1]].append(self.polyCounter)
            curSpot[1] += 1

        while curSpot[0] > gridX1:
            verts.append(self._addVertexByGridCoords(curSpot[0], curSpot[1]))
            if curSpot[0] == gridX2 + 1:
                angles.append(90)
            else:
                angles.append(180)
            self.vertToPolys[verts[-1]].append(self.polyCounter)
            curSpot[0] -= 1

        while curSpot[1] > gridY1:
            if curSpot[1] == gridY2 + 1:
                angles.append(90)
            else:
                angles.append(180)
            verts.append(self._addVertexByGridCoords(curSpot[0], curSpot[1]))
            self.vertToPolys[verts[-1]].append(self.polyCounter)
            curSpot[1] -= 1

        self.polyToVerts[self.polyCounter] = verts
        self.polyToAngles[self.polyCounter] = angles
        self.polyCounter += 1

    def _subdivide(self):
        print "Growing squares..."
        self.vertexCounter = 0
        self.polyCounter = 0

        self.gridCoordToVertexId = {}
        self.vertexIdToXYZ = {}

        self.polyToVerts = {}
        self.polyToAngles = {}
        self.vertToPolys = {}

        self.squares = self.quadTree.squarify()

        for (gridX1, gridY1, gridX2, gridY2) in self.squares:
            self._addOpenSquare(gridX1, gridY1, gridX2, gridY2)
Ejemplo n.º 24
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
Ejemplo n.º 25
0
class Camera:
    """A floating 3rd person camera that follows an actor around, and can be 
    turned left or right around the actor. 

    Public fields: 
    self.controlMap -- The camera's movement controls. 
    actor -- The Actor object that the camera will follow. 
    
    Public functions: 
    init(actor) -- Initialise the camera. 
    move(task) -- Move the camera each frame, following the assigned actor. 
                  This task is called every frame to update the camera. 
    setControl -- Set the camera's turn left or turn right control on or off. 
    
    """
    def __init__(self, actor):
        """Initialise the camera, setting it to follow 'actor'. 
        
        Arguments: 
        actor -- The Actor that the camera will initially follow. 
        
        """

        self.actor = actor
        self.prevtime = 0

        # The camera's controls:
        # "left" = move the camera left, 0 = off, 1 = on
        # "right" = move the camera right, 0 = off, 1 = on
        self.controlMap = {"left": 0, "right": 0}

        taskMgr.add(self.move, "cameraMoveTask")

        # Create a "floater" object. It is used to orient the camera above the
        # target actor's head.

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

        # Set up the camera.

        base.disableMouse()
        base.camera.setPos(self.actor.getX(), self.actor.getY() + 2, 2)
        # uncomment for topdown
        #base.camera.setPos(self.actor.getX(),self.actor.getY()+10,2)
        #base.camera.setHpr(180, -50, 0)

        # A CollisionRay beginning above the camera and going down toward the
        # ground is used to detect camera collisions and the height of the
        # camera above the ground. A ray may hit the terrain, or it may hit a
        # rock or a tree.  If it hits the terrain, we detect the camera's
        # height.  If it hits anything else, the camera is in an illegal
        # position.

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

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

    def move(self, task):
        """Update the camera's position before rendering the next frame. 
        
        This is a task function and is called each frame by Panda3D. The 
        camera follows self.actor, and tries to remain above the actor and 
        above the ground (whichever is highest) while looking at a point 
        slightly above the actor's head. 
        
        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. 
        
        """

        # FIXME: There is a bug with the camera -- if the actor runs up a
        # hill and then down again, the camera's Z position follows the actor
        # up the hill but does not come down again when the actor goes down
        # the hill.

        elapsed = task.time - self.prevtime

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        # comment out for topdown
        base.camera.lookAt(self.actor)

        camright = base.camera.getNetTransform().getMat().getRow3(0)
        camright.normalize()
        if (self.controlMap["left"] != 0):
            base.camera.setPos(base.camera.getPos() - camright *
                               (elapsed * 20))
        if (self.controlMap["right"] != 0):
            base.camera.setPos(base.camera.getPos() + camright *
                               (elapsed * 20))

        # If the camera is too far from the actor, move it closer.
        # If the camera is too close to the actor, move it farther.

        camvec = self.actor.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Keep the camera at one foot above the terrain,
        # or two feet above the actor, whichever is greater.
        # comment out for topdown

        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"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0)
        if (base.camera.getZ() < self.actor.getZ() + 2.0):
            base.camera.setZ(self.actor.getZ() + 2.0)

        # The camera should look in the player's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above the player's head.

        self.floater.setPos(self.actor.getPos())
        self.floater.setZ(self.actor.getZ() + 2.0)

        #self.floater.setZ(self.actor.getZ() + 10.0)
        #self.floater.setY(self.actor.getY() + 7.0)

        # comment out for topdown
        base.camera.lookAt(self.floater)

        base.camera.setPos(self.floater.getPos())

        # 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 camera'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