def initCollisions(self):
     self.collNodePath.setCollideMask(BitMask32(0))
     self.collNodePath.node().setFromCollideMask(CIGlobals.WallBitmask)
     pusher = CollisionHandlerPusher()
     pusher.setInPattern('%in')
     pusher.addCollider(self.collNodePath, self)
     base.cTrav.addCollider(self.collNodePath, pusher)
 def addPlayer(self, name):
     self.players[name] = PlayerLogic(name)
     self.players[name].nodePath = self.nodePath.attachNewNode(PandaNode(name))
     
     collisionNodePath = self.players[name].nodePath.attachNewNode(CollisionNode("pusherCollision"))
     collisionNodePath.node().addSolid(CollisionSphere(0, 0, 0, 1))
     pusher = CollisionHandlerPusher()
     pusher.addCollider(collisionNodePath, self.players[name].nodePath)
     self.traverser.addCollider(collisionNodePath, pusher)
 def setupCollision(self):
     cs = CollisionSphere(0, 0, 0, 10)
     cnodePath = self.player.attachNewNode(CollisionNode('cnode'))
     cnodePath.node().addSolid(cs)
     cnodePath.show()
     for o in self.OBS:
         ct = CollisionBox(0, 1, 1, 0.5)
         cn = o.attachNewNode(CollisionNode('ocnode'))
         cn.node().addSolid(ct)
         cn.show()
     pusher = CollisionHandlerPusher()
     pusher.addCollider(cnodePath, self.player)
     self.cTrav = CollisionTraverser()
     self.cTrav.addCollider(cnodePath, pusher)
     self.cTrav.showCollisions(render)
Exemple #4
0
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # Create player node and attach camera and collision node/solid
        self.Player = render.attachNewNode('Player')
        self.camera.reparentTo(self.Player)
        self.PlayerCN = CollisionNode('Player')
        self.PlayerCNP = self.Player.attachNewNode(self.PlayerCN)
        self.PlayerCSph = CollisionSphere(0, 0, 0, 1)
        self.PlayerCN.addSolid(self.PlayerCSph)
        # Player collision sphere
        playerCS = CollisionSphere(0, 0, 0, 2)
        playerCNP = self.Player.attachNewNode(CollisionNode('cnode'))
        playerCNP.node().addSolid(playerCS)
        #PlayerCNP.reparentTo(self.camera)
        playerCNP.show() # This won't show since we are inside
        
        # Create generic sphere in the world in front of us to see
        self.Sphere = self.loader.loadModel("models/misc/sphere")
        self.Sphere.reparentTo(self.render)
        self.Sphere.setPos(0, 20, -0.2)
        # Collision sphere for visible sphere, slightly larger
        cs = CollisionSphere(0, 0, 0, 1)
        cnodePath = self.Sphere.attachNewNode(CollisionNode('cSpherenode'))
        cnodePath.node().addSolid(cs)
        cnodePath.show()
        
        # Create global collision traverser
        self.cTrav = CollisionTraverser()
        # Collision handler pusher - visible sphere will push back
        self.pusher = CollisionHandlerPusher()

        # Tell player sphere to act as pusher - or world object?
        self.cTrav.addCollider(cnodePath, self.pusher)
        self.pusher.addCollider(cnodePath, self.Sphere, base.drive.node())

        seq = self.Player.posInterval(5, Point3(0, 40, 0), 
                                     startPos=Point3(0, 0, 0), fluid=1).loop()
        def setupCollision(self):
	    cs = CollisionSphere(0,0,2,1)
	    cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(cs)
	    cnodePath.show()
	    #for o in self.OBS:
		#ct = CollisionTube(0,0,0, 0,0,1, 0.5)
		#cn = o.attachNewNode(CollisionNode('ocnode'))
		#cn.node().addSolid(ct)
		#cn.show()
	    eyecs = CollisionSphere(0,0,4,5)
	    cnodePath = self.gianteye.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	 
	    eyecs = CollisionSphere(0,0,4,2)
	    cnodePath = self.chik.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	    
    
	    pusher = CollisionHandlerPusher()
	    pusher.addCollider(cnodePath, self.player)
	    self.cTrav = CollisionTraverser()
	    self.cTrav.add_collider(cnodePath,pusher)
	    self.cTrav.showCollisions(render)
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)
        self.orbCollisionHandler = CollisionHandlerQueue()
        self.cTrav = CollisionTraverser()

        #hbPath = NodePath()

        utils3.setUpKeys(self)
        utils3.loadModels(self)
        utils3.setUpLighting(self)
        utils3.setUpFloatingSpheres(self)
        utils3.setUpRalphsShot(self)
        utils3.setUpCamera(self)
        self.healthTxt = utils3.addInstructions(.06,"Health: 100")
        self.orbTxt = utils3.addInstructions(.18,"Orbs: 0")

        self.vec = LVector3(0,1,0)#vector for pawns shot

        # Create a frame
        #frame = DirectFrame(text = "main", scale = 0.001)
        # Add button
        #bar = DirectWaitBar(text = "", value = 50, pos = (0,.4,.4))
        #bar.reparent(render)

        # Game state variables
        self.isMoving = False
        self.jumping = False
        self.vz = 0
        self.numOrbs = 0
        self.healthCount = 100

        #self.shotList = []
        taskMgr.add(self.move, "moveTask")
        #taskMgr.add(utils2.moveChris,"moveChrisTask")
        
        self.sphere = CollisionSphere(0,0,4,2)
        self.sphere2 = CollisionSphere(0,0,2,2)
        self.cnodePath = self.ralph.attachNewNode((CollisionNode('ralphColNode')))
        self.cnodePath.node().addSolid(self.sphere)
        self.cnodePath.node().addSolid(self.sphere2)
        #self.cnodePath.show()
        
        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.cnodePath, self.ralph)

        #self.cTrav.addCollider(self.cnodePath, self.ralphCollisionHandler)
        self.cTrav.addCollider(self.cnodePath, self.pusher)

        ca = CollisionSphere(0,0,0,20)
        cb = self.chik.attachNewNode(CollisionNode('chikCollisionNode'))
        cb.node().addSolid(ca)
        cb.show()

        cc = CollisionSphere(3,5,12,25)
        cd = self.gianteye.attachNewNode(CollisionNode('gianteyeCollisionNode'))
        cd.node().addSolid(cc)
        cd.show()

        ci = CollisionSphere(0,0,0,2)
        coi = self.catidol.attachNewNode(CollisionNode('catidolCollisionNode'))
        coi.node().addSolid(ci)
        coi.show()

        chi = CollisionSphere(-1,3,3,3)
        chco = self.chris.attachNewNode(CollisionNode('chrisColPath'))
        chco.node().addSolid(chi)
        self.cTrav.addCollider(chco, self.orbCollisionHandler)
        #chco.show()

        self.chris.setH(90)
        self.chris.setR(-90)
        self.chris.setZ(2)

        #cbox = CollisionBox((-50,30,20),10,85,20)
        #cboxPath = self.room.attachNewNode(CollisionNode('roomSide1'))
        #cboxPath.node().addSolid(cbox)
        #cboxPath.show()

        #cbox2 = CollisionBox((200,30,20),10,85,20)
        #cboxPath2 = self.room.attachNewNode(CollisionNode('roomSide1'))
        #cboxPath2.node().addSolid(cbox2)
        #cboxPath2.show()

        #cbox3 = CollisionBox((80,-60,20),120,20,20)
        #cboxPath3 = self.room.attachNewNode(CollisionNode('roomSide1'))
        #cboxPath3.node().addSolid(cbox3)
        #cboxPath3.show()

        ct = CollisionSphere(0,0,0,1)
        cn = self.pawn.attachNewNode(CollisionNode('pawnCollisionNode'))
        cn.node().addSolid(ct)
        cn.show()

        cs2 = CollisionSphere(0,0,0,.2)
        cs2path = self.plnp.attachNewNode((CollisionNode('orbColPath')))
        cs2path.node().addSolid(cs2)
        cs2path.show()

        self.cTrav.addCollider(cs2path, self.orbCollisionHandler)

        #cs3 = CollisionSphere(0,0,0,1)
        cs3path = self.plnp2.attachNewNode((CollisionNode('orbColPath')))
        cs3path.node().addSolid(cs2)
        cs3path.show()

        chrisShotNp = self.chrisShot.attachNewNode((CollisionNode("enemyOrbColPath")))
        chrisShotNp.node().addSolid(cs2)
        chrisShotNp.show()

        self.cTrav.addCollider(cs3path, self.orbCollisionHandler)
        self.cTrav.addCollider(chrisShotNp, self.orbCollisionHandler)


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

        self.chrisLastShotTime = globalClock.getFrameTime()
        self.chrisTimer = globalClock.getDt()

    # 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 that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()
        utils3.moveChris(self,dt)

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

        if self.keyMap["cam-left"]:
            self.camera.setZ(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setZ(self.camera, +20 * dt)

        # 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"]:
            self.ralph.setH(self.ralph.getH() + 150 * dt)
            #self.camera.setX(self.camera, +15.5 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 150 * dt)
            #self.camera.setX(self.camera, -15.5 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -35 * dt)
            #self.camera.setY(self.camera, -35 * dt)
        if self.keyMap["back"]:
            self.ralph.setY(self.ralph, +35 * dt)
            #self.camera.setY(self.camera, 35 * dt)
        if self.keyMap["c"]:
            if self.jumping is False:
            #self.ralph.setZ(self.ralph.getZ() + 100 * dt)
                self.jumping = True
                self.vz = 7

        if self.keyMap["space"]:
            self.keyMap["space"] = False
            self.shotList[self.shotCount].lpivot.setPos(self.ralph.getPos())
            self.shotList[self.shotCount].lpivot.setZ(self.ralph.getZ() + .5)
            self.shotList[self.shotCount].lpivot.setX(self.ralph.getX() - .25)

            #self.shotList.append(rShot)
            #self.lightpivot3.setPos(self.ralph.getPos())
            #self.lightpivot3.setZ(self.ralph.getZ() + .5)
            #self.lightpivot3.setX(self.ralph.getX() - .25)
            #self.myShot.setHpr(self.ralph.getHpr())
            #parent to ralph
            #node = NodePath("tmp")
            #node.setHpr(self.ralph.getHpr())
            #vec = render.getRelativeVector(node,(0,-1,0))
            #self.myShotVec = vec

            node = NodePath("tmp")
            node.setHpr(self.ralph.getHpr())
            vec = render.getRelativeVector(node,(0,-1,0))
            self.shotList[self.shotCount].vec = vec
            self.shotCount = (self.shotCount + 1) % 5


        for rs in self.shotList:
            rs.lpivot.setPos(rs.lpivot.getPos() + rs.vec * dt * 15 )
            #if shot is too far stop updating



        if self.jumping is True:
            self.vz = self.vz - 16* dt
            self.ralph.setZ(self.ralph.getZ() + self.vz * dt )
            if self.ralph.getZ() < 0:
                self.ralph.setZ(0)
                self.jumping = False
        else:
            if self.ralph.getZ() < 0:
                self.ralph.setZ(0)
            elif self.ralph.getZ() > 0:
                self.ralph.setZ(self.ralph.getZ() -7 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"] or self.keyMap["c"] or self.keyMap["forward"] or self.keyMap["back"]:
            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

        # update pawns shot or set up new shot after it reaches a certain distance
        node = NodePath("tmp")
        node.setHpr(self.pawn.getHpr())
        vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
        self.shot.setPos(self.shot.getPos() + self.vec * dt * 10 )
        if self.shot.getY() < -15 or self.shot.getY() > 30 or self.shot.getX() < 5 or self.shot.getX() > 15:
            self.shot.setPos(self.pawn.getPos() + (0,0,0))
            self.vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
            self.vec = render.getRelativeVector(node,(random.random() * random.randrange(-1,2),random.random() + 1,0))

        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.
        #self.camera.lookAt(self.floater)
        camvec = self.ralph.getPos() - self.camera.getPos()
        #camvec = Vec3(0,camvec.getY(),0)
        camdist = camvec.length()
        x = self.camera.getZ()
        camvec.normalize()
        #if camdist > 6.0:
        #    self.camera.setPos(self.camera.getPos() + camvec * (camdist - 6))
        #if camdist < 6.0:
        #    self.camera.setPos(self.camera.getPos() - camvec * (6 - camdist))

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #self.cTrav.traverse(render)

        # Adjust camera so it stays at same height
        if self.camera.getZ() < self.ralph.getZ() + 1 or self.camera.getZ() > self.ralph.getZ() + 1:
            self.camera.setZ(self.ralph.getZ() + 1)

        # 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.camera.lookAt(self.floater)


        entries = list(self.orbCollisionHandler.getEntries())
        if(len(entries) > 0):
            #self.lightpivot.reparentTo(NodePath())
            for entry in self.orbCollisionHandler.getEntries():
                #print(entry)
                fromColNp = entry.getFromNodePath()
                toColNp = entry.getIntoNodePath()
                if fromColNp.getName() == "orbColPath" and toColNp.getName() == "ralphColNode":
                    fromColNp.getParent().reparentTo(NodePath())
                    self.orbTxt.destroy()
                    self.numOrbs += 1
                    str1 = "Orbs: " + str(self.numOrbs)
                    self.orbTxt = utils3.addInstructions(.18, str1)
                elif toColNp.getName() == "orbColPath" and fromColNp.getName() == "ralphColNode":
                    toColNp.getParent().reparentTo(NodePath())
                    self.orbTxt.destroy()
                    self.numOrbs += 1
                    str1 = "Orbs: " + str(self.numOrbs)
                    self.orbTxt = utils3.addInstructions(.18, str1)
                elif toColNp.getName() == "ralphOrbColPath" and fromColNp.getName() == "chrisColPath":
                    toColNp.getParent().setPos(-50,0,2)
                    self.chrisHealth = self.chrisHealth - 1
                    self.chris.setColor(1,0,0,1)
                    self.chrisHit = True
                    self.chrisRedTime = globalClock.getFrameTime()
                    #print self.chrisRedTime
                    if self.chrisHealth < 0:
                        fromColNp.getParent().removeNode()
                        self.chrisAlive = False
                elif toColNp.getName() == "chrisColPath" and fromColNp.getName() == "ralphOrbColPath":
                    fromColNp.getParent().setPos(-50,0,2)
                    self.chrisHealth = self.chrisHealth - 1
                    self.chris.setColor(1,0,0,1)
                    self.chrisHit = True
                    self.chrisRedTime = globalClock.getFrameTime()
                    #print self.chrisRedTime
                    if self.chrisHealth < 0:
                        fromColNp.getParent().removeNode()
                        self.chrisAlive = False
                        self.chrisShot.setZ(26)
                elif toColNp.getName() == "enemyOrbColPath" and fromColNp.getName() == "ralphColNode":
                    toColNp.getParent().setZ(26)
                    self.healthTxt.destroy()
                    self.healthCount -= 3
                    str1 = "Health: " + str(self.healthCount)
                    self.healthTxt = utils3.addInstructions(.06, str1)
                elif toColNp.getName() == "ralphColNode" and fromColNp.getName() == "enemyOrbColPath":
                    fromColNp.getParent().setZ(26)
                    self.healthTxt.destroy()
                    self.healthCount -= 3
                    str1 = "Health: " + str(self.healthCount)
                    self.healthTxt = utils3.addInstructions(.06, str1)



        return task.cont
Exemple #7
0
class CogdoFlyingCollisions(GravityWalker):
    wantFloorSphere = 0

    def __init__(self):
        GravityWalker.__init__(self, gravity=0.0)

    def initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0):
        self.cHeadSphereNodePath = None
        self.cFloorEventSphereNodePath = None
        self.setupHeadSphere(avatarNodePath)
        self.setupFloorEventSphere(avatarNodePath, ToontownGlobals.FloorEventBitmask, avatarRadius)
        GravityWalker.initializeCollisions(self, collisionTraverser, avatarNodePath, avatarRadius, floorOffset, reach)
        return

    def setupWallSphere(self, bitmask, avatarRadius):
        self.avatarRadius = avatarRadius
        cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius)
        cSphereNode = CollisionNode('Flyer.cWallSphereNode')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        if config.GetBool('want-fluid-pusher', 0):
            self.pusher = CollisionHandlerFluidPusher()
        else:
            self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(cSphereNodePath, self.avatarNodePath)
        self.cWallSphereNodePath = cSphereNodePath

    def setupEventSphere(self, bitmask, avatarRadius):
        self.avatarRadius = avatarRadius
        cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75, self.avatarRadius * 1.04)
        cSphere.setTangible(0)
        cSphereNode = CollisionNode('Flyer.cEventSphereNode')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.event = CollisionHandlerEvent()
        self.event.addInPattern('enter%in')
        self.event.addOutPattern('exit%in')
        self.cEventSphereNodePath = cSphereNodePath

    def setupRay(self, bitmask, floorOffset, reach):
        cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0)
        cRayNode = CollisionNode('Flyer.cRayNode')
        cRayNode.addSolid(cRay)
        self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
        cRayNode.setFromCollideMask(bitmask)
        cRayNode.setIntoCollideMask(BitMask32.allOff())
        self.lifter = CollisionHandlerGravity()
        self.lifter.setLegacyMode(self._legacyLifter)
        self.lifter.setGravity(self.getGravity(0))
        self.lifter.addInPattern('%fn-enter-%in')
        self.lifter.addAgainPattern('%fn-again-%in')
        self.lifter.addOutPattern('%fn-exit-%in')
        self.lifter.setOffset(floorOffset)
        self.lifter.setReach(reach)
        self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath)

    def setupHeadSphere(self, avatarNodePath):
        collSphere = CollisionSphere(0, 0, 0, 1)
        collSphere.setTangible(1)
        collNode = CollisionNode('Flyer.cHeadCollSphere')
        collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask)
        collNode.setIntoCollideMask(BitMask32.allOff())
        collNode.addSolid(collSphere)
        self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode)
        self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0)
        self.headCollisionEvent = CollisionHandlerEvent()
        self.headCollisionEvent.addInPattern('%fn-enter-%in')
        self.headCollisionEvent.addOutPattern('%fn-exit-%in')
        base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent)

    def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius):
        cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75)
        cSphereNode = CollisionNode('Flyer.cFloorEventSphere')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.floorCollisionEvent = CollisionHandlerEvent()
        self.floorCollisionEvent.addInPattern('%fn-enter-%in')
        self.floorCollisionEvent.addAgainPattern('%fn-again-%in')
        self.floorCollisionEvent.addOutPattern('%fn-exit-%in')
        base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent)
        self.cFloorEventSphereNodePath = cSphereNodePath

    def deleteCollisions(self):
        GravityWalker.deleteCollisions(self)
        if self.cHeadSphereNodePath != None:
            base.cTrav.removeCollider(self.cHeadSphereNodePath)
            self.cHeadSphereNodePath.detachNode()
            self.cHeadSphereNodePath = None
            self.headCollisionsEvent = None
        if self.cFloorEventSphereNodePath != None:
            base.cTrav.removeCollider(self.cFloorEventSphereNodePath)
            self.cFloorEventSphereNodePath.detachNode()
            self.cFloorEventSphereNodePath = None
            self.floorCollisionEvent = None
        self.cRayNodePath.detachNode()
        del self.cRayNodePath
        self.cEventSphereNodePath.detachNode()
        del self.cEventSphereNodePath
        return

    def setCollisionsActive(self, active = 1):
        if self.collisionsActive != active:
            if self.cHeadSphereNodePath != None:
                base.cTrav.removeCollider(self.cHeadSphereNodePath)
                if active:
                    base.cTrav.addCollider(self.cHeadSphereNodePath, self.headCollisionEvent)
            if self.cFloorEventSphereNodePath != None:
                base.cTrav.removeCollider(self.cFloorEventSphereNodePath)
                if active:
                    base.cTrav.addCollider(self.cFloorEventSphereNodePath, self.floorCollisionEvent)
        GravityWalker.setCollisionsActive(self, active)
        return

    def enableAvatarControls(self):
        pass

    def disableAvatarControls(self):
        pass

    def handleAvatarControls(self, task):
        pass
Exemple #8
0
class Load():
    def __init__(self):
        # import leap motion
        self.leap = leapmotion.LeapMotion()
        # disable mouse control
        base.disableMouse()
        render.hide()
        self.inGame = True

        # menu music
        # taken from https://www.youtube.com/watch?v=2iEWbHJDlo4&list=PLzCxunOM5WFIudfMTgJzXkOE-xbVWrpIF&index=7
        self.starterMusic = loader.loadMusic(
            'musics/starterMenuBackground.ogg')
        self.starterMusic.setLoop(True)
        # taken form https://www.youtube.com/watch?v=I0vEzblcnPA&list=PLzCxunOM5WFIudfMTgJzXkOE-xbVWrpIF&index=18
        self.endMusic = loader.loadMusic('musics/endMusic.ogg')
        self.endMusic.setLoop(True)

        # game music from https://www.youtube.com/watch?v=mNFNOEi9QV4&list=PLzCxunOM5WFK7WGa3wGjlONp_9R66a2zz&index=8
        self.gameMusic = loader.loadMusic('musics/gameMusic.ogg')
        self.gameMusic.setLoop(True)

        # import flybot, enemy, door, chests, key, and player
        self.flyBot = FlyBot()
        self.player = player.Player(self.flyBot)
        self.enemies = []
        self.numbEnemies = 0
        keyChest = random.randint(0, 3)
        # self.key = Key(keyChest)
        self.door = Door(225, 190, self.flyBot)
        self.walls = []
        self.chests = []

    def startGame(self):
        # Load the map.
        self.environ = loader.loadModel("models/background_model")
        # Reparent the model to render.
        self.environ.reparentTo(render)
        # Apply scale and position transforms on the model.
        # image taken from http://motorbikes-passion.info/scary-dark-room.html
        myTexture = loader.loadTexture("models/backgroundtexture.jpg")
        self.environ.setTexGen(TextureStage.getDefault(),
                               TexGenAttrib.MWorldCubeMap)
        self.environ.setTexture(myTexture)
        self.environ.setScale(1, 1, 1)
        self.environ.setPos(0, 0, 0)
        self.environ.reparentTo(render)

        # random generate map
        self.numbWalls = 4
        walls = generateRoom([], self.numbWalls)
        # if random generation fails, input default map
        if walls == None:
            walls = [(120, 30, 0), (-100, 80, 90), (-130, -70, 0),
                     (50, -50, 90)]
        # load wall models in respective location
        for wall in walls:
            x, y, angle = wall
            newWall = Wall(x, y, angle)
            self.walls.append(newWall)

        # generate chests in random areas
        chests = generateChestLocation(walls)
        for chest in chests:
            x, y, chestNumb = chest
            newChest = Chest(self.player, self.flyBot, x, y, chestNumb)
            self.chests.append(newChest)

        # display player stats
        self.display = self.player.displayStats()

        # run collision settings
        base.cTrav = CollisionTraverser()
        # Set up collision for environment
        self.backgroundCollide = CollisionRay()
        self.backgroundNode = CollisionNode('backgroundCollider')
        self.backgroundNode.addSolid(self.backgroundCollide)
        self.backgroundNode.setFromCollideMask(CollideMask.bit(0))
        self.backgroundNode.setIntoCollideMask(CollideMask.allOff())
        self.backgroundCollider = self.environ.attachNewNode(
            self.backgroundNode)

        # call all functions that deal with collisions
        taskMgr.add(self.swordHitEnemy, 'killEnemy')
        self.wallCollisions()
        taskMgr.add(self.fireballHitPlayer, 'fireballHits')

        # load sound effects
        # sound taken from https://bigsoundbank.com/detail-0129-sword.html
        self.swordCut = loader.loadSfx('musics/0129.ogg')
        # sound taken from https://bigsoundbank.com/detail-0437-shot-beretta-m12-9-mm.html
        self.fireballHit = loader.loadSfx('musics/0437.ogg')

        # run quitGame
        self.quitGame()

        # Set up initial camera position
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.camera.reparentTo(self.flyBot.flyBot)
        # import player controls from player file
        self.playerControl = player.KeyboardControl(self.flyBot, self.chests,
                                                    self.door, self.walls,
                                                    self.player)

        # import leap motion control
        self.leapControl = player.swordControl(self.leap, self.player)
        taskMgr.add(self.leapControl.swingsword, 'swingsword')

        # spawn new enemies
        sec = 5 - self.player.atLevel
        taskMgr.doMethodLater(sec, self.spawnEnemies, 'createNewEnemy')

        # test enemy movements
        taskMgr.add(self.enemyMovements, 'enemyMovements')

        # Game AI
        AI = GameAI(self.enemies, self.flyBot)
        taskMgr.add(AI.makeDecision, 'enemyStateDetermination')

    # stop all tasks
    def stopGame(self):
        taskMgr.remove('checkGameState')
        taskMgr.remove('enemyStateDetermination')
        taskMgr.remove('enemyMovements')
        taskMgr.remove('createNewEnemy')
        taskMgr.remove('swingsword')
        taskMgr.remove('fireballHits')
        taskMgr.remove('killEnemy')
        taskMgr.remove("playerMove")
        taskMgr.remove('openChestOrDoor')
        taskMgr.remove('moveFireball')
        taskMgr.remove('fireFireballs')

    # allow keyboard exit
    def quitGame(self):
        textObject = OnscreenText(text='ESC to exit game',
                                  pos=(-0.25, -0.05),
                                  scale=0.05,
                                  parent=base.a2dTopRight)
        # The key esc will exit the game
        base.accept('escape', sys.exit)

    # create new enemies
    def spawnEnemies(self, task):
        if len(self.enemies) < 20:
            # default state is stay
            self.numbEnemies += 1
            newEnemy = enemy.Enemy(1, self.numbEnemies, self.player)
            self.enemies.append(newEnemy)
        task.delayTime += 1
        return task.again

    # moves the enemies towards the player
    def enemyMovements(self, task):
        for enemy in self.enemies:
            enemy.lookAtPlayer(self.flyBot)
            if enemy.state == 0:
                enemy.move(self.flyBot.flyBot)
            if enemy.state == 2:
                randomChest = random.randint(0, 3)
                doorOrChest = random.randint(
                    [self.door.door, self.chests[randomChest].chestModel])
                enemy.move(doorOrChest)
        return task.cont

    # Collision functions, called in init
    def wallCollisions(self):
        # Pusher so that the player cannot move past the walls
        self.playerPusher = CollisionHandlerPusher()
        base.cTrav.addCollider(self.flyBot.playerCollider, self.playerPusher)
        self.playerPusher.addCollider(self.flyBot.playerCollider,
                                      self.flyBot.flyBot)

        self.enemyPusher = CollisionHandlerPusher()
        for enemy in self.enemies:
            base.cTrav.addCollider(enemy.collider, self.enemyPusher)
            self.enemyPusher.addCollider(enemy.collider, enemy.enemyModel)

    def swordHitEnemy(self, task):
        # When the sword collides with enemy, enemy dies
        for enemy in self.enemies:
            self.playerKill = CollisionHandlerEvent()
            base.cTrav.addCollider(enemy.collider, self.playerKill)
            self.playerKill.addInPattern('%fn-into-%in')

            # perform the task
            self.kill = DirectObject()
            self.kill.accept('enemy' + str(enemy.numb) + '-into-swordCollider',
                             enemy.killEnemy)
            self.swordHit = DirectObject()
            self.swordHit.accept(
                'enemy' + str(enemy.numb) + '-into-swordCollider',
                self.swordHitSound)
            if not enemy.isAlive:
                self.enemies.remove(enemy)
        return task.cont

    # play the sound when the sword hits an ememy
    def swordHitSound(self, *args):
        if self.player.damage:
            self.swordCut.play()

    # create collision system for fireballs based on the location of the player
    # and the location of a given enemy
    def fireballHitPlayer(self, task):
        for enemy in self.enemies:
            if enemy.fireballFired.isLive:
                # When fireball collides with player, player health reduces
                playerX = self.flyBot.flyBot.getX()
                playerY = self.flyBot.flyBot.getY()
                margin = 5

                enemyH = math.sin(math.radians(enemy.enemyModel.getH()))
                fireballX = enemy.enemyModel.getX()
                fireballY = enemy.enemyModel.getY(
                ) + enemyH * enemy.fireballFired.fireball.getY()
                enemyY = enemy.enemyModel.getY()
                playerH = self.flyBot.flyBot.getH()

                if abs(fireballY) > 230 or abs(fireballX) > 230:
                    enemy.fireballFired.removeFireball(task)

                if (playerH > -45 and
                        playerH < 45) or (playerH > 135) or (playerH < -135):
                    if playerX - margin <= fireballX and playerX + margin >= fireballX:
                        if (abs(enemy.enemyModel.getH()) <= 45 and fireballY >= playerY) or\
                        (abs(enemy.enemyModel.getH()) >= 135 and fireballY <= playerY):
                            self.fireballHit.play()
                            self.player.changeStats(-5, 0)
                            enemy.fireballFired.removeFireball(task)

                else:
                    if playerY - margin <= fireballY and playerY + margin >= fireballY:
                        if (enemy.enemyModel.getH() <= 0 and fireballX >= playerX) or\
                            (enemy.enemyModel.getH() > 0 and fireballX <= playerX):
                            self.fireballHit.play()
                            self.player.changeStats(-5, 0)
                            enemy.fireballFired.removeFireball(task)

        return task.cont
class SmartCamera:
    UPDATE_TASK_NAME = 'update_smartcamera'
    notify = directNotify.newCategory('SmartCamera')

    def __init__(self):
        self.cTrav = CollisionTraverser('cam_traverser')
        base.pushCTrav(self.cTrav)
        self.cTrav.setRespectPrevTransform(1)
        self.default_pos = None
        self.parent = None
        self.initialized = False
        self.started = False
        self.camFloorRayNode = None
        self.ccRay2 = None
        self.ccRay2Node = None
        self.ccRay2NodePath = None
        self.ccRay2BitMask = None
        self.ccRay2MoveNodePath = None
        self.camFloorCollisionBroadcaster = None
        self.notify.debug('SmartCamera initialized!')
        return

    def lerpCameraFov(self, fov, time):
        taskMgr.remove('cam-fov-lerp-play')
        oldFov = base.camLens.getHfov()
        if abs(fov - oldFov) > 0.1:

            def setCamFov(fov):
                base.camLens.setMinFov(fov / (4.0 / 3.0))

            self.camLerpInterval = LerpFunctionInterval(setCamFov, fromData=oldFov, toData=fov, duration=time, name='cam-fov-lerp')
            self.camLerpInterval.start()

    def setCameraFov(self, fov):
        self.fov = fov
        if not (self.isPageDown or self.isPageUp):
            base.camLens.setMinFov(self.fov / (4.0 / 3.0))

    def initCameraPositions(self):
        camHeight = max(base.localAvatar.getHeight(), 3.0)
        nrCamHeight = base.localAvatar.getHeight()
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        self.firstPersonCamPos = Point3(0.0, 0.7, nrCamHeight * 5.0)
        scXoffset = 3.0
        scPosition = (Point3(scXoffset - 1, -10.0, camHeight + 5.0), Point3(scXoffset, 2.0, camHeight))
        self.cameraPositions = [
         (Point3(0.0, -9.0 * heightScaleFactor, camHeight),
          defLookAt,
          Point3(0.0, camHeight, camHeight * 4.0),
          Point3(0.0, camHeight, camHeight * -1.0),
          0),
         (
          Point3(0.0, 0.7, camHeight),
          defLookAt,
          Point3(0.0, camHeight, camHeight * 1.33),
          Point3(0.0, camHeight, camHeight * 0.66),
          1),
         (
          Point3(5.7 * heightScaleFactor, 7.65 * heightScaleFactor, camHeight + 2.0),
          Point3(0.0, 1.0, camHeight),
          Point3(0.0, 1.0, camHeight * 4.0),
          Point3(0.0, 1.0, camHeight * -1.0),
          0),
         (
          Point3(0.0, 8.65 * heightScaleFactor, camHeight),
          Point3(0.0, 1.0, camHeight),
          Point3(0.0, 1.0, camHeight * 4.0),
          Point3(0.0, 1.0, camHeight * -1.0),
          0),
         (
          Point3(0.0, -24.0 * heightScaleFactor, camHeight + 4.0),
          defLookAt,
          Point3(0.0, 1.5, camHeight * 4.0),
          Point3(0.0, 1.5, camHeight * -1.0),
          0),
         (
          Point3(0.0, -12.0 * heightScaleFactor, camHeight + 4.0),
          defLookAt,
          Point3(0.0, 1.5, camHeight * 4.0),
          Point3(0.0, 1.5, camHeight * -1.0),
          0)]

    def pageUp(self):
        if not base.localAvatar.avatarMovementEnabled:
            return
        if not self.isPageUp:
            self.isPageDown = 0
            self.isPageUp = 1
            self.lerpCameraFov(70, 0.6)
            self.setCameraPositionByIndex(self.cameraIndex)
        else:
            self.clearPageUpDown()

    def pageDown(self):
        if not base.localAvatar.avatarMovementEnabled:
            return
        if not self.isPageDown:
            self.isPageUp = 0
            self.isPageDown = 1
            self.lerpCameraFov(70, 0.6)
            self.setCameraPositionByIndex(self.cameraIndex)
        else:
            self.clearPageUpDown()

    def clearPageUpDown(self):
        if self.isPageDown or self.isPageUp:
            self.lerpCameraFov(self.fov, 0.6)
            self.isPageDown = 0
            self.isPageUp = 0
            self.setCameraPositionByIndex(self.cameraIndex)

    def nextCameraPos(self, forward):
        if not base.localAvatar.avatarMovementEnabled:
            return
        self.__cameraHasBeenMoved = 1
        if forward:
            self.cameraIndex += 1
            if self.cameraIndex > len(self.cameraPositions) - 1:
                self.cameraIndex = 0
        else:
            self.cameraIndex -= 1
            if self.cameraIndex < 0:
                self.cameraIndex = len(self.cameraPositions) - 1
        self.setCameraPositionByIndex(self.cameraIndex)

    def setCameraPositionByIndex(self, index):
        self.notify.debug('switching to camera position %s' % index)
        self.setCameraSettings(self.cameraPositions[index])

    def setCameraSettings(self, camSettings):
        self.setIdealCameraPos(camSettings[0])
        if self.isPageUp and self.isPageDown or not self.isPageUp and not self.isPageDown:
            self.__cameraHasBeenMoved = 1
            self.setLookAtPoint(camSettings[1])
        else:
            if self.isPageUp:
                self.__cameraHasBeenMoved = 1
                self.setLookAtPoint(camSettings[2])
            else:
                if self.isPageDown:
                    self.__cameraHasBeenMoved = 1
                    self.setLookAtPoint(camSettings[3])
                else:
                    self.notify.error('This case should be impossible.')
        self.__disableSmartCam = camSettings[4]
        if self.__disableSmartCam:
            self.putCameraFloorRayOnAvatar()
            self.cameraZOffset = 0.0

    def set_default_pos(self, pos):
        self.default_pos = pos

    def get_default_pos(self):
        return self.default_pos

    def set_parent(self, parent):
        self.parent = parent

    def get_parent(self):
        return self.parent

    def getVisibilityPoint(self):
        return Point3(0.0, 0.0, base.localAvatar.getHeight())

    def setLookAtPoint(self, la):
        self.__curLookAt = Point3(la)

    def getLookAtPoint(self):
        return Point3(self.__curLookAt)

    def setIdealCameraPos(self, pos):
        self.__idealCameraPos = Point3(pos)
        self.updateSmartCameraCollisionLineSegment()

    def getIdealCameraPos(self):
        return Point3(self.__idealCameraPos)

    def getCompromiseCameraPos(self):
        if self.__idealCameraObstructed == 0:
            compromisePos = self.getIdealCameraPos()
        else:
            visPnt = self.getVisibilityPoint()
            idealPos = self.getIdealCameraPos()
            distance = Vec3(idealPos - visPnt).length()
            ratio = self.closestObstructionDistance / distance
            compromisePos = idealPos * ratio + visPnt * (1 - ratio)
            liftMult = 1.0 - ratio * ratio
            compromisePos = Point3(compromisePos[0], compromisePos[1], compromisePos[2] + base.localAvatar.getHeight() * 0.4 * liftMult)
        compromisePos.setZ(compromisePos[2] + self.cameraZOffset)
        return compromisePos

    def updateSmartCameraCollisionLineSegment(self):
        pointB = self.getIdealCameraPos()
        pointA = self.getVisibilityPoint()
        vectorAB = Vec3(pointB - pointA)
        lengthAB = vectorAB.length()
        if lengthAB > 0.001:
            self.ccLine.setPointA(pointA)
            self.ccLine.setPointB(pointB)

    def initializeSmartCamera(self):
        self.__idealCameraObstructed = 0
        self.closestObstructionDistance = 0.0
        self.cameraIndex = 0
        self.cameraPositions = []
        self.auxCameraPositions = []
        self.cameraZOffset = 0.0
        self.setGeom(render)
        self.__onLevelGround = 0
        self.__camCollCanMove = 0
        self.__disableSmartCam = 0
        self.initializeSmartCameraCollisions()
        self._smartCamEnabled = False
        self.isPageUp = 0
        self.isPageDown = 0
        self.fov = CIGlobals.DefaultCameraFov

    def enterFirstPerson(self):
        self.stop_smartcamera()
        if hasattr(self.get_parent(), 'toon_head'):
            head = self.get_parent().toon_head
            camera.reparentTo(head)
        camera.setPos(0, -0.35, 0)
        camera.setHpr(0, 0, 0)

    def exitFirstPerson(self):
        self.initialize_smartcamera()
        self.initialize_smartcamera_collisions()
        self.start_smartcamera()

    def putCameraFloorRayOnAvatar(self):
        self.camFloorRayNode.setPos(base.localAvatar, 0, 0, 5)

    def putCameraFloorRayOnCamera(self):
        self.camFloorRayNode.setPos(self.ccSphereNodePath, 0, 0, 0)

    def recalcCameraSphere(self):
        nearPlaneDist = base.camLens.getNear()
        hFov = base.camLens.getHfov()
        vFov = base.camLens.getVfov()
        hOff = nearPlaneDist * math.tan(deg2Rad(hFov / 2.0))
        vOff = nearPlaneDist * math.tan(deg2Rad(vFov / 2.0))
        camPnts = [Point3(hOff, nearPlaneDist, vOff),
         Point3(-hOff, nearPlaneDist, vOff),
         Point3(hOff, nearPlaneDist, -vOff),
         Point3(-hOff, nearPlaneDist, -vOff),
         Point3(0.0, 0.0, 0.0)]
        avgPnt = Point3(0.0, 0.0, 0.0)
        for camPnt in camPnts:
            avgPnt = avgPnt + camPnt

        avgPnt = avgPnt / len(camPnts)
        sphereRadius = 0.0
        for camPnt in camPnts:
            dist = Vec3(camPnt - avgPnt).length()
            if dist > sphereRadius:
                sphereRadius = dist

        avgPnt = Point3(avgPnt)
        self.ccSphereNodePath.setPos(avgPnt)
        self.ccSphereNodePath2.setPos(avgPnt)
        self.ccSphere.setRadius(sphereRadius)

    def setGeom(self, geom):
        self.__geom = geom

    def initializeSmartCameraCollisions(self):
        if self.initialized:
            return
        self.ccTrav = CollisionTraverser('LocalAvatar.ccTrav')
        self.ccLine = CollisionSegment(0.0, 0.0, 0.0, 1.0, 0.0, 0.0)
        self.ccLineNode = CollisionNode('ccLineNode')
        self.ccLineNode.addSolid(self.ccLine)
        self.ccLineNodePath = base.localAvatar.attachNewNode(self.ccLineNode)
        self.ccLineBitMask = CIGlobals.CameraBitmask
        self.ccLineNode.setFromCollideMask(self.ccLineBitMask)
        self.ccLineNode.setIntoCollideMask(BitMask32.allOff())
        self.camCollisionQueue = CollisionHandlerQueue()
        self.ccTrav.addCollider(self.ccLineNodePath, self.camCollisionQueue)
        self.ccSphere = CollisionSphere(0, 0, 0, 1)
        self.ccSphereNode = CollisionNode('ccSphereNode')
        self.ccSphereNode.addSolid(self.ccSphere)
        self.ccSphereNodePath = base.camera.attachNewNode(self.ccSphereNode)
        self.ccSphereNode.setFromCollideMask(CIGlobals.CameraBitmask)
        self.ccSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.camPusher = CollisionHandlerPusher()
        self.camPusher.addCollider(self.ccSphereNodePath, base.camera)
        self.camPusher.setCenter(base.localAvatar)
        self.ccPusherTrav = CollisionTraverser('LocalAvatar.ccPusherTrav')
        self.ccSphere2 = self.ccSphere
        self.ccSphereNode2 = CollisionNode('ccSphereNode2')
        self.ccSphereNode2.addSolid(self.ccSphere2)
        self.ccSphereNodePath2 = base.camera.attachNewNode(self.ccSphereNode2)
        self.ccSphereNode2.setFromCollideMask(CIGlobals.CameraBitmask)
        self.ccSphereNode2.setIntoCollideMask(BitMask32.allOff())
        self.camPusher2 = CollisionHandlerPusher()
        self.ccPusherTrav.addCollider(self.ccSphereNodePath2, self.camPusher2)
        self.camPusher2.addCollider(self.ccSphereNodePath2, base.camera)
        self.camPusher2.setCenter(base.localAvatar)
        self.camFloorRayNode = base.localAvatar.attachNewNode('camFloorRayNode')
        self.ccRay = CollisionRay(0.0, 0.0, 0.0, 0.0, 0.0, -1.0)
        self.ccRayNode = CollisionNode('ccRayNode')
        self.ccRayNode.addSolid(self.ccRay)
        self.ccRayNodePath = self.camFloorRayNode.attachNewNode(self.ccRayNode)
        self.ccRayBitMask = CIGlobals.FloorBitmask
        self.ccRayNode.setFromCollideMask(self.ccRayBitMask)
        self.ccRayNode.setIntoCollideMask(BitMask32.allOff())
        self.ccTravFloor = CollisionTraverser('LocalAvatar.ccTravFloor')
        self.camFloorCollisionQueue = CollisionHandlerQueue()
        self.ccTravFloor.addCollider(self.ccRayNodePath, self.camFloorCollisionQueue)
        self.ccTravOnFloor = CollisionTraverser('LocalAvatar.ccTravOnFloor')
        self.ccRay2 = CollisionRay(0.0, 0.0, 0.0, 0.0, 0.0, -1.0)
        self.ccRay2Node = CollisionNode('ccRay2Node')
        self.ccRay2Node.addSolid(self.ccRay2)
        self.ccRay2NodePath = self.camFloorRayNode.attachNewNode(self.ccRay2Node)
        self.ccRay2BitMask = CIGlobals.FloorBitmask
        self.ccRay2Node.setFromCollideMask(self.ccRay2BitMask)
        self.ccRay2Node.setIntoCollideMask(BitMask32.allOff())
        self.ccRay2MoveNodePath = hidden.attachNewNode('ccRay2MoveNode')
        self.camFloorCollisionBroadcaster = CollisionHandlerFloor()
        self.camFloorCollisionBroadcaster.setInPattern('on-floor')
        self.camFloorCollisionBroadcaster.setOutPattern('off-floor')
        self.camFloorCollisionBroadcaster.addCollider(self.ccRay2NodePath, self.ccRay2MoveNodePath)
        self.cTrav.addCollider(self.ccRay2NodePath, self.camFloorCollisionBroadcaster)
        self.initialized = True

    def deleteSmartCameraCollisions(self):
        del self.ccTrav
        del self.ccLine
        del self.ccLineNode
        self.ccLineNodePath.removeNode()
        del self.ccLineNodePath
        del self.camCollisionQueue
        del self.ccRay
        del self.ccRayNode
        self.ccRayNodePath.removeNode()
        del self.ccRayNodePath
        del self.ccRay2
        del self.ccRay2Node
        self.ccRay2NodePath.removeNode()
        del self.ccRay2NodePath
        self.ccRay2MoveNodePath.removeNode()
        del self.ccRay2MoveNodePath
        del self.ccTravOnFloor
        del self.ccTravFloor
        del self.camFloorCollisionQueue
        del self.camFloorCollisionBroadcaster
        del self.ccSphere
        del self.ccSphereNode
        self.ccSphereNodePath.removeNode()
        del self.ccSphereNodePath
        del self.camPusher
        del self.ccPusherTrav
        del self.ccSphere2
        del self.ccSphereNode2
        self.ccSphereNodePath2.removeNode()
        del self.ccSphereNodePath2
        del self.camPusher2
        self.initialized = False

    def startUpdateSmartCamera(self):
        if self.started:
            return
        self.__floorDetected = 0
        self.__cameraHasBeenMoved = 1
        self.recalcCameraSphere()
        self.__instantaneousCamPos = camera.getPos()
        self.cTrav.addCollider(self.ccSphereNodePath, self.camPusher)
        self.ccTravOnFloor.addCollider(self.ccRay2NodePath, self.camFloorCollisionBroadcaster)
        self.__disableSmartCam = 0
        self.__lastPosWrtRender = camera.getPos(render) + 1
        self.__lastHprWrtRender = camera.getHpr(render) + 1
        taskName = base.localAvatar.taskName('updateSmartCamera')
        taskMgr.remove(taskName)
        taskMgr.add(self.updateSmartCamera, taskName, priority=47)
        self.started = True

    def stopUpdateSmartCamera(self):
        self.cTrav.removeCollider(self.ccSphereNodePath)
        self.ccTravOnFloor.removeCollider(self.ccRay2NodePath)
        taskName = base.localAvatar.taskName('updateSmartCamera')
        taskMgr.remove(taskName)
        camera.setPos(self.getIdealCameraPos())
        self.started = False

    def updateSmartCamera(self, task):
        if not self.__camCollCanMove and not self.__cameraHasBeenMoved:
            if self.__lastPosWrtRender == camera.getPos(render):
                if self.__lastHprWrtRender == camera.getHpr(render):
                    return Task.cont
        self.__cameraHasBeenMoved = 0
        self.__lastPosWrtRender = camera.getPos(render)
        self.__lastHprWrtRender = camera.getHpr(render)
        self.__idealCameraObstructed = 0
        if not self.__disableSmartCam:
            self.ccTrav.traverse(self.__geom)
            if self.camCollisionQueue.getNumEntries() > 0:
                try:
                    self.camCollisionQueue.sortEntries()
                    self.handleCameraObstruction(self.camCollisionQueue.getEntry(0))
                except AssertionError:
                    pass

            if not self.__onLevelGround:
                self.handleCameraFloorInteraction()
        if not self.__idealCameraObstructed:
            self.nudgeCamera()
        if not self.__disableSmartCam:
            self.ccPusherTrav.traverse(self.__geom)
            self.putCameraFloorRayOnCamera()
        self.ccTravOnFloor.traverse(self.__geom)
        return Task.cont

    def positionCameraWithPusher(self, pos, lookAt):
        camera.setPos(pos)
        self.ccPusherTrav.traverse(self.__geom)
        camera.lookAt(lookAt)

    def nudgeCamera(self):
        CLOSE_ENOUGH = 0.1
        curCamPos = self.__instantaneousCamPos
        curCamHpr = camera.getHpr()
        targetCamPos = self.getCompromiseCameraPos()
        targetCamLookAt = self.getLookAtPoint()
        posDone = 0
        if Vec3(curCamPos - targetCamPos).length() <= CLOSE_ENOUGH:
            camera.setPos(targetCamPos)
            posDone = 1
        camera.setPos(targetCamPos)
        camera.lookAt(targetCamLookAt)
        targetCamHpr = camera.getHpr()
        hprDone = 0
        if Vec3(curCamHpr - targetCamHpr).length() <= CLOSE_ENOUGH:
            hprDone = 1
        if posDone and hprDone:
            return
        lerpRatio = 0.15
        lerpRatio = 1 - pow(1 - lerpRatio, globalClock.getDt() * 30.0)
        self.__instantaneousCamPos = targetCamPos * lerpRatio + curCamPos * (1 - lerpRatio)
        if self.__disableSmartCam or not self.__idealCameraObstructed:
            newHpr = targetCamHpr * lerpRatio + curCamHpr * (1 - lerpRatio)
        else:
            newHpr = targetCamHpr
        camera.setPos(self.__instantaneousCamPos)
        camera.setHpr(newHpr)

    def popCameraToDest(self):
        newCamPos = self.getCompromiseCameraPos()
        newCamLookAt = self.getLookAtPoint()
        self.positionCameraWithPusher(newCamPos, newCamLookAt)
        self.__instantaneousCamPos = camera.getPos()

    def handleCameraObstruction(self, camObstrCollisionEntry):
        collisionPoint = camObstrCollisionEntry.getSurfacePoint(self.ccLineNodePath)
        collisionVec = Vec3(collisionPoint - self.ccLine.getPointA())
        distance = collisionVec.length()
        self.__idealCameraObstructed = 1
        self.closestObstructionDistance = distance
        self.popCameraToDest()

    def handleCameraFloorInteraction(self):
        self.putCameraFloorRayOnCamera()
        self.ccTravFloor.traverse(self.__geom)
        if self.__onLevelGround:
            return
        if self.camFloorCollisionQueue.getNumEntries() == 0:
            return
        self.camFloorCollisionQueue.sortEntries()
        camObstrCollisionEntry = self.camFloorCollisionQueue.getEntry(0)
        camHeightFromFloor = camObstrCollisionEntry.getSurfacePoint(self.ccRayNodePath)[2]
        self.cameraZOffset = camera.getPos()[2] + camHeightFromFloor
        if self.cameraZOffset < 0:
            self.cameraZOffset = 0
        if self.__floorDetected == 0:
            self.__floorDetected = 1
            self.popCameraToDest()
Exemple #10
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # Set the background color to black
        self.win.setClearColor((0, 0, 0, 1))

        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "back": 0, "cam-left": 0, "cam-right": 0}

        # Post the instructions
        self.title = addTitle(
            "Adventurer: 3rd Person File Manager (in progress)")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Arrows]: Angle Camera")
        self.inst3 = addInstructions(0.18, "[WASD]: Move")
        # 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)

        #loader.unload_model
        startPos = Point3(0,0,0)#self.environ.find("**/start_point").getPos()
        
        # Setup controls
        self.keys = {}
        for key in ['arrow_left', 'arrow_right', 'arrow_up', 'arrow_down',
                    'a', 'd', 'w', 's']:
            self.keys[key] = 0
            self.accept(key, self.push_key, [key, 1])
            self.accept('shift-%s' % key, self.push_key, [key, 1])
            self.accept('%s-up' % key, self.push_key, [key, 0])
        #self.accept('f', self.toggleWireframe)
        #self.accept('x', self.toggle_xray_mode)
        #self.accept('b', self.toggle_model_bounds)
        self.accept('escape', __import__('sys').exit, [0])
        self.disableMouse()

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

        #insert test features
        #addCube(models, render, startPos + (0, 1, 0.5), 0.5)
        #addWall(models, render, startPos + (0, 1, 0.5), 30, 0.2)
        addDir(render, startPos + (0, 1, 0.5))
        
        # Game state variables
        self.isMoving = False

        # Set up the camera
        self.disableMouse()
        lens = PerspectiveLens()
        lens.setFov(60)
        lens.setNear(0.01)
        lens.setFar(1000.0)
        self.cam.node().setLens(lens)
        self.camera.setPos(startPos)
        self.heading = -95.0
        self.pitch = 0.0

        # Add collision to keept he camera in the room
        cn = CollisionNode('camera')
        cn.addSolid(CollisionSphere(0, 0, 0, 0.5))
        camColl = self.camera.attachNewNode(cn)
        self.cTrav = CollisionTraverser('camera traverser')
        self.camGroundHandler = CollisionHandlerPusher()
        self.camGroundHandler.addCollider(camColl, NodePath(self.camera))
        self.cTrav.addCollider(camColl, self.camGroundHandler)

        # Makes colliding objects show up 
        self.cTrav.showCollisions(render)
        
        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))


    def push_key(self, key, value):
        """Stores a value associated with a key."""
        self.keys[key] = value

    def update(self, task):
        """Updates the camera based on the keyboard input. Once this is
        done, then the CellManager's update function is called."""
        posStart = self.camera.getPos()
        delta = globalClock.getDt()
        move_x = delta * SPEED_MOVE * -self.keys['a'] + delta * SPEED_MOVE * self.keys['d']
        move_z = delta * SPEED_MOVE * self.keys['s'] + delta * SPEED_MOVE * -self.keys['w']
        self.camera.setHpr(self.heading, 0, 0)
        self.camera.setPos(self.camera, move_x, -move_z, 0)
        self.heading += (delta * 90 * self.keys['arrow_left'] +
                         delta * 90 * -self.keys['arrow_right'])
        self.pitch += (delta * 90 * self.keys['arrow_up'] +
                       delta * 90 * -self.keys['arrow_down'])
        self.camera.setHpr(self.heading, self.pitch, 0)

        # for entry in self.camGroundHandler.getEntries():
        #     if entry.getFromNode().getName() == "camera":
        #         print "Collision", posStart, self.camera.getPos()
        #         self.camera.setPos(posStart)
        #         break
        
        return task.cont
Exemple #11
0
class Player():
    def __init__(self, camera, accept, render, loader, maxJPHeight):
        #initial variables and sounds

        self.developer = True  # Developer tools (building tools) will be accessible if this is turned on.
        self.gameMode = self.mode0  # the current playerUpdate function that is in use
        # self.playerModeParameters = () # the parameters being fed into the function above.
        self.groundContact = False  # if the player is on the ground or a surface, gravity will not pull the player below the surface
        self.jetPack_energy = 100
        self.maximumHeight = maxJPHeight  # maximum height in which the jetpack can fly to, this is dependent on the map loaded.
        self.jetPack_AUDIO = loader.loadSfx("assets/base/sounds/jetpack2.wav")
        self.jetPack_AUDIO.setLoop(True)
        self.vertical_velocity = 0  # Current Z velocity, positive = Upwards.
        self.z_velocity = 0  # Current Y velocity
        self.x_velocity = 0
        self.movingZ = False
        self.movingX = False

        #initiate GUI
        self.HUD = GUI()
        self.playerHolder = render.attachNewNode('player')

        # camera control - Hiding mouse and using it to rotate the camera
        props = WindowProperties()
        props.setCursorHidden(True)
        props.setMouseMode(WindowProperties.M_relative)
        base.win.requestProperties(props)

        # PLAYER MODEL SCENE GRAPH
        self.thirdPersonCamera_ZOOM = -50  # initial distance of third person camera.
        self.character = loader.loadModel(
            'assets/base/models/playerModel/player.bam')
        self.toggleFPCam = False  # Whether first person camera is on, this is initially off.
        self.character.setPos(0, 0, 0)
        self.character.reparentTo(self.playerHolder)
        self.playerBase = self.playerHolder.attachNewNode('camParent')
        self.thirdPersonNode = self.playerBase.attachNewNode('thirdPersonCam')
        camera.reparentTo(self.thirdPersonNode)
        self.mouseSeconds = []
        self.playerHolder.setScale(4)
        self.monitor = loader.loadModel(
            'assets/base/models/faces/playerMonitor.bam')
        self.monitor.reparentTo(self.playerHolder)
        self.cTrav = CollisionTraverser()

        # Horizontal collisions
        self.pusher = CollisionHandlerPusher()
        self.pusher.horizontal = True
        self.colliderNode = CollisionNode("player")
        self.colliderNode.addSolid(CollisionSphere(0, 0, 0, 2))
        self.colliderNode.setFromCollideMask(CollideMask.bit(1))
        self.colliderNode.setFromCollideMask(CollideMask.bit(0))
        self.colliderNode.setIntoCollideMask(BitMask32.allOff())
        collider = self.playerHolder.attachNewNode(self.colliderNode)
        collider.show()
        self.pusher.addCollider(collider, self.playerHolder)
        self.cTrav.addCollider(collider, self.pusher)

        # Vertical collisions - Downwards
        self.groundRay = CollisionRay()
        self.groundRay.setDirection(0, 0, -1)
        self.groundRayCol = CollisionNode('playerRay')
        self.groundRayCol.addSolid(self.groundRay)
        self.groundRayCol.setFromCollideMask(CollideMask.bit(1))
        self.groundRayCol.setIntoCollideMask(CollideMask.allOff())
        self.groundColNp = self.playerHolder.attachNewNode(self.groundRayCol)
        self.groundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.groundColNp, self.groundHandler)

        # Third Person Camera Collision
        self.cameraRay = CollisionSegment()
        self.cameraRayNode = CollisionNode('camerRay')
        self.cameraRayNode.addSolid(self.cameraRay)
        self.cameraRayNodePath = render.attachNewNode(self.cameraRayNode)
        self.cameraCollisionHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.cameraRayNodePath,
                               self.cameraCollisionHandler)

        # Vertical collisions - Upwards
        self.upwardsRay = CollisionRay()
        self.upwardsRay.setDirection(0, 0, 1)
        self.upwardsRayCol = CollisionNode('playerupRay')
        self.upwardsRayCol.addSolid(self.upwardsRay)
        self.upwardsRayCol.setFromCollideMask(CollideMask.bit(1))
        self.upwardsRayCol.setIntoCollideMask(CollideMask.allOff())
        self.upwardsColNp = self.playerHolder.attachNewNode(self.upwardsRayCol)
        self.upwardsHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.upwardsColNp, self.upwardsHandler)
        #self.cTrav.showCollisions(render)

        if self.developer == True:
            self.tool = buildingTool(
                "newbuildings", self.playerHolder, loader,
                accept)  # Load up building tool if developer modee is on.

        #self.setupLighting() # light
        #initial position
        self.playerHolder.setPos(45178.3, 43109.3, 0)
        self.keyMap = {
            "left": False,
            "right": False,
            "forward": False,
            "backwards": False,
            "change_camera": False,
            "leftClick": False,
            "space": False,
            "p": False,
            "scrollup": False,
            "scrolldown": False
        }

        accept("escape", sys.exit)
        accept("w", self.updateKey, ["forward", True])  #
        accept("w-up", self.updateKey, ["forward", False])

        accept("a", self.updateKey, ["left", True])
        accept("a-up", self.updateKey, ["left", False])

        accept("s", self.updateKey, ["backwards", True])
        accept("s-up", self.updateKey, ["backwards", False])

        accept("d", self.updateKey, ["right", True])
        accept("d-up", self.updateKey, ["right", False])

        accept("c", self.updateKey, ["change_camera", True])

        accept("wheel_up", self.updateKey, ["scrollup", True])

        accept("wheel_down", self.updateKey, ["scrolldown", True])

        accept("p", self.updateKey, ["p", True])
        accept("p-up", self.updateKey, ["p", False])

        accept("space", self.updateKey, ["space", True])
        accept("space-up", self.updateKey, ["space", False])

        self.playerMode = playerModes(
            self.playerBase, self.playerHolder, self.character,
            self.vertical_velocity, self.z_velocity, self.x_velocity,
            self.keyMap, self.monitor, self.thirdPersonNode,
            self.jetPack_energy, self.jetPack_AUDIO,
            self.thirdPersonCamera_ZOOM, self.toggleFPCam, self.HUD,
            self.cTrav, self.groundHandler, self.upwardsHandler,
            self.maximumHeight)

    def playerUpdate(self, task):  # our UPDATE TASK
        self.gameMode()
        return task.cont

    def updateKey(self, key, value):
        self.keyMap[key] = value
        if key == "change_camera":
            self.changeCamera()
        self.scrollFactor = 10
        if key == "scrollup":  # third person zoom in/out
            self.thirdPersonCamera_ZOOM += self.scrollFactor
        if key == "scrolldown":
            self.thirdPersonCamera_ZOOM -= self.scrollFactor

    def changeCamera(self):  # Toggle first person camera.
        if self.toggleFPCam == False:
            self.toggleFPCam = True
        else:
            self.toggleFPCam = False

    def recenterMouse(self):
        base.win.movePointer(0, int(base.win.getProperties().getXSize() / 2),
                             int(base.win.getProperties().getYSize() / 2))

    def setupLighting(self):
        plight = PointLight('plight')
        plight.setColor((1, 1, 1, 1))
        plnp = self.playerHolder.attachNewNode(plight)
        plnp.setPos(0, 1, 7)
        render.setLight(plnp)

# PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER

#   MODE 0
# Mode 0 is the default update mode, it allows WASD movement,
# mouse controlled camera rotations, first person and third
# person switching, it also has GUI display and player physics.

    def mode0(self):

        #THIRD PERSON CAMERA COLLISION

        # print("thirdpersonnode")
        # print(self.playerBase.getHpr())
        # print("pb")
        # print(self.character.getHpr())

        deltaTime = globalClock.getDt()
        self.movingZ = False
        self.movingX = False
        self.walkConstant = 25
        self.rotateConstant = 750

        # Keyboard controls
        # LEVITATION STUFF (FORMERLY CALLED JETPACK)

        if self.keyMap["space"] and self.jetPack_energy > 0:
            jetpack = 0.00001 * ((
                (self.playerHolder.getZ()) - self.maximumHeight)**2) + 9.81
            self.playerHolder.setZ(self.playerBase, jetpack)
            self.jetPack_energy -= 15 * deltaTime
            self.walkConstant = 70
            self.jetPack_AUDIO.play()
        else:
            self.jetPack_AUDIO.stop()
        if self.jetPack_energy < 100:
            self.jetPack_energy += 10 * deltaTime
        if self.jetPack_energy > 100:
            self.jetPack_energy = 100

        self.HUD.jetpackStatus.text = "Levitation Battery: " + str(
            int(self.jetPack_energy)) + "%"

        if (self.keyMap["forward"]
                or self.keyMap["backwards"]) and (self.keyMap["right"]
                                                  or self.keyMap["left"]):
            self.walkConstant = int(((self.walkConstant**2) / 2)**0.5)

        # WASD MOVEMENT
        if self.keyMap["forward"]:
            self.monitor.setH(self.playerBase.getH() - 90)
            self.movingZ = True
            self.z_velocity += 5
            if self.z_velocity > self.walkConstant:
                self.z_velocity = self.walkConstant

        if self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() - 180)
            self.movingX = True
            self.x_velocity += 5
            if self.x_velocity > self.walkConstant:
                self.x_velocity = self.walkConstant
        if self.keyMap["p"]:
            print(self.playerHolder.getPos())
            print(self.thirdPersonCamera_ZOOM)
            self.gameMode = self.mode1
        if self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH())
            self.movingX = True
            self.x_velocity -= 5
            if self.x_velocity < -self.walkConstant:
                self.x_velocity = -self.walkConstant
        if self.keyMap["backwards"]:
            self.monitor.setH(self.playerBase.getH() + 90)
            self.movingZ = True
            self.z_velocity -= 20
            if self.z_velocity < -self.walkConstant:
                self.z_velocity = -self.walkConstant

        if self.movingZ == False:
            if self.z_velocity <= 7 or (
                    self.z_velocity >= -5
                    and self.z_velocity < 0):  # Shaking bug fix
                self.z_velocity = 0
            if self.z_velocity > 0:
                self.z_velocity -= 10
            elif self.z_velocity < 0:
                self.z_velocity += 10
        if self.movingX == False:
            if self.x_velocity <= 5 or (
                    self.x_velocity >= -5
                    and self.x_velocity < 0):  # Shaking bug fix
                self.x_velocity = 0
            if self.x_velocity > 0:
                self.x_velocity -= 10
            elif self.x_velocity < 0:
                self.x_velocity += 10
        # MONITOR HEADINGS FOR DOUBLE INPUT
        if self.keyMap["forward"] and self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() - 135)
        elif self.keyMap["forward"] and self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH() - 45)
        elif self.keyMap["backwards"] and self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH() + 45)
        elif self.keyMap["backwards"] and self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() + 135)

        # third person camera control
        if (self.toggleFPCam == False):  # third person camera controls
            if (base.mouseWatcherNode.hasMouse() == True):
                mouseposition = base.mouseWatcherNode.getMouse()
                self.thirdPersonNode.setP(mouseposition.getY() * 30)
                self.playerBase.setH(mouseposition.getX() * -50)
                if (mouseposition.getX() < 0.1
                        and mouseposition.getX() > -0.1):
                    self.playerBase.setH(self.playerBase.getH())

            if self.thirdPersonNode.getP() > 90:
                self.recenterMouse()
                self.thirdPersonNode.setP(90)  # TRACK MOUSE
            elif self.thirdPersonNode.getP() < -90:
                self.recenterMouse()
                self.thirdPersonNode.setP(-90)
            if self.thirdPersonCamera_ZOOM > -20:  # validate zoom
                self.thirdPersonCamera_ZOOM = -20
            elif self.thirdPersonCamera_ZOOM < -390:
                self.thirdPersonCamera_ZOOM = -390
        # CAMERA STUFF
        # FIRST PERSON CAMERA
        if self.toggleFPCam:  # first person camera controls
            camera.setPos(self.character.getPos())  # 0,-50,-10
            camera.setZ(camera.getZ() + 6)
            self.playerHolder.hide()
            if (base.mouseWatcherNode.hasMouse() == True):
                mouseposition = base.mouseWatcherNode.getMouse()
                camera.setP(mouseposition.getY() * 20)
                self.playerBase.setH(mouseposition.getX() * -50)
                if (mouseposition.getX() < 0.1
                        and mouseposition.getX() > -0.1):
                    self.playerBase.setH(self.playerBase.getH())
            if camera.getP() > 90:
                self.recenterMouse()
                camera.setP(90)  # TRACK MOUSE
            elif camera.getP() < -90:
                self.recenterMouse()
                camera.setP(-90)
        else:  # takes out of first person perspective if toggleFPS is turned off.
            self.playerHolder.show()
            camera.setPos(0, self.thirdPersonCamera_ZOOM, 0)  # 0,-50,-4
            camera.lookAt(self.character)
        # movement updates
        self.playerHolder.setY(self.playerBase, (self.z_velocity * deltaTime))
        self.playerHolder.setX(self.playerBase, (self.x_velocity * deltaTime))

        # forward/backward rolling
        axis = self.playerBase.getQuat().getRight()
        angle = (self.z_velocity * deltaTime * -8)
        quat = Quat()
        quat.setFromAxisAngle(angle, axis)
        newVec = self.character.getQuat() * quat
        # print(newVec.getHpr())
        self.character.setQuat(newVec)

        # sideways rolling
        axis = self.playerBase.getQuat().getForward()
        angle = (self.x_velocity * deltaTime * 8)
        quat = Quat()
        quat.setFromAxisAngle(angle, axis)
        newVec = self.character.getQuat() * quat
        # print(self.playerBase.getPos())
        self.character.setQuat(newVec)
        self.cameraRay.setPointA(self.playerBase.getPos())
        if camera.getPos() != (0, 0, 0):
            self.cameraRay.setPointB(camera.getPos(base.render))

        self.cTrav.traverse(render)

        # checking for camera collisions
        entries = list(self.cameraCollisionHandler.entries)
        for entry in entries:
            if str(entry.getIntoNodePath())[:19] != "render/worldTerrain":
                #camera.setPos(entry.getSurfacePoint(self.thirdPersonNode))
                self.thirdPersonCamera_ZOOM += 1

        # if len(entries) > 0:
        #     if (self.playerHolder.getZ() < entries[-1].getSurfacePoint(render).getZ() + 8):
        #         self.playerHolder.setZ(entries[-1].getSurfacePoint(render).getZ() + 8)
        #         self.vertical_velocity = 0

        # checking for collisions - downwards
        entries = list(self.groundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        self.performGravity = True
        if self.performGravity == True:
            self.vertical_velocity -= (deltaTime * 9.81)
            if self.vertical_velocity <= -15:
                self.vertical_velocity = -15
            self.playerHolder.setPos(self.playerHolder,
                                     Vec3(0, 0,
                                          self.vertical_velocity))  # Gravity
        if len(entries) > 0:
            if (self.playerHolder.getZ() <
                    entries[-1].getSurfacePoint(render).getZ() + 8):
                self.playerHolder.setZ(
                    entries[-1].getSurfacePoint(render).getZ() + 8)
                self.vertical_velocity = 0

        # checking for collisions - upwards
        entries = list(self.upwardsHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        if len(entries) > 0:
            for entry in entries:
                if (self.playerHolder.getZ() >
                        entry.getSurfacePoint(render).getZ() - 70):
                    self.playerHolder.setZ(
                        entry.getSurfacePoint(render).getZ() - 130)

    # PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER
    #   MODE 1
    # Mode 1 is a test update loop used to test player loop switching.
    # it simply freezes the controls.

    def mode1(self):
        self.playerHolder.hide()
        self.playerHolder.setHpr(0, 0, 0)
        if self.keyMap["backwards"]:
            self.playerHolder.show()
            self.gameMode = self.mode0
Exemple #12
0
class PlayerController(DirectObject):
    
    #-----------------
    # Initialization
    #-----------------
    
    def __init__(self, engine, environment):
        self.engine = engine
        self.players = {}
        self.environment = environment
        self.inputQueue = deque()
        self.collisionDummy = CollisionDummy()
        self.inputPollWait = 0
        self.playerCollisionHandler = CollisionHandlerPusher()
        self.playerCollisionHandler.addCollider(self.collisionDummy.GetCollisionNode(), self.collisionDummy.GetNode())
        self.playerCollisionTraverser = CollisionTraverser('playerCollisionTraverser')
        self.playerCollisionTraverser.addCollider(self.collisionDummy.GetCollisionNode(), self.playerCollisionHandler)
        #self.playerCollisionTraverser.showCollisions(render)
        
        self.LoadServerPosDebug()
        self.LoadMyself()
        
        self.accept(ViewModeChangeEvent.EventName, self.OnViewModeChange)
        self.accept(SelectedItemChangeEvent.EventName, self.OnSelectedItemChangeEvent)
        self.accept(PlayerAttackEvent.EventName, self.OnPlayerAttackEvent)
        self.accept(PlayerRespawnEvent.EventName, self.OnPlayerRespawnEvent)
        self.accept(PlayerDeathEvent.EventName, self.OnPlayerDeathEvent)
        self.accept(TeamSelectEvent.EventName, self.OnTeamSelectEvent)
        
        if(not Settings.IS_SERVER):
            self.sounds = {}
            self.sounds['blockBreak'] = loader.loadSfx('Assets/Sounds/blockBreak.mp3')
            self.sounds['blockPlace'] = loader.loadSfx('Assets/Sounds/blockPlace.mp3')
        
    #-----------------------
    # Game Updates / Ticks
    #-----------------------
    
    def FixedUpdate(self):
        self.UpdatePlayer(self.GetMyself(), self.GetMyself().GetPlayerState(), self.engine.input, Globals.FIXED_UPDATE_DELTA_TIME)
        
    def Update(self):
        if(Settings.IS_SERVER):
            # Move all of the players that we have input for
            for elem in self.inputQueue:
                self.ProcessInput(elem[0], elem[1])
            self.inputQueue.clear()
            
            # Check to see if anyone fell off the environment
            self.CheckForFallingPlayers()
        else:
            self.GetMyself().UpdateLookingDirection(self.engine.camera.GetDirection())
            
            for player in self.players.values():
                player.GetPlayerOverheadName().Update()
            
            if(Globals.OFFLINE):
                self.CheckForFallingPlayers()
            
    def CheckForFallingPlayers(self):
        for player in self.players.values():
            if(player.GetPlayerState().GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
                if(player.GetPlayerState().GetValue(PlayerState.POSITION).getZ() < -10):
                    PlayerAttackEvent(player, player, 1000, False).Fire()
            
    #--------------------
    # Updating a player
    #--------------------
    
    def UpdatePlayer(self, player, playerState, playerInput, deltaTime):
        if(playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING_DEAD):
            return
        
        playerState = self.MovePlayer(player, playerState, playerInput, deltaTime)
        player.SetPos(playerState.GetValue(PlayerState.POSITION))
        playerState.UpdateValue(PlayerState.KEYS_PRESSED, playerInput.GetKeys())
        self.HandleDeltaStates()
        player.Update(deltaTime)
        player.UpdateLookingRayDirection(playerInput.GetLookingDir())
        playerState.UpdateValue(PlayerState.LOOKING_DIRECTION, playerInput.GetLookingDir())
        if(playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
            self.PlayerInteraction(player, playerInput.click1, playerInput.click3)
        
    def MovePlayer(self, player, playerState, playerInput, deltaTime):
                
        if(playerState.HasValue(PlayerState.TIME_ELAPSED)):
            timeElapsed = playerState.GetValue(PlayerState.TIME_ELAPSED)
        else:
            timeElapsed = 0
            
        if(playerState.HasValue(PlayerState.Z_VELOCITY)):
            zVelocity = playerState.GetValue(PlayerState.Z_VELOCITY)
        else:
            zVelocity = 0
        
        startPos = playerState.GetValue(PlayerState.POSITION)
        if(playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
            newPos = self.ApplyInput(playerState, Vec3(startPos), playerInput, timeElapsed, zVelocity, deltaTime)
        elif(playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_SPECTATE):
            newPos = self.ApplySpectatorInput(playerState, Vec3(startPos), playerInput, timeElapsed, zVelocity, deltaTime)
        
        playerState = self.EnvironmentCollisionCheck(self.environment, player, newPos, startPos, playerState)
        return playerState
    
    def ApplyInput(self, playerState, pos, playerInput, timeElapsed, zVelocity, deltaTime):
        fDir = Vec3(0, 0, 0)
        movementSpeed = 5
        
        facingDirection = Vec3(playerInput.GetLookingDir())
        facingDirection.setZ(0)
        facingDirection.normalize()
        keysPressed = playerInput.GetKeys()
        
        # Apply input commands
        for key in keysPressed:
            if(key == Globals.KEY_FWD):
                fDir += facingDirection
                
            elif(key == Globals.KEY_BACK):
                fDir -= facingDirection
                
            elif(key == Globals.KEY_RIGHT):
                strafePoint = facingDirection.cross(Globals.UP_VECTOR)
                strafePoint.normalize()
                fDir += strafePoint
                
            elif(key == Globals.KEY_LEFT):
                strafePoint = facingDirection.cross(Globals.UP_VECTOR)
                strafePoint.normalize()
                fDir -= strafePoint
                
            elif(key == Globals.KEY_JUMP):
                if(not playerState.HasValue(PlayerState.IS_GROUNDED)):
                    playerState.SetValue(PlayerState.IS_GROUNDED, True)
                if(playerState.GetValue(PlayerState.IS_GROUNDED)):
                    timeElapsed = 0
                    zVelocity = 6.55
                    playerState.UpdateValue(PlayerState.Z_VELOCITY, 5)
                    playerState.UpdateValue(PlayerState.IS_GROUNDED, False)           
                    
        # Calculate new position
        fDir.normalize()
        pos =  pos + (fDir * movementSpeed * deltaTime)
        
        #if(Settings.IS_SERVER or playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
        # Update timeElapsed (for gravity)
        timeElapsed += deltaTime
        playerState.UpdateValue(PlayerState.TIME_ELAPSED, timeElapsed)
        
        # Figure out effect of gravity
        dz = (zVelocity * timeElapsed + 0.5 * Settings.GRAVITY * timeElapsed * timeElapsed) - (zVelocity * (timeElapsed - deltaTime) + 0.5 * Settings.GRAVITY * (timeElapsed - deltaTime) * (timeElapsed - deltaTime))
        pos.setZ(pos.getZ() + dz)
        
        return pos
    
    def ApplySpectatorInput(self, playerState, pos, playerInput, timeElapsed, zVelocity, deltaTime):
        fDir = Vec3(0, 0, 0)
        movementSpeed = 8
        
        facingDirection = Vec3(playerInput.GetLookingDir())
        facingDirection.normalize()
        keysPressed = playerInput.GetKeys()
        
        # Apply input commands
        for key in keysPressed:
            if(key == Globals.KEY_FWD):
                fDir += facingDirection
                
            elif(key == Globals.KEY_BACK):
                fDir -= facingDirection
                
            elif(key == Globals.KEY_RIGHT):
                strafePoint = facingDirection.cross(Globals.UP_VECTOR)
                strafePoint.normalize()
                fDir += strafePoint
                
            elif(key == Globals.KEY_LEFT):
                strafePoint = facingDirection.cross(Globals.UP_VECTOR)
                strafePoint.normalize()
                fDir -= strafePoint         
                    
        # Calculate new position
        fDir.normalize()
        pos =  pos + (fDir * movementSpeed * deltaTime)
        
        return pos
    
    # Draws bullet tracers and bullet impacts with environment
    def ShowShootingEffects(self, player):
        lookingDir = player.GetPlayerState().GetValue(PlayerState.LOOKING_DIRECTION)
        if(player.lookingRayCollisionEntry):
            loc = player.lookingRayCollisionEntry.getSurfacePoint(render)
            norm = player.lookingRayCollisionEntry.getSurfaceNormal(render)
            
            if(player.lookingRayCollisionEntry.getIntoNodePath().getPythonTag(Globals.TAG_COLLISION) == Globals.COLLISION_BLOCK):
                bid = player.lookingRayCollisionEntry.getIntoNodePath().getPythonTag(Globals.TAG_BLOCK).GetId()
                BlockBulletMark(loc, norm, bid)
            else:
                BloodBulletMark(loc, norm, 0)
        else:
            loc = Point3(player.camNode.getPos(render) + lookingDir * 1000)
        start = player.currentItem.GetPos(render) + Vec3(0, 0, -0.1) + lookingDir * 5
        if((loc - start).lengthSquared() > 16):
            BulletTracer(start, loc)  
    
    def OtherPlayerInteraction(self, player, click1, click3):
        if(isinstance(player.currentItem, Firearm)):
            player.currentItem.Use()
            player.PerfromLookingRayCollision(False)
            
            if(not Settings.IS_SERVER):
                self.ShowShootingEffects(player)
    
    def PlayerInteraction(self, player, click1, click3):
        traversed = False
        playerState = player.GetPlayerState()
        playerState.SetValue(PlayerState.USED_ITEM, False)
        
        currentItem = player.currentItem
        if(isinstance(currentItem, Firearm)):
            if(click1):
                if(currentItem.CanUse()):
                    currentItem.Use()
                    currentItem.Used()
                    playerState.UpdateValue(PlayerState.USED_ITEM, True)
                    player.camNode.setP(player.camNode.getP() + currentItem.recoil)
                    player.camNode.setH(player.camNode.getH() + (0.5 - random.random()) * 2 * currentItem.recoil)
                    
                    if(Settings.IS_SERVER):
                        self.MovePlayersToSnapshot(player, playerState.GetValue(PlayerState.CURRENT_SERVER_TIME) - playerState.GetValue(PlayerState.LAST_SERVER_TIME) + 2) # Add 2 to account for 100ms delay caused by lerping
                    player.PerfromLookingRayCollision()
                    if(Settings.IS_SERVER):
                        self.ReturnPlayersToCurrentPosition()
                    traversed = True
                    
                    # Check for collision with player, if so, do damage
                    if(Settings.IS_SERVER):
                        if(player.lookingRayCollisionEntry):
                            np = player.lookingRayCollisionEntry.getIntoNodePath()
                            collisionTag = np.getPythonTag(Globals.TAG_COLLISION)
                            if(collisionTag != Globals.COLLISION_BLOCK):
                                victim = np.getPythonTag(Globals.TAG_PLAYER)
                                damage = currentItem.GetDamage()
                                hs = False
                                if(collisionTag == Globals.COLLISION_HEAD):
                                    damage *= 1.25
                                    hs = True
                                elif(collisionTag == Globals.COLLISION_LEG):
                                    damage *= 0.75
                                    
                                # Either frindly fire is on, or the attacker and victim are on separate teams
                                if(Settings.FRIENDLY_FIRE or player.GetPlayerState().GetValue(PlayerState.TEAM) != victim.GetPlayerState().GetValue(PlayerState.TEAM)):
                                    PlayerAttackEvent(player, victim, damage, hs).Fire()
                    
                    if(not Settings.IS_SERVER):
                        self.ShowShootingEffects(player)
                
                # Auto reload on the client
                elif(not Settings.IS_SERVER and Settings.AUTO_RELOAD and currentItem.GetCurrentClipAmmo() == 0 and currentItem.GetTotalRemainingAmmo() > 0):
                    player.Reload()
                    
            if(click3):
                if(not Settings.IS_SERVER):
                    currentItem.ToggleADS()
                    
        if(not traversed):
            player.PerfromLookingRayCollision()
                    
        if(isinstance(currentItem, Builder)):
            
            if(click1):
                selectedBlock = player.GetSelectedBlock()
                if(selectedBlock and currentItem.CanUse()):
                    playerState.UpdateValue(PlayerState.USED_ITEM, True)
                    self.environment.DestroyBlock(int(selectedBlock.getX()), int(selectedBlock.getY()), int(selectedBlock.getZ()))
                    currentItem.Used()
                    
                    if(not Settings.IS_SERVER):
                        self.sounds['blockBreak'].play()
                
            if(click3):
                adjacentBlockPoint = player.GetAdjacentBlock()
                if(adjacentBlockPoint and currentItem.CanUse()):
                    self.environment.AddBlock(int(adjacentBlockPoint.getX()), int(adjacentBlockPoint.getY()), int(adjacentBlockPoint.getZ()), currentItem.GetBlockId())
                    currentItem.Used()
                    
                    if(not Settings.IS_SERVER):
                        self.sounds['blockPlace'].play()  
                    
    def MovePlayersToSnapshot(self, currentPlayer, numFramesBack):
        for player in self.players.values():
            player.currentPosition = player.pNode.getPos()
            if(player != currentPlayer and player.GetPlayerState().GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
                player.MovePosToPriorSnapshot(numFramesBack)
            
    def ReturnPlayersToCurrentPosition(self):
        for player in self.players.values():
            player.ReturnToCurrentPosition()
            
    def IsColliding(self, player, x, y, z):
        blocks = self.engine.GetEnvironment().GetBlocks()
        blockPoss = [[x, y, z], [x+1, y, z], [x, y+1, z], [x-1, y, z], [x, y-1, z],
                     [x, y, z+1], [x+1, y, z+1], [x, y+1, z+1], [x-1, y, z+1], [x, y-1, z+1],
                     [x, y, z+2], [x+1, y, z+2], [x, y+1, z+2], [x-1, y, z+2], [x, y-1, z+2],
                     [x+1, y+1, z], [x-1, y+1, z], [x+1, y-1, z], [x-1, y-1, z],
                     [x+1, y+1, z+1], [x-1, y+1, z+1], [x+1, y-1, z+1], [x-1, y-1, z+1],
                     [x+1, y+1, z+2], [x-1, y+1, z+2], [x+1, y-1, z+2], [x-1, y-1, z+2]]
        for (x1, y1, z1) in blockPoss:
            if(self.engine.GetEnvironment().AreValidIndices(x1, y1, z1)):
                if(blocks[x1][y1][z1].IsSolid() and player.boundingBox.IsCollidingWithBlock(x1, y1, z1)):
                    return True
        return False
    
    def EnvironmentCollisionCheck(self, environment, player, newPos, lastGoodPos, playerState):                
        
        x = int(lastGoodPos.getX())
        y = int(lastGoodPos.getY())
        z = int(lastGoodPos.getZ())
        
        # Check Z component
        z = int(newPos.getZ())
        player.pNode.setZ(newPos.getZ())
        if(self.IsColliding(player, x, y, z)):
            player.pNode.setZ(player.pNode.getZ() + player.boundingBox.lastAxisCollisions[2])
            z = int(player.pNode.getZ())
            
            playerState.UpdateValue(PlayerState.TIME_ELAPSED, 0)
            playerState.UpdateValue(PlayerState.Z_VELOCITY, 0)
            if(newPos.getZ() < lastGoodPos.getZ()):
                playerState.UpdateValue(PlayerState.IS_GROUNDED, True)
        else:
            playerState.UpdateValue(PlayerState.IS_GROUNDED, False)  
            
        # Check X component
        x = int(newPos.getX())
        player.pNode.setX(newPos.getX())
        if(self.IsColliding(player, x, y, z)):
            player.pNode.setX(player.pNode.getX() + player.boundingBox.lastAxisCollisions[0])
            x = int(player.pNode.getX())
            
        # Check Y component
        y = int(newPos.getY())
        player.pNode.setY(newPos.getY())
        if(self.IsColliding(player, x, y, z)):
            player.pNode.setY(player.pNode.getY() + player.boundingBox.lastAxisCollisions[1])
            y = int(player.pNode.getY())
            
        playerState.UpdateValue(PlayerState.POSITION, player.GetPos())
        return playerState
    
    #------------------------------
    # Player Deaths and Respawning
    #------------------------------
    
    def OnPlayerRespawnEvent(self, event):
        player = event.GetPlayer()
        pos = self.engine.game.FindRespawnPoint(None)
        playerState = player.GetPlayerState()
        if(playerState):
            playerState.UpdateValue(PlayerState.PLAYING_STATE, PlayerState.PS_PLAYING)
            playerState.UpdateValue(PlayerState.POSITION, pos)
            playerState.UpdateValue(PlayerState.HEALTH, 100)
            player.ChangeItem(player.currentItem)
            player.SetPos(pos)
            self.RefillAllAmmo(player)
            player.OnRespawn()
            if(Settings.IS_SERVER):
                self.engine.server.SendPlayerRespawn(playerState)
            print 'player respawned', playerState.GetValue(PlayerState.NAME), playerState.GetValue(PlayerState.CURRENT_ITEM)
            
            if(not Settings.IS_SERVER):
                self.engine.scoreboard.UpdateIsAlive(playerState.GetValue(PlayerState.PID), True)
            
        else:
            del player
            
    def OnPlayerDeathEvent(self, event):
        victim = event.GetVictim()
        attacker = event.GetAttacker()
        wasHS = event.WasHeadshot()
        
        playerState = victim.GetPlayerState()
        playerState.UpdateValue(PlayerState.PLAYING_STATE, PlayerState.PS_PLAYING_DEAD)
        print 'player Died', playerState.GetValue(PlayerState.NAME)
        victim.OnDeath()
        
        if(Settings.IS_SERVER or Globals.OFFLINE):
            taskMgr.doMethodLater(Game.RESPAWN_TIME, PlayerRespawnEvent(victim, None).Fire, 'RespawnPlayer_%s' % (playerState.GetValue(PlayerState.PID))) 
            
        if(not Settings.IS_SERVER and victim == self.GetMyself()):
            self.engine.respawnCountdown.Start()
            
        if(not Settings.IS_SERVER):
            self.engine.scoreboard.UpdateIsAlive(playerState.GetValue(PlayerState.PID), False)
    
    #------------------------
    # Client only functions
    #------------------------
    
    # This event only gets fired when our player selects a team
    def OnTeamSelectEvent(self, event):
        teamId = event.GetTeam()
        self.GetMyself().OnTeamChange(teamId)
        self.engine.scoreboard.UpdateTeam(Globals.MY_PID, Globals.MY_TEAM)
    
    def VerifyPrediction(self, serverState, snapshots):
        if(not serverState.HasValue(PlayerState.POSITION)):
            return
        
        if(Globals.DEBUG_CSP):
            print 'SERVER', serverState.GetValue(PlayerState.TIMESTAMP), serverState.GetValue(PlayerState.POSITION)
            print 'ME', snapshots[0].GetTimestamp(), snapshots[0].GetPosition()
            for x in snapshots:
                print 'SS', x.GetTimestamp(), x.GetPosition()
        
        diff = (serverState.GetValue(PlayerState.POSITION) - snapshots[0].GetPosition())
        
        if(diff.length() > 0.001):
            print 'DIFF', diff
            myself = self.GetMyself()
            myState = myself.GetPlayerState()
            for snapshot in snapshots:
                serverState.SetValue(PlayerState.PLAYING_STATE, PlayerState.PS_PLAYING)
                serverState = self.MovePlayer(myself, serverState, snapshot.GetInput(), Globals.FIXED_UPDATE_DELTA_TIME)
                snapshot.pos = serverState.GetValue(PlayerState.POSITION)
                myState.UpdateValue(PlayerState.POSITION, serverState.GetValue(PlayerState.POSITION))
                myself.SetPos(serverState.GetValue(PlayerState.POSITION))
                
        return snapshots
    
    def HandleDeltaStates(self):
        
        if(not Settings.IS_SERVER):
        
            for player in self.players.values():
                state = player.GetPlayerState()
                deltaState = state.GetDeltaVars()
                
                if(not Settings.IS_SERVER):
                    state.ClearDeltaVars()
                
                for dVar in deltaState:
                    # If isWalking changed
                    if(dVar == PlayerState.IS_WALKING):
                        if(state.GetValue(dVar)):           # If the player is now walking
                            player.RequestFSMTransition('IdleToWalk')
                        else:                               # If the player stopped moving
                            player.RequestFSMTransition('WalkToIdle')
                                                    
    # Given a dictionary of playerstate updates from the server,
    # apply them to the players in the game
    def HandleServerPlayerStates(self, playerStates):
        for pid, playerState in playerStates.iteritems():
            if(pid != self.GetMyId()):
                if(not pid in self.players.keys()):
                    continue
                    
                player = self.GetPlayer(pid)
                for pVar, value in playerState.vars.iteritems():
                    
                    if(pVar == PlayerState.POSITION):
                        self.GetPlayerPlayerState(player).UpdateValue(PlayerState.POSITION, value)
                        player.LerpTo(value)
                        
                    elif(pVar == PlayerState.LOOKING_DIRECTION):
                        self.GetPlayerPlayerState(player).UpdateValue(PlayerState.LOOKING_DIRECTION, value)
                        player.UpdateLookingDirection(value)
                        player.UpdateLookingRayDirection(value)
                            
                                
    def OtherPlayerWalkingChange(self, player, isWalking):
        if(isWalking):
            player.RequestFSMTransition('IdleToWalk')
        else:
            player.RequestFSMTransition('WalkToIdle')
            
    def HealthChange(self, player, health):
        player.GetPlayerState().UpdateValue(PlayerState.HEALTH, health)
        if(player == self.GetMyself()):
            PlayerHealthEvent(player, health).Fire()
    
    #------------------------
    # Server only functions
    #------------------------
    
    def IsFull(self):
        return len(self.players) > Globals.MAX_PLAYERS
    
    def QueueClientInput(self, player, keys, lookingDir, clicks, timestamp):
        
        newInput = Input(keys, lookingDir, clicks, timestamp)
        self.inputQueue.append([player, newInput])
        
        playerState = player.GetPlayerState()
        playerState.timestamp = timestamp
        
        return newInput
    
    def ProcessInput(self, player, newInput):
        if(player in self.players.values()):
            playerInputBuffer = player.GetInputBuffer()
            playerInputBuffer.UpdateInput(newInput)
            
            if(playerInputBuffer.GoodToGo()):
                newestInput = playerInputBuffer.GetNewestInput()
                bufferedInput = playerInputBuffer.GetBufferedInput()
                playerState = player.GetPlayerState()
                playerState.UpdateValue(PlayerState.KEYS_PRESSED, bufferedInput.GetKeys())
                
                if(playerState.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
                    
                    # Run a Fixed MovementUpdate as many times as necessary
                    while(newestInput.GetTimestamp() - playerState.GetValue(PlayerState.TIMESTAMP) > Globals.FIXED_UPDATE_DELTA_TIME):
                        self.UpdatePlayer(player, playerState, bufferedInput, Globals.FIXED_UPDATE_DELTA_TIME)
                        playerState.SetValue(PlayerState.TIMESTAMP, playerState.GetValue(PlayerState.TIMESTAMP) + Globals.FIXED_UPDATE_DELTA_TIME)
                        #print 'processing input for player ', playerState.GetValue(PlayerState.PID)
                else:
                    print 'spectator', playerState.GetValue(PlayerState.PID)
            else:
                player.GetPlayerState().SetValue(PlayerState.TIMESTAMP, newInput.GetTimestamp())
    
    #---------------------------------------
    # Adding and Removing Players from Game
    #---------------------------------------
        
    def AddNewPlayer(self, pid, name, teamId, playingState = PlayerState.PS_SPECTATE):
        print 'adding new player', pid
        if(pid not in self.players.keys()):
            player = Player()
            
            self.players[pid] = player
            playerState = player.GetPlayerState()
            playerState.SetValue(PlayerState.PID, pid)
            playerState.SetValue(PlayerState.NAME, name)
            playerState.SetValue(PlayerState.TEAM, teamId)
            playerState.SetValue(PlayerState.PLAYING_STATE, playingState)
            print 'added player', pid, name
            
            player.CreateNameTextNode(name)
            player.OnTeamChange(teamId)
            player.ShowPlayerModel()
            
            
            if(pid != Globals.MY_PID):
                player.RemoveSelectionGeom()
                
                if(teamId == Globals.MY_TEAM):
                    player.ShowNameAboveHead()
            else:
                player.HidePlayerModel()
                
            
                
        
    def RemovePlayer(self, pid):
        player = self.players[pid]
        player.Destroy()
        del self.players[pid]
        taskMgr.remove('RespawnPlayer_%s' %(pid))
        
    def HidePlayerModel(self, playerObject):
        playerObject.HidePlayerModel()
        
    def ShowPlayerModel(self, playerObject):
        playerObject.ShowPlayerModel()
        
    # THIS IS TEMPORARY
    def RefillAllAmmo(self, player):
        for item in player.itemModels.values():
            if(isinstance(item, Firearm)):
                item.RefillAmmo()
                
        if(not Settings.IS_SERVER and player.GetPlayerState().GetValue(PlayerState.PID) == Globals.MY_PID):
            inv = player.GetPlayerState().GetValue(PlayerState.MAIN_INVENTORY)
            for itemStack in inv.GetItemStacks():
                if(isinstance(itemStack.GetItem(), Firearm)):
                    itemStack.GetItem().RefillAmmo()
        
    #--------------------
    # Event Handling
    #-----------------
    
    def OnSelectedItemChangeEvent(self, event):
        self.GetMyself().OnSelectedItemChangeEvent(event)
        
    # Figure out what item the player now has. If they've had
    # it before, use the already loaded model. Otherwise,
    # load the model
    def OtherPlayerItemChange(self, player, itemId, extraData = None):
        itemClass = ItemId.ToItem(itemId)
        #player.GetPlayerState().UpdateValue(PlayerState.CURRENT_ITEM, ItemId.NoItem)
        #player.GetPlayerState().UpdateValue(PlayerState.CURRENT_ITEM, itemId)
        if(itemId not in player.itemModels.keys()):            
            if(itemClass):
                item = itemClass()
                item.playerId = player.GetPlayerState().GetValue(PlayerState.PID)
            else:
                item = None
            player.itemModels[itemId] = item
            
        if(extraData):
            print 'changing with extra data'
            player.GetPlayerState().SetValue(PlayerState.CURRENT_ITEM, ItemId.Unknown)
            player.GetPlayerState().UpdateValue(PlayerState.CURRENT_ITEM, itemId)
            if(itemId == ItemId.Builder):
                player.itemModels[itemId].SetBlockId(extraData[0])
                if(not Settings.IS_SERVER):
                    player.itemModels[itemId].UpdateTexture()
                    
                    
        #player.GetPlayerState().UpdateValue(PlayerState.CURRENT_ITEM, itemId)
        
        player.ThirdPersonChangeItem(player.itemModels[itemId])
    
    def OnViewModeChange(self, event):        
        if(event.GetViewMode() == Camera.FirstPersonMode):
            self.GetMyself().HidePlayerModel() 
        else:
            self.GetMyself().ShowPlayerModel()
            
    def OnPlayerAttackEvent(self, event):
        victim = event.GetVictim()
        
        # Update the victim's health
        health = victim.GetPlayerState().GetValue(PlayerState.HEALTH)
        health = max(0, health - event.GetDamage())
        victim.GetPlayerState().UpdateValue(PlayerState.HEALTH, health)
        
        player = event.GetPlayer()
        player.GetPlayerState().UpdateValue(PlayerState.VICTIM, victim)
        
        if(event.WasHeadshot() and health == 0):
            player.GetPlayerState().UpdateValue(PlayerState.VICTIM_ATTACK_TYPE, PlayerState.VAT_BOTH)
        elif(event.WasHeadshot()):
            player.GetPlayerState().UpdateValue(PlayerState.VICTIM_ATTACK_TYPE, PlayerState.VAT_HEADSHOT)
        elif(health == 0):
            player.GetPlayerState().UpdateValue(PlayerState.VICTIM_ATTACK_TYPE, PlayerState.VAT_KILLSHOT)
        else:
            player.GetPlayerState().UpdateValue(PlayerState.VICTIM_ATTACK_TYPE, PlayerState.VAT_NONE)
            
        if(health == 0):
            PlayerDeathEvent(victim, player, event.WasHeadshot()).Fire()
            print 'PLAYER DIEEED'
            
    def ResetPlayerNames(self):
        for player in self.players.values():
            if(player != self.GetMyself()):
                if(player.GetPlayerState().GetValue(PlayerState.TEAM) != Globals.MY_TEAM):
                    # THIS IS REALLY BAD
                    player.nameText.reshowOnInView = False
                    player.nameText.Hide()
                else:
                    player.nameText.reshowOnInView = True
                    player.ShowNameAboveHead()
    
    #------------------------------------------------
    # Getting Information for All Players
    #------------------------------------------------
    
    def GetAllPlayers(self):
        return self.players.values()  
    
    def GetAllPlayerStates(self):
        ps = []
        for player in self.players.values():
            ps.append(player.GetPlayerState())
        return ps
    
    def GetAllPlayingPlayerStates(self):
        ps = []
        for player in self.players.values():
            ps1 = player.GetPlayerState()
            if(ps1.GetValue(PlayerState.PLAYING_STATE) == PlayerState.PS_PLAYING):
                ps.append(ps1)
        return ps
    
    def GetAllPlayerNodes(self):
        nodes = []
        for p in self.GetPlayers():
            nodes.append(p.pNode)
        return nodes  
    
    #------------------------------------------------
    # Getting information for One Player
    #------------------------------------------------
    
    def GetPlayer(self, pid):
        if(pid in self.players.keys()):
            return self.players[pid]
        else:
            return None
    
    def GetPlayerPlayerState(self, player, pid = None):
        if(player is None):
            return self.GetPlayerPlayerState(self.GetPlayer(pid))
        else:
            return player.GetPlayerState()

    def GetPlayerPickerRay(self, player):
        return player.lookingRay
    
    def GetPlayerCollision(self, player):
        return player.collisionGeom 
    
    def GetPlayerEyePosition(self, player):
        return player.camNode.getPos(render)
    
    def GetPlayerLookingDirection(self, player):
        return player.lookingDirection
    
    #------------------------------------------------
    # Getting information for Myself
    #------------------------------------------------
    
    def GetMyself(self):
        return self.players[Globals.MY_PID]
    
    def GetMyId(self):
        return Globals.MY_PID
    
    def GetMyCamNode(self):
        return self.GetMyself().camNode
    
    def GetMyPlayerState(self):
        return self.GetPlayerPlayerState(self.GetMyself())
            
    def GetMyDeltaState(self):
        return self.GetMyself().GetPlayerState().GetDeltaVars()
    
    #--------------------------------------------------------
    # Helper Functions for Setup of PlayerController Object 
    #--------------------------------------------------------
        
    def LoadServerPosDebug(self):
        self.serverPlayer = loader.loadModel('Assets/Models/Players/ralph')
        self.serverPlayer.setScale(0.36)
        self.serverPlayer.reparentTo(render)
        if(not Globals.DEBUG_CSP):
            self.serverPlayer.hide()
        
    def LoadMyself(self):
        print 'loading self'
        if(not Settings.IS_SERVER):
            self.AddNewPlayer(pid = Globals.MY_PID, name = Settings.NAME, teamId = Game.SPECTATE, playingState = PlayerState.PS_SPECTATE)
            
    #-------------------------------------------------------------
    # Helper Functions for Destruction of PlayerController Object 
    #-------------------------------------------------------------
        
    def Destroy(self):
        self.ignoreAll()
        for player in self.players.values():
            player.Destroy()
        del self.players
        del self.environment
        del self.inputQueue
        del self.collisionDummy
        del self.inputPollWait
        del self.playerCollisionHandler
        del self.playerCollisionTraverser
Exemple #13
0
class Physics:
    def __init__(self):
        self.rayCTrav = CollisionTraverser("collision traverser for ray tests")
        #self.pusher = PhysicsCollisionHandler()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addInPattern('%fn-in-%in')
        self.pusher.addOutPattern('%fn-out-%in')
        self.pusher.addInPattern('%fn-in')
        self.pusher.addOutPattern('%fn-out')

    def startPhysics(self):
        #self.actorNode = ActorNode("playerPhysicsControler")
        #base.physicsMgr.attachPhysicalNode(self.actorNode)
        #self.actorNode.getPhysicsObject().setMass(self.player_mass)
        #self.mainNode = render.attachNewNode(self.actorNode)
        self.mainNode = render.attachNewNode("CharacterColliders")
        self.reparentTo(self.mainNode)

        charCollisions = self.mainNode.attachNewNode(
            CollisionNode(self.char_collision_name))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0))
        charCollisions.node().addSolid(
            CollisionSphere(0, 0, self.player_height / 2.0,
                            self.player_height / 4.0))
        charCollisions.node().setIntoCollideMask(BitMask32(0x80))  # 1000 0000
        if self.show_collisions:
            charCollisions.show()
        self.pusher.addCollider(charCollisions, self.mainNode)
        base.cTrav.addCollider(charCollisions, self.pusher)

        charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray"))
        charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1))
        #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1)))
        charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff())
        charFFootCollisions.node().setFromCollideMask(
            BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            charFFootCollisions.show()

        self.floor_handler = CollisionHandlerFloor()
        self.floor_handler.addCollider(charFFootCollisions, self.mainNode)
        #self.floor_handler.setOffset(0)
        self.floor_handler.setMaxVelocity(5)
        base.cTrav.addCollider(charFFootCollisions, self.floor_handler)

        self.accept("{}-in".format(self.char_collision_name),
                    self.checkCharCollisions)

        self.raytest_segment = CollisionSegment(0, 1)
        self.raytest_np = render.attachNewNode(CollisionNode("testRay"))
        self.raytest_np.node().addSolid(self.raytest_segment)
        self.raytest_np.node().setIntoCollideMask(BitMask32.allOff())
        self.raytest_np.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            self.raytest_np.show()

        self.raytest_queue = CollisionHandlerQueue()
        self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue)

    def stopPhysics(self):
        self.raytest_segment.removeNode()
        self.pusher.clearColliders()
        self.floor_handler.clearColliders()
        self.rayCTrav.clearColliders()

    def updatePlayerPos(self, speed, heading, dt):
        if heading is not None:
            self.mainNode.setH(camera, heading)
            self.mainNode.setP(0)
            self.mainNode.setR(0)
        self.mainNode.setFluidPos(self.mainNode, speed)
        self.doStep()

    def checkCharCollisions(self, args):
        self.doStep()

    def doStep(self):
        # do the step height check
        tmpNP = self.mainNode.attachNewNode("temporary")
        tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight)
        pointA = self.mainNode.getPos(render)
        pointA.setZ(pointA.getZ() + self.player_height / 1.8)
        pointB = tmpNP.getPos(render)
        if pointA == pointB: return
        char_step_collision = self.getFirstCollisionInLine(pointA, pointB)
        tmpNP.removeNode()
        if char_step_collision is not None:
            self.mainNode.setFluidZ(char_step_collision.getZ())
            return True
        return False

    def getFirstCollisionInLine(self, pointA, pointB):
        """A simple raycast check which will return the first collision point as
        seen from point A towards pointB"""
        self.raytest_segment.setPointA(pointA)
        self.raytest_segment.setPointB(pointB)
        self.rayCTrav.traverse(render)
        self.raytest_queue.sortEntries()
        pos = None
        if self.raytest_queue.getNumEntries() > 0:
            pos = self.raytest_queue.getEntry(0).getSurfacePoint(render)
        return pos
Exemple #14
0
class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # Call various initialization methods on class
        self.windowInit(1280, 720)
        self.levelInit("Models/Environment/environment")
        self.lightingInit()
        self.playerInit()
        self.cameraInit(pos=Vec3(0, 0, 32), hpr=Vec3(0, -90, 0))
        self.inputInit()
        self.collisionInit()

        self.tempEnemy = WalkingEnemy(Vec3(5, 0, 0))

        # Set up a task that we'll run consistently
        self.updateTask = taskMgr.add(self.update, "update")

    def windowInit(self, h, w):
        properties = WindowProperties()
        properties.setSize(h, w)
        self.win.requestProperties(properties)

    def levelInit(self, levelname):
        # Load a backdrop model and attach it to the Scene Graph
        self.environment = loader.loadModel(levelname)
        self.environment.reparentTo(render)

        # Set up level collision
        self.cTrav = CollisionTraverser()
        self.pusher = CollisionHandlerPusher()

    def lightingInit(self):
        # Kind of dark with just an ambient light, maybe a directional light eh
        mainLight = DirectionalLight("main light")
        self.mainLightNodePath = render.attachNewNode(mainLight)
        self.mainLightNodePath.setHpr(45, -45, 0)
        render.setLight(self.mainLightNodePath)

        # hook us up some automatic perpixel lighting
        render.setShaderAuto()

    def playerInit(self):
        # Initialize and render player character
        self.player = Player()
        self.player.actor.reparentTo(render)

    def cameraInit(self, pos, hpr):
        self.camera.setPos(pos)
        self.camera.setHpr(hpr)

    def collisionInit(self):
        self.pusher.addCollider(self.player.collider, self.player.actor)
        self.cTrav.addCollider(self.player.collider, self.pusher)
        self.pusher.setHorizontal(True)

        wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2)
        wallNode = CollisionNode("wall")
        wallNode.addSolid(wallSolid)
        wall = render.attachNewNode(wallNode)
        wall.setY(8.0)

        wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2)
        wallNode = CollisionNode("wall")
        wallNode.addSolid(wallSolid)
        wall = render.attachNewNode(wallNode)
        wall.setY(-8.0)

        wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2)
        wallNode = CollisionNode("wall")
        wallNode.addSolid(wallSolid)
        wall = render.attachNewNode(wallNode)
        wall.setX(8.0)

        wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2)
        wallNode = CollisionNode("wall")
        wallNode.addSolid(wallSolid)
        wall = render.attachNewNode(wallNode)
        wall.setX(-8.0)

    def inputInit(self):
        # Input states
        self.keyMap = {
            "up": False,
            "down": False,
            "left": False,
            "right": False,
            "shoot": False
        }

        # Disable the default camera control
        self.disableMouse()

        # Set up events to call self.updateKeyMap with args when certain keys are pressed or released
        self.accept("w", self.updateKeyMap, ["up", True])
        self.accept("w-up", self.updateKeyMap, ["up", False])
        self.accept("s", self.updateKeyMap, ["down", True])
        self.accept("s-up", self.updateKeyMap, ["down", False])
        self.accept("a", self.updateKeyMap, ["left", True])
        self.accept("a-up", self.updateKeyMap, ["left", False])
        self.accept("d", self.updateKeyMap, ["right", True])
        self.accept("d-up", self.updateKeyMap, ["right", False])
        self.accept("mouse1", self.updateKeyMap, ["shoot", True])
        self.accept("mouse1-up", self.updateKeyMap, ["shoot", False])

    # keyMap setter
    def updateKeyMap(self, controlName, controlState):
        self.keyMap[controlName] = controlState

    # Main game logic we have running every frame
    def update(self, task):
        dt = globalClock.getDt()

        self.player.update(self.keyMap, dt)

        self.tempEnemy.update(self.player, dt)

        return task.cont
# Set the object's collision node to render as visible.
smileyC.show()

# Load another model.
frowney = loader.loadModel('frowney')
# Reparent the model to render.
frowney.reparentTo(render)
# Set the position of the model in the scene.
frowney.setPos(5, 25, 0)

# Create a collsion node for this object.
cNode = CollisionNode('frowney')
# Attach a collision sphere solid to the collision node.
cNode.addSolid(CollisionSphere(0, 0, 0, 1.1))
# Attach the collision node to the object's model.
frowneyC = frowney.attachNewNode(cNode)
# Set the object's collision node to render as visible.
frowneyC.show()

# Add the Pusher collision handler to the collision traverser.
base.cTrav.addCollider(frowneyC, pusher)
# Add the 'frowney' collision node to the Pusher collision handler.
pusher.addCollider(frowneyC, frowney, base.drive.node())

# Have the 'smiley' sphere moving to help show what is happening.
frowney.posInterval(5, Point3(5, 25, 0), startPos=Point3(-5, 25, 0),
                    fluid=1).loop()

# Run the scene. Move around with the mouse to see how the moving sphere changes
# course to avoid the one attached to the camera.
run()
Exemple #16
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0,
        }

        # Post the instructions
        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward")
        self.inst5 = addInstructions(0.30, "[Down Arrow]: Walk Ralph Backward")
        self.inst6 = addInstructions(0.36, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.42, "[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)

        # We do not have a skybox, so we will just use a sky blue background color
        self.setBackgroundColor(0.53, 0.80, 0.92, 1)

        # 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 + (0, 0, 1.5))

        # Create a floater object, which floats 2 units above ralph.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.ralph)
        self.floater.setZ(2.0)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["backward", True])
        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("s", self.setKey, ["cam-right", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["backward", False])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])

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

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        self.cTrav = CollisionTraverser()

        # Use a CollisionHandlerPusher to handle collisions between Ralph and
        # the environment. Ralph is added as a "from" object which will be
        # "pushed" out of the environment if he walks into obstacles.
        #
        # Ralph is composed of two spheres, one around the torso and one
        # around the head.  They are slightly oversized since we want Ralph to
        # keep some distance from obstacles.
        self.ralphCol = CollisionNode('ralph')
        self.ralphCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5))
        self.ralphCol.addSolid(CollisionSphere(center=(0, -0.25, 4), radius=1.5))
        self.ralphCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphCol.setIntoCollideMask(CollideMask.allOff())
        self.ralphColNp = self.ralph.attachNewNode(self.ralphCol)
        self.ralphPusher = CollisionHandlerPusher()
        self.ralphPusher.horizontal = True

        # Note that we need to add ralph both to the pusher and to the
        # traverser; the pusher needs to know which node to push back when a
        # collision occurs!
        self.ralphPusher.addCollider(self.ralphColNp, self.ralph)
        self.cTrav.addCollider(self.ralphColNp, self.ralphPusher)

        # 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.
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 9)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphGroundCol.setIntoCollideMask(CollideMask.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, 9)
        self.camGroundRay.setDirection(0, 0, -1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.camGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

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

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

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    # 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 that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

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

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

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

        if self.keyMap["left"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -20 * dt)
        if self.keyMap["backward"]:
            self.ralph.setY(self.ralph, +10 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        currentAnim = self.ralph.getCurrentAnim()

        if self.keyMap["forward"]:
            if currentAnim != "run":
                self.ralph.loop("run")
        elif self.keyMap["backward"]:
            # Play the walk animation backwards.
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(-1.0, "walk")
        elif self.keyMap["left"] or self.keyMap["right"]:
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(1.0, "walk")
        else:
            if currentAnim is not None:
                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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z

        entries = list(self.ralphGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.ralph.setZ(entry.getSurfacePoint(render).getZ())

        # Keep the camera at one unit above the terrain,
        # or two units above ralph, whichever is greater.

        entries = list(self.camGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.camera.setZ(entry.getSurfacePoint(render).getZ() + 1.5)
        if self.camera.getZ() < self.ralph.getZ() + 2.0:
            self.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.camera.lookAt(self.floater)

        return task.cont
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)
        self.orbCollisionHandler = CollisionHandlerQueue()
        self.cTrav = CollisionTraverser()
        self.cTrav.setRespectPrevTransform(True)
        self.startgame = False
        self.sound=loader.loadSfx("models/0614.ogg")
        self.sound2=loader.loadSfx("models/01-main-theme.mp3")
        self.sound2.play()
        status=self.sound2.status()
        #hbPath = NodePath()
    
        utils.setUpKeys(self)
        utils.loadModels(self)
        utils.setUpLighting(self)
        #utils.setUpFloatingSpheres(self)
        utils.setUpRalphsShot(self)
        utils.setUpCamera(self)
        utils.setUpCollisionSpheres(self)
        self.healthTxt = utils.addInstructions(.06,"Health: 100")
        self.orbTxt = utils.addInstructions(.18,"Orbs: 0")
        self.hitsTxt = utils.addInstructions(.28,"Enemy Hits: 0")
        self.strHealthStatus = str(self.healthTxt)
        # Create a frame
        frame = DirectFrame(text = "main", scale = 0.001)
        # Add button
        self.flagstartbutton = 0        

        self.imageObject = OnscreenImage(image = 'models/instapage.jpg', pos = (0, 0, 0), scale=1.1)    
        self.imageObject2 = OnscreenImage(image = 'models/gap.jpg', pos = (-2.15, 0, 0), scale=1.1)
        self.imageObject3 = OnscreenImage(image = 'models/gap.jpg', pos = (2.15, 0, 0), scale=1.1)
        self.helpOn = DirectButton(text = ("Start", "on/off", "Start", "disabled"), scale=.10, pos=(-1.1,0,-.9), command=utils.buttonClickedOn, extraArgs=[self, self.imageObject,self.imageObject2,self.imageObject3, self.flagstartbutton])
        #helpOff = DirectButton(text = ("helpOff", "on/off", "helpOff", "disabled"), scale=.10, pos=(-0.5,0,-1), command=utils.buttonClickedOff, extraArgs=[self, self.imageObject, self.buttonflag])
      #  mytimer = DirectLabel()
      #  mytimer.reparentTo(render)
      #  mytimer.setY(7)        
        #Create 4 buttons       
        #print self.strHealthStatus
        #incBar(100)
    
        self.vec = LVector3(0,1,0)#vector for pawns shot

        # Create a frame
        #frame = DirectFrame(text = "main", scale = 0.001)
        # Add button
        #bar = DirectWaitBar(text = "", value = 50, pos = (0,.4,.4))
        #bar.reparent(render)

        # Game state variables
        self.isMoving = False
        self.jumping = False
        self.vz = 0
        self.numOrbs = 0
        self.healthCount = 100
        self.enemyhits = 0
    
        
        

        #self.shotList = []
        #self.sphere = CollisionBox((self.ralph.getX() + -10,self.ralph.getY(),self.ralph.getZ()),10,10,10)
        self.ralphBox1 = CollisionBox((0,2.5,3.5),1.5,0.5,1.5)
        cnodepath = self.ralph.attachNewNode((CollisionNode("ralphColNode")))
        cnodepath.node().addSolid(self.ralphBox1)
        cnodepath.node().addSolid(CollisionBox((0,-2.5,3.5),1.5,0.5,1.5))

        cnodepath.node().addSolid(CollisionBox((2.5,0,3.5),0.5,1.5,1.5))
        cnodepath.node().addSolid(CollisionBox((-2.5,0,3.5),0.5,1.5,1.5))

        #cnodepath.show()
        #self.cTrav.addCollider(cnodepath, self.orbCollisionHandler)

        self.sphere = CollisionSphere(0,-5,4,3)
        self.sphere3 = CollisionSphere(0,5,5,3)
        self.sphere4 = CollisionSphere(-4,0,5,2)
        self.sphere5 = CollisionSphere(4,0,5,2)
        self.sphere2 = CollisionSphere(0,0,3,2)
        self.cnodePath = self.ralph.attachNewNode((CollisionNode("ralphColNode")))
        self.cnodePath2 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck")))
        self.cnodePath3 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck2")))
        self.cnodePath4 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck3")))
        self.cnodePath5 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck4")))
        self.cnodePath.node().addSolid(self.sphere2)
        self.cnodePath2.node().addSolid(self.sphere)
        self.cnodePath3.node().addSolid(self.sphere3)
        self.cnodePath4.node().addSolid(self.sphere4)
        self.cnodePath5.node().addSolid(self.sphere5)
        #self.cnodePath.node().addSolid(self.sphere2)

        #self.cnodePath.show()#ralph pusher

        #self.cnodePath2.show()
        #self.cnodePath3.show()
        #self.cnodePath4.show()
        #self.cnodePath5.show()
        self.cTrav.addCollider(self.cnodePath2, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath3, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath4, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath5, self.orbCollisionHandler)


        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.cnodePath, self.ralph)

        #self.cTrav.addCollider(self.cnodePath, self.ralphCollisionHandler)
        self.cTrav.addCollider(self.cnodePath, self.pusher)


        self.chrisLastShotTime = globalClock.getFrameTime()
        self.chrisTimer = globalClock.getDt()

        #def __init__(self, pos,showbase, colPathName, dir, length):
        self.chrisList = [utils.cheken((-249,419,0),self,"chrisColPath0","X",5), #earthroom
                            utils.chris((-404,343,2),self,"chrisColPath1","X",5), #yellowroom
                            utils.fetus((-141,-69,1),self,"chrisColPath2","X",5), #lightblueroom

                            utils.cheken((-277,356,0),self,"chrisColPath3","Y",5), #between earth and y
                            utils.rose((-102,-5,1),self,"chrisColPath4","Y",5), #between r and lb

                            utils.cheken((-133,83,0),self,"chrisColPath5","Y",5), #blue hall
                            utils.fetus((-246,280,1),self,"chrisColPath6","X",5), #earth hall

                            utils.cheken((-330,241,0),self,"chrisColPath7","X",5), #yellow hall
                            utils.chris((-60,110,2),self,"chrisColPath8","Y",5), #red hall cheken z 0

                            utils.fetus((-75,52,1),self, "chrisColPath9", "X", 5),
                            utils.cheken((-75,141,0),self, "chrisColPath10", "X", 5),

                          utils.rose((-302,202,1),self,"chrisColPath11","X",5),
                          utils.chris((-303,304,2),self,"chrisColPath12","Y",5)

                              
                         ]
        #rose z = 1
        #cheken z = 0
        #chris z = 2
        #fetus z = 1

        #def _init_(self,showbase,pos,color,speed,radius):
        self.orbList = [utils.orb(self,( 18, 29,2.5),(1,0,0,1),20,2.5), #first red
                        utils.orb(self,( -249, 419,2.5),(1,1,1,1),20,2.5),#earthroom
                        utils.orb(self,( -404, 343,2.5),(1,1,0,1),20,2.5), #yellowroom
                        utils.orb(self,( -141, -69,2.5),(0,0,1,1),20,2.5),#light blue room

                        utils.orb(self,( -277, 356,2.5),(1,1,0,1),20,2.5), #between y and earth
                        utils.orb(self,( -102, -5,2.5),(0,0,1,1),20,2.5),   #between red and lb

                        utils.orb(self,( -135, 22,2.5),(0,0,1,1),20,2.5), #lb hall
                        utils.orb(self,( -248, 329,2.5),(1,1,1,1),20,2.5), #earthhall

                        utils.orb(self,( -330, 241,2.5),(1,1,0,1),20,2.5), #yellow hall
                        utils.orb(self,( -60, 110,2.5),(1,0,0,1),20,2.5) #red hall
                         ]
        self.donutList = [utils.donut(self, (0,0,1),20, 2.5),
                          utils.donut(self,( -330, 250,2.5),20,2.5), #yellow hall
                          utils.donut(self,( -141, -80,2.5),20,2.5),#light blue room
                          utils.donut(self,( -249, 430,2.5),20,2.5),#earthroom
                          utils.donut(self,( -102, -10,2.5),20,2.5),   #between red and lb

                          ]

        self.cameraCollided = False
        self.ralphSpeed = 60
        self.ralphHit = False
        self.ralphRedTime = 0

        self.textTime = -1
        self.textTime2 = -1
        self.textTime3 = -1
        self.mTextPath = utils.addInstructions2(.44,"")
        self.mTextPath2 = utils.addInstructions2(.55,"")
        self.winText2 = utils.addInstructions2(.55, "")
        self.timerText = utils.addInstructions4(.26,"0:00")
        self.introText = utils.addInstructions2(.55,"")

        self.minutes = 4
        self.seconds = 0
        self.timerTime = globalClock.getFrameTime()

        taskMgr.add(self.move, "moveTask")
        taskMgr.add(self.moveChris,"moveChrisTask")
        taskMgr.add(self.timerTask,"timerTask")
        #taskMgr.add(self.timerTask, "timerTask")
        

    # Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
    def clickResponse():
        pass
        #startgame=1;
        
        
    def timerTask(self,task):
        if self.startgame == False:
            return task.cont
        dt = globalClock.getFrameTime()
        if dt - self.timerTime > 1:
            self.seconds -= 1
            if self.seconds == -1:
                self.seconds = 59
                self.minutes -=1
            self.timerText.destroy()

            if self.seconds < 10:
                str1 = "0" + str(self.minutes) + ":0" + str(self.seconds)
            else:
                str1 = "0" + str(self.minutes) + ":" + str(self.seconds)
            self.timerText = utils.addInstructions4(.26,str1)
            self.timerTime = globalClock.getFrameTime() - ((dt - self.timerTime) - 1)
        if self.minutes == 0 and self.seconds == 0:
            self.startgame = False
            #utils.addInstructions3(.45,"You Lose")
            self.imageObject2 = OnscreenImage(image = 'models/gameover.jpg', pos = (0, 0, 0), scale=1.1)
            self.imageObject2 = OnscreenImage(image = 'models/gap.jpg', pos = (-2.15, 0, 0), scale=1.1)
            self.imageObject3 = OnscreenImage(image = 'models/gap.jpg', pos = (2.15, 0, 0), scale=1.1)
        return task.cont

    def moveChris(self,task):
        if self.startgame == False:
            return task.cont
        else:
            dt = globalClock.getDt()
            self.gianteye.setH(self.gianteye.getH() + 100 * dt)
            for chris in self.chrisList:
                chris.moveChris(dt,self,self.chrisList)
            return task.cont
    

    # 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.sound2.status() != self.sound2.PLAYING:
            self.sound2.play()

        if self.startgame == False:
            return task.cont
        else:
        # Get the time that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
            dt = globalClock.getDt()
            dt2 = globalClock.getFrameTime()
            #utils.moveChris(self,dt)
            #self.chris2.moveChris(dt,self)
            #self.startEnemyThread()

            if dt2 - self.textTime > 2 and self.textTime != -1:
                self.textTime = -1;
                self.mTextPath.destroy()

            if dt2 - self.textTime2 > 2 and self.textTime2 != -1:
                self.textTime2 = -1;
                self.mTextPath2.destroy()

            if dt2 - self.textTime3 > 5 and self.textTime3 != -1:
                self.textTime3 = -1;
                self.introText.destroy()



            if globalClock.getFrameTime()- self.ralphRedTime > .3 and self.ralphHit == True:
                    self.ralph.clearColor()
                    self.ralphHit = False

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

            if self.keyMap["cam-left"]:
                self.camera.setZ(self.camera, -20 * dt)
            if self.keyMap["cam-right"]:
                self.camera.setZ(self.camera, +20 * dt)

            # 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"]:
                self.ralph.setH(self.ralph.getH() + 75 * dt)
                #self.camera.setX(self.camera, +15.5 * dt)
            if self.keyMap["right"]:
                self.ralph.setH(self.ralph.getH() - 75 * dt)
                #self.camera.setX(self.camera, -15.5 * dt)
            if self.keyMap["forward"]:#-1
                self.ralph.setFluidY(self.ralph, -1*self.ralphSpeed * dt)
                #self.camera.setY(self.camera, -35 * dt)
            if self.keyMap["back"]:
                self.ralph.setFluidY(self.ralph, self.ralphSpeed * dt)
                #self.camera.setY(self.camera, 35 * dt)
            if self.keyMap["space"]:
                if self.jumping is False:
                #self.ralph.setZ(self.ralph.getZ() + 100 * dt)
                    self.jumping = True
                    self.vz = 8

            if self.keyMap["enter"]:
                self.keyMap["enter"] = False
                self.sound.play()
                self.shotList[self.shotCount].lpivot.setPos(self.ralph.getPos())
                self.shotList[self.shotCount].lpivot.setZ(self.ralph.getZ() + .5)
                self.shotList[self.shotCount].lpivot.setX(self.ralph.getX() - .25)
                print self.ralph.getPos()
                

                #self.shotList.append(rShot)
                #self.lightpivot3.setPos(self.ralph.getPos())
                #self.lightpivot3.setZ(self.ralph.getZ() + .5)
                #self.lightpivot3.setX(self.ralph.getX() - .25)
                #self.myShot.setHpr(self.ralph.getHpr())
                #parent to ralph
                #node = NodePath("tmp")
                #node.setHpr(self.ralph.getHpr())
                #vec = render.getRelativeVector(node,(0,-1,0))
                #self.myShotVec = vec

                node = NodePath("tmp")
                node.setHpr(self.ralph.getHpr())
                vec = render.getRelativeVector(node,(0,-1,0))
                self.shotList[self.shotCount].vec = vec
                self.shotCount = (self.shotCount + 1) % 10
            else:
                self.sound.stop()

            for rs in self.shotList:
                rs.lpivot.setPos(rs.lpivot.getPos() + rs.vec * dt * 25 )
                #if shot is too far stop updating


            
            if self.jumping is True:
                self.vz = self.vz - 16* dt
                self.ralph.setZ(self.ralph.getZ() + self.vz * dt )
                if self.ralph.getZ() < 0:
                    self.ralph.setZ(0)
                    self.jumping = False
            else:
                if self.ralph.getZ() < 0.25:
                    self.ralph.setZ(0.25)
                elif self.ralph.getZ() > 0.25:
                    self.ralph.setZ(self.ralph.getZ() -7 * dt)

            # If ralph is moving, loop the run animation.
            # If he is standing still, stop the animation.
            if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"] or self.keyMap["space"] or self.keyMap["forward"] or self.keyMap["back"]:
                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

            # update pawns shot or set up new shot after it reaches a certain distance
            node = NodePath("tmp")
            node.setHpr(self.pawn.getHpr())
            vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
            self.shot.setPos(self.shot.getPos() + self.vec * dt * 10 )
            if self.shot.getY() < -15 or self.shot.getY() > 30 or self.shot.getX() < 5 or self.shot.getX() > 15:
                self.shot.setPos(self.pawn.getPos() + (0,0,0))
                self.vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
                self.vec = render.getRelativeVector(node,(random.random() * random.randrange(-1,2),random.random() + 1,0))

            # If the camera is too far from ralph, move it closer.
            # If the camera is too close to ralph, move it farther.
            #self.camera.lookAt(self.floater)
            camvec = self.ralph.getPos() - self.camera.getPos()
            #camvec = Vec3(0,camvec.getY(),0)
            camdist = camvec.length()
            x = self.camera.getZ()
            camvec.normalize()
            #if camdist > 6.0:
            #    self.camera.setPos(self.camera.getPos() + camvec * (camdist - 6))
            #if camdist < 6.0:
            #    self.camera.setPos(self.camera.getPos() - camvec * (6 - camdist))

            # Normally, we would have to call traverse() to check for collisions.
            # However, the class ShowBase that we inherit from has a task to do
            # this for us, if we assign a CollisionTraverser to self.cTrav.
            #self.cTrav.traverse(render)

            # Adjust camera so it stays at same height
            if self.cameraCollided == False:
                if self.camera.getZ() < self.ralph.getZ() + 1 or self.camera.getZ() > self.ralph.getZ() + 1:
                    self.camera.setZ(self.ralph.getZ() + 1)

            # 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.camera.lookAt(self.floater)


            entries = list(self.orbCollisionHandler.getEntries())
            if(len(entries) > 0):
                #self.lightpivot.reparentTo(NodePath())
                orbCollected = False
                self.cameraCollided = False
                self.ralphSpeed = 85
                ralphHit = False
                for entry in self.orbCollisionHandler.getEntries():
                    #print(entry)
                    fromColNp = entry.getFromNodePath()
                    toColNp = entry.getIntoNodePath()
                    if fromColNp.getName() == "orbColPath" and toColNp.getName() == "ralphColNode":
                        if orbCollected == False:
                            fromColNp.getParent().reparentTo(NodePath())
                            self.orbTxt.destroy()
                            self.numOrbs += 1
                            str1 = "Orbs: " + str(self.numOrbs)
                            self.orbTxt = utils.addInstructions(.18, str1)
                            orbCollected = True
                    elif toColNp.getName() == "orbColPath" and fromColNp.getName() == "ralphColNode":
                        if orbCollected == False:
                            toColNp.getParent().reparentTo(NodePath())
                            self.orbTxt.destroy()
                            self.numOrbs += 1
                            str1 = "Orbs: " + str(self.numOrbs)
                            self.orbTxt = utils.addInstructions(.18, str1)
                            orbCollected = True

                    elif fromColNp.getName() == "donutCollisionNode" and toColNp.getName() == "ralphColNode":
                        fromColNp.getParent().reparentTo(NodePath())
                        self.healthCount += 15
                        if(self.healthCount > 100):
                            self.healthCount = 100
                        self.healthTxt.destroy()
                        str1 = "Health: " + str(self.healthCount)
                        self.healthTxt = utils.addInstructions(.06, str1)
                    elif toColNp.getName() == "donutCollisionNode" and fromColNp.getName() == "ralphColNode":
                        toColNp.getParent().reparentTo(NodePath())
                        self.healthCount += 15
                        if(self.healthCount > 100):
                            self.healthCount = 100
                        self.healthTxt.destroy()
                        str1 = "Health: " + str(self.healthCount)
                        self.healthTxt = utils.addInstructions(.06, str1)
                    elif toColNp.getName() == "ralphOrbColPath" and (fromColNp.getName()[:-1] == "chrisColPath" or fromColNp.getName()[:-2] == "chrisColPath"):
                        toColNp.getParent().setZ(20)
                        for chriss in self.chrisList:
                            if chriss.chrisColName == fromColNp.getName():
                                chris = chriss
                                break

                        chris.chrisHealth = chris.chrisHealth - 1
                        chris.chris.setColor(1,0,0,1)
                        chris.chrisHit = True
                        chris.chrisRedTime = globalClock.getFrameTime()
                        #print chris.chrisRedTime
                        if chris.chrisHealth < 0 and chris.chrisAlive == True:
                            fromColNp.getParent().removeNode()
                            chris.chrisAlive = False
                            self.hitsTxt.destroy()
                            self.enemyhits += 1
                            str1 = "Enemy Hits: " + str(self.enemyhits)
                            self.hitsTxt = utils.addInstructions(.28, str1)
                            chris.chrisShot.setZ(26)
                    elif (toColNp.getName()[:-1] == "chrisColPath" or toColNp.getName()[:-2] == "chrisColPath") and fromColNp.getName() == "ralphOrbColPath":
                        fromColNp.getParent().setZ(20)
                        for chriss in self.chrisList:
                            if chriss.chrisColName == toColNp.getName():
                                chris = chriss
                                break

                        chris.chrisHealth = chris.chrisHealth - 1
                        chris.chris.setColor(1,0,0,1)
                        chris.chrisHit = True
                        chris.chrisRedTime = globalClock.getFrameTime()
                        #print chris.chrisRedTime
                        if chris.chrisHealth < 0 and chris.chrisAlive == True:
                            toColNp.getParent().removeNode()
                            chris.chrisAlive = False
                            self.hitsTxt.destroy()
                            self.enemyhits += 1
                            str1 = "Enemy Hits: " + str(self.enemyhits)
                            self.hitsTxt = utils.addInstructions(.28, str1)
                            chris.chrisShot.setZ(26)
                    elif toColNp.getName() == "enemyOrbColPath" and fromColNp.getName() == "ralphColNode":
                        if ralphHit == False:
                            toColNp.getParent().setZ(26)
                            self.healthTxt.destroy()
                            self.healthCount -= 5
                            str1 = "Health: " + str(self.healthCount)
                            self.healthTxt = utils.addInstructions(.06, str1)
                            self.ralphHit = True
                            self.ralph.setColor((1,0,0,1))
                            self.ralphRedTime = globalClock.getFrameTime()

                        if self.healthCount <= 0:
                            self.startgame = False
                            #utils.addInstructions3(.45,"You Lose")
                            self.imageObject2 = OnscreenImage(image = 'models/gameover.jpg', pos = (0, 0, 0), scale=1.1)
                            self.imageObject2 = OnscreenImage(image = 'models/gap.jpg', pos = (-2.15, 0, 0), scale=1.1)
                            self.imageObject3 = OnscreenImage(image = 'models/gap.jpg', pos = (2.15, 0, 0), scale=1.1)
                    elif toColNp.getName() == "ralphColNode" and fromColNp.getName() == "enemyOrbColPath":
                        fromColNp.getParent().setZ(26)
                        if ralphHit == False:
                            self.healthTxt.destroy()
                            self.healthCount -= 5
                            str1 = "Health: " + str(self.healthCount)
                            self.healthTxt = utils.addInstructions(.06, str1)
                            self.ralphHit = True
                            self.ralph.setColor((1,0,0,1))
                            self.ralphRedTime = globalClock.getFrameTime()
                            ralphHit = True

                        if self.healthCount <= 0:
                            self.startgame = False
                            #utils.addInstructions3(.45,"You Lose")
                            self.imageObject2 = OnscreenImage(image = 'models/gameover.jpg', pos = (0, 0, 0), scale=1.1)
                            self.imageObject2 = OnscreenImage(image = 'models/gap.jpg', pos = (-2.15, 0, 0), scale=1.1)
                            self.imageObject3 = OnscreenImage(image = 'models/gap.jpg', pos = (2.15, 0, 0), scale=1.1)
                    elif toColNp.getName() == "ralphColNode" and fromColNp.getName() == "portalColPath":
                        if self.numOrbs < 3 and self.enemyhits < 4:
                            self.mTextPath.destroy()
                            self.mTextPath = utils.addInstructions2(.30, "Not enough orbs.")
                            self.textTime = globalClock.getFrameTime()
                            self.mTextPath2.destroy()
                            self.mTextPath2 = utils.addInstructions2(.45, "Not enough kills.")
                            self.textTime2 = globalClock.getFrameTime()
                        elif self.numOrbs < 3:
                            self.mTextPath.destroy()
                            self.mTextPath = utils.addInstructions2(.30, "Not enough orbs.")
                            self.textTime = globalClock.getFrameTime()
                        elif self.enemyhits < 4:
                            self.mTextPath2.destroy()
                            self.mTextPath2 = utils.addInstructions2(.45, "Not enough kills.")
                            self.textTime2 = globalClock.getFrameTime()
                        else:
                            self.winText = utils.addInstructions3(.45, "You Win")
                            self.startgame = False
                            #self.ralph.setPos(-196, 177, 3)
                            if self.isMoving == True:
                                self.ralph.stop()
                                self.ralph.pose("walk", 5)
                                self.isMoving = False



                    elif fromColNp.getName() == "ralphOrbColPath" and toColNp.getName() == "allinclusive":
                        fromColNp.getParent().setZ(50)
                    elif toColNp.getName() == "ralphOrbColPath" and fromColNp.getName() == "allinclusive":
                        toColNp.getParent().setZ(50)
                    elif fromColNp.getName() == "enemyOrbWallCheck" and toColNp.getName() == "allinclusive":
                        fromColNp.getParent().setZ(50)
                        #print toColNp.getName()
                    elif toColNp.getName() == "enemyOrbWallCheck" and fromColNp.getName() == "allinclusive":
                        toColNp.getParent().setZ(50)
                        #print fromColNp.getName()

                    elif fromColNp.getName() == "ralphWallCheck" and toColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(0,-1,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #fromColNp.getParent().setZ(26)
                        self.ralphSpeed = 60
                    elif toColNp.getName() == "ralphWallCheck" and fromColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(0,-1,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #print "wtf"
                        #toColNp.getParent().setZ(26)
                        self.ralphSpeed = 60
                    elif fromColNp.getName() == "ralphWallCheck2" and toColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(0,1,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #fromColNp.getParent().setZ(26)
                        self.ralphSpeed = 60
                    elif toColNp.getName() == "ralphWallCheck2" and fromColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(0,1,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #self.camera.setPos(self.ralph.getPos())
                        #self.cameraCollided = True
                        self.ralphSpeed = 60
                    elif fromColNp.getName() == "ralphWallCheck3" and toColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(-1,0,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #fromColNp.getParent().setZ(26)
                        self.ralphSpeed = 60
                        
                    elif toColNp.getName() == "ralphWallCheck3" and fromColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(-1,0,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #self.camera.setPos(self.ralph.getPos())
                        #self.cameraCollided = True
                        self.ralphSpeed = 60
                        
                    elif fromColNp.getName() == "ralphWallCheck4" and toColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(1,0,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #fromColNp.getParent().setZ(26)
                        self.ralphSpeed = 60
                        
                    elif toColNp.getName() == "ralphWallCheck4" and fromColNp.getName() == "allinclusive":
                        #node = NodePath("tmp")
                        #node.setHpr(self.ralph.getHpr())
                        #vec = render.getRelativeVector(node,(1,0,0))
                        #self.ralph.setPos(self.ralph.getPos()-vec)
                        #self.camera.setPos(self.ralph.getPos())
                        #self.cameraCollided = True
                        self.ralphSpeed = 60
                        

            utils.updateHealthBar(self.healthCount, self.bar)
            #utils.turnofstartbutton(self.flagstartbutton)
            #if self.flagstartbutton ==1:
            #    self.helpOn.destory()
            return task.cont
Exemple #18
0
class Player(DirectObject):
    def __init__(self, _main):
        self.main = _main
        self.name = ""
        self.points = 0
        self.health = 100.0
        self.runSpeed = 1.8
        self.keyMap = {
            "left":False,
            "right":False,
            "up":False,
            "down":False
            }
        base.camera.setPos(0,0,0)
        self.model = loader.loadModel("Player")
        self.model.find('**/+SequenceNode').node().stop()
        self.model.find('**/+SequenceNode').node().pose(0)
        base.camera.setP(-90)
        self.playerHud = Hud()
        self.playerHud.hide()
        self.model.hide()

        # Weapons: size=2, 0=main, 1=offhand
        self.mountSlot = []
        self.activeWeapon = None
        self.isAutoActive = False
        self.trigger = False
        self.lastShot = 0.0
        self.fireRate = 0.0

        self.playerTraverser = CollisionTraverser()
        self.playerEH = CollisionHandlerEvent()
        ## INTO PATTERNS
        self.playerEH.addInPattern('intoPlayer-%in')
        #self.playerEH.addInPattern('colIn-%fn')
        self.playerEH.addInPattern('intoHeal-%in')
        self.playerEH.addInPattern('intoWeapon-%in')
        ## OUT PATTERNS
        self.playerEH.addOutPattern('outOfPlayer-%in')
        playerCNode = CollisionNode('playerSphere')
        playerCNode.setFromCollideMask(BitMask32.bit(1))
        playerCNode.setIntoCollideMask(BitMask32.bit(1))
        self.playerSphere = CollisionSphere(0, 0, 0, 0.6)
        playerCNode.addSolid(self.playerSphere)
        self.playerNP = self.model.attachNewNode(playerCNode)
        self.playerTraverser.addCollider(self.playerNP, self.playerEH)
        #self.playerNP.show()

        self.playerPusher = CollisionHandlerPusher()
        self.playerPusher.addCollider(self.playerNP, self.model)
        self.playerPushTraverser = CollisionTraverser()
        self.playerPushTraverser.addCollider(self.playerNP, self.playerPusher)

    def acceptKeys(self):
        self.accept("w", self.setKey, ["up", True])
        self.accept("w-up", self.setKey, ["up", False])
        self.accept("a", self.setKey, ["left", True])
        self.accept("a-up", self.setKey, ["left", False])
        self.accept("s", self.setKey, ["down", True])
        self.accept("s-up", self.setKey, ["down", False])
        self.accept("d", self.setKey, ["right", True])
        self.accept("d-up", self.setKey, ["right", False])

        # Add mouse btn for fire()
        self.accept("mouse1", self.setWeaponTrigger, [True])
        self.accept("mouse1-up", self.setWeaponTrigger, [False])

        # Killed enemies
        self.accept("killEnemy", self.addPoints)

        # Game states
        self.accept("doDamageToPlayer", self.doDamage)

    def ignoreKeys(self):
        self.ignore("w")
        self.ignore("a")
        self.ignore("s")
        self.ignore("d")
        self.ignore("killEnemy")
        self.ignore("mouse1")
        self.ignore("mouse1-up")

        for item in self.main.itemList:
            if item.type == "heal":
                self.ignore("intoHeal-" + "itemHeal" + str(item.id))
            elif item.type == "gun":
                self. ignore("intoWeapon-" + "itemWeapon" + str(item.id))

        for enemy in self.main.enemyList:
            self.ignore("intoPlayer-" + "colEnemy" + str(enemy.id))

        # Add mouse btn for fire to ignore

    def setKey(self, action, pressed):
        self.keyMap[action] = pressed

    def start(self, startPos, playerName):
        self.name = playerName
        self.points = 0
        self.health = 100
        self.model.reparentTo(render)
        self.model.setPos(startPos.x,
                          startPos.y,
                          0)
        for slot in self.mountSlot[:]:
            self.mountSlot.remove(slot)
        # Create a basic weapon
        self.mountSlot.append(Weapon(self.main, "Pistol", 0.30, 25, weaponType="Pistol"))
        # Mount the players default weapon
        self.mountWeapon(self.mountSlot[0])
        self.playerHud.setWeapon("Pistol")

        self.acceptKeys()
        self.playerHud.show()

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

    def stop(self):
        taskMgr.remove("moveTask")
        self.ignoreKeys()
        self.unmountWeapon()
        self.playerHud.hide()
        self.model.hide()

    def addPoints(self, args):
        self.points += 10
        base.messenger.send("setHighscore", [self.points])

    def move(self, task):
        elapsed = globalClock.getDt()
        #self.playerTraverser.traverse(self.main.enemyParent)
        #self.playerTraverser.traverse(self.main.itemParent)

        # set headding
        pos = self.main.mouse.getMousePos()
        pos.setZ(0)
        self.model.lookAt(pos)
        self.model.setP(-90)

        # new player position
        if self.keyMap["up"]:
            # follow mouse mode
            #self.model.setZ(self.model, 5 * elapsed * self.runSpeed)
            # axis move mode
            self.model.setY(self.model.getY() + elapsed * self.runSpeed)
        elif self.keyMap["down"]:
            #self.model.setZ(self.model, -5 * elapsed * self.runSpeed)
            self.model.setY(self.model.getY() - elapsed * self.runSpeed)

        if self.keyMap["left"]:
            # follow mouse mode
            #self.model.setX(self.model, -5 * elapsed * self.runSpeed)
            # axis move mode
            self.model.setX(self.model.getX() - elapsed * self.runSpeed)
        elif self.keyMap["right"]:
            #self.model.setX(self.model, 5 * elapsed * self.runSpeed)
            self.model.setX(self.model.getX() + elapsed * self.runSpeed)

        # actualize cam position
        base.camera.setPos(self.model.getPos())
        base.camera.setZ(20)
        return task.cont

    def mountWeapon(self, _weaponToMount):
        self.activeWeapon = _weaponToMount # self.mountSlot[0]
        if self.activeWeapon.style == "TwoHand":
            self.model.find('**/+SequenceNode').node().pose(0)
        else:
            self.model.find('**/+SequenceNode').node().pose(1)
        self.activeWeapon.model.reparentTo(self.model)
        self.activeWeapon.model.setY(self.model.getY() - 0.1)
        self.model.show()
        self.activeWeapon.model.show()
        self.fireRate = self.activeWeapon.fireRate

    def unmountWeapon(self):
        self.activeWeapon.model.hide()

    def setWeaponTrigger(self, _state):
        self.trigger = _state

        if _state:
            mpos = self.main.mouse.getMousePos()
            self.activeWeapon.doFire(mpos)
            if self.activeWeapon.weaponType == "MG":
                self.fireActiveWeapon()
            else:
                self.activeWeapon.stopFire()
        else:
            self.activeWeapon.stopFire()
            taskMgr.remove("Fire")

    def fireActiveWeapon(self):
        if self.activeWeapon:
            #mpos = self.main.mouse.getMousePos()
            taskMgr.add(self.fireUpdate, "Fire")
            #self.activeWeapon.doFire(mpos)

    def fireUpdate(self, task):
        dt = globalClock.getDt()
        self.lastShot += dt
        mpos = self.main.mouse.getMousePos()
        #print self.lastShot
        if self.lastShot >= self.fireRate:
            self.lastShot -= self.fireRate

            if self.trigger:
                self.activeWeapon.doFire(mpos)
                #task.delayTime += self.fireRate
        return task.again

    def setMouseBtn(self):
        self.trigger = False

        print "Mouse Released"

    def addEnemyDmgEvent(self, _id):
        self.accept("intoPlayer-" + "colEnemy" + str(_id), self.setEnemyAttack)
        #self.accept("outOfPlayer-" + "colEnemy" + str(_id), self.setEnemyAttackOutOfRange)

    def setEnemyAttack(self, _entry):
        enemyColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("inRange-" + enemyColName, [True])

    def setEnemyAttackOutOfRange(self, _entry):
        enemyColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("inRange-" + enemyColName, [False])

    def doDamage(self, _dmg):

        if self.health <= 0:
            #print "KILLED IN ACTION"
            self.main.stop()
        else:
            self.health -= _dmg
            #print "Remaining Health: ", self.health
        base.messenger.send("setHealth", [self.health])

    def addHealItemEvent(self, _id):
        self.accept("intoHeal-" + "itemHeal" + str(_id), self.healPlayer)

    def healPlayer(self, _entry):
        itemColName = _entry.getIntoNodePath().node().getName()

        if self.health == 100:
            pass

        else:
            self.health += 50
            base.messenger.send("into-" + itemColName)
            if self.health > 100:
                self.health = 100

        print self.health

    def addWeaponItemEvent(self, _id):
        self.accept("intoWeapon-" + "itemWeapon" + str(_id), self.changeWeapon)

    def changeWeapon(self, _entry):
        itemColName = _entry.getIntoNodePath().node().getName()
        base.messenger.send("into-" + itemColName)
        for weapon in self.mountSlot:
            if weapon.name == "MachineGun":
                return
        self.unmountWeapon()
        self.mountSlot.append(Weapon(self.main, "MachineGun", 0.15, 50, weaponType="MG"))
        self.playerHud.setWeapon("MG")
        self.mountWeapon(self.mountSlot[len(self.mountSlot) - 1])
        self.activeWeapon.model.show()
Exemple #19
0
    def __init__(self):
        messenger.toggleVerbose()

        ShowBase.__init__(self)

        self.environ = self.loader.loadModel("models/falcon")
        self.environ.reparentTo(self.render)
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, 0)

        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
        self.taskMgr.add(self.moveCameraTask, "MoveCameraTask")
        self.taskMgr.add(self.playerGravity, "PlayerGravity")
        #self.taskMgr.add(self.collTask, "CollisionTask")


        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.setPos(0, 0, 10)
        self.pandaActor.reparentTo(self.render)

        # Initialize the collision traverser.
        self.cTrav = CollisionTraverser()
        self.cTrav.showCollisions(self.render)
         
        # Initialize the Pusher collision handler.
        pusher = CollisionHandlerPusher()
 
        # Create a collision node for this object.
        cNode = CollisionNode('panda')
        # Attach a collision sphere solid to the collision node.
        cNode.addSolid(CollisionSphere(0, 0, 0, 600))
        # Attach the collision node to the object's model.
        pandaC = self.pandaActor.attachNewNode(cNode)
        # Set the object's collision node to render as visible.
        pandaC.show()
 
        # Create a collsion node for this object.
        cNode = CollisionNode('environnement')
        # Attach a collision sphere solid to the collision node.
        cNode.addSolid(CollisionSphere(-1.3, 19, 0.5, 2.5))
        cNode.addSolid(CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,0.2))))
        # Attach the collision node to the object's model.
        environC = self.environ.attachNewNode(cNode)
        # Set the object's collision node to render as visible.
        environC.show()
 
        # Add the Pusher collision handler to the collision traverser.
        self.cTrav.addCollider(pandaC, pusher)
        # Add the 'frowney' collision node to the Pusher collision handler.
        pusher.addCollider(pandaC, self.environ, base.drive.node())
         
        fromObject = self.pandaActor.attachNewNode(CollisionNode('colNode'))
        fromObject.node().addSolid(CollisionRay(0, 0, 0, 0, 0, -1))
        lifter = CollisionHandlerFloor()
        lifter.addCollider(fromObject, self.pandaActor)
        self.cTrav.addCollider(pandaC, lifter)

        # Have the 'smiley' sphere moving to help show what is happening.
        #frowney.posInterval(5, Point3(5, 25, 0), startPos=Point3(-5, 25, 0), fluid=1).loop()
 
        #self.stuff = Actor("models/panda-model")
        #self.stuff.setScale(0.005, 0.005, 0.005)
        #self.stuff.setPos(-1.3, 19., 0.5)
        #self.stuff.reparentTo(self.render)

#        cTrav = CollisionTraverser()
#        ceh = CollisionHandlerQueue()
#        #ceh.addInPattern('%fn-into-%in')
#        #ceh.addAgainPattern('%fn-again-%in')
#        #ceh.addOutPattern('%fn-outof-%in')
#        self.pandaColl = self.pandaActor.attachNewNode(CollisionNode('cnode'))
#        self.pandaColl.node().addSolid(CollisionSphere(self.pandaActor.getChild( 0 ).getBounds( ).getCenter(), 400))
#        self.pandaColl.show()
#        cTrav.addCollider( self.pandaColl, ceh )
#        self.cTrav = cTrav
#        self.cTrav.showCollisions(self.render)
#        self.queue = ceh
#        cs = CollisionSphere(-1.3, 19, 0.5, 2.5)
#        pl = CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,0.2)))
#        # ray = CollisionRay(self.pandaActor.getPos(), Vec3(0,0,-1))
#        cnodePath = self.render.attachNewNode(CollisionNode('cnode'))
#        # rayNodePath = self.render.attachNewNode(CollisionNode('raynode'))
#        cnodePath.node().addSolid(cs)
#        cnodePath.node().addSolid(pl)
#        # rayNodePath.node().addSolid(ray)
#        cnodePath.show()
#        # rayNodePath.show()
#        #rayNodePath.reparentTo(self.pandaActor)
        #self.accept('car-into-rail', handleRailCollision)
        #cTrav.addCollider(cnodePath, ceh)

        self.camera.reparentTo(self.pandaActor)
        self.camera.setPos(0., 1050., 1000.)

        self.camAlpha = 180
        self.camBeta = 0
        self.moving = []
        self.playerAltitude = 0
        self.jumping = False
        self.inJump = False
        self.playerFallingSpeed = 0
        self.player = Mass(80)
        base.useDrive()
        #base.disableMouse( ) # disable the default camera controls that are created for us
        self.keyBoardSetup()
class RoamingPenguinDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0,
        }

    

        ###########################################################################

        self.environ = loader.loadModel("models/world")
        self.environ.reparentTo(render)

        # We do not have a skybox, so we will just use a sky blue background color
        #self.setBackgroundColor(0.53, 0.80, 0.92, 1)
        self.setBackgroundColor(.1, .1, .1, 1)
        # Create the main character, person

        #personStartPos = self.environ.find("**/start_point").getPos()
        #self.person = Actor("models/panda",
         #                  {"run": "models/panda-walk",
          #                  "walk": "models/panda-walk"})

        person2StartPos = self.environ.find("**/start_point").getPos()
        self.person2 = Actor("models/passenger_penguin",
                           {"run": "models/passenger_penguin",
                            "walk": "models/passenger_penguin"})

       
        self.person2.reparentTo(render)
        self.person2.setScale(.1)
   
        self.person2.setPos(person2StartPos + (px, py, 1))


        person3StartPos = self.environ.find("**/start_point").getPos()
        self.person3 = Actor("models/MagicBunny",
                           {"run": "models/MagicBunny",
                            "walk": "models/MagicBunny"})

        #px = random.randint(-1,1)
        #py = random.randint(-1,1)


        self.person3.reparentTo(render)
        self.person3.setScale(.04)
        #self.person.setPos(personStartPos + (0, 0, 2))
        self.person3.setPos(person3StartPos + (px/1.5+3, py/2, 0))

        personStartPos = self.environ.find("**/start_point").getPos()
        self.person = Actor("models/panda",
                           {"run": "models/panda-walk",
                            "walk": "models/panda-walk"})


        self.person.reparentTo(render)
        self.person.setScale(.1)
        self.person.setPos(personStartPos + (0, 0, 1.5))
        self.person.loop("run")


        arenaStartPos = self.environ.find("**/start_point").getPos()
        self.arena = Actor("models/FarmHouse")


        self.arena.reparentTo(render)
        self.arena.setScale(.1)
        self.arena.setPos(arenaStartPos + (-1, 0, 0))


        arena2StartPos = self.environ.find("**/start_point").getPos()
        self.arena2 = Actor("models/fence")


        self.arena2.reparentTo(render)
        self.arena2.setScale(5.9)
        self.arena.setPos(arenaStartPos + (px, py-12, 1))
        self.arena2.setPos(arenaStartPos + (8, 5, -1))


        arena2StartPos = self.environ.find("**/start_point").getPos()
        self.arena3 = Actor("models/gate")


        self.arena3.reparentTo(render)
        self.arena3.setScale(.01)

        self.arena3.setPos(arenaStartPos + (px/2+random.randint(12,15), py/2, -1))

        self.arena4 = Actor("models/FarmHouse")
        self.arena4.reparentTo(render)
        self.arena4.setScale(.1)

        self.arena4.setPos(arenaStartPos + (px/3-random.randint(18,22), py/3, -1))


        self.arena5 = Actor("models/gate")
        self.arena5.reparentTo(render)
        self.arena5.setScale(.008)

        self.arena5.setPos(arenaStartPos + (px/1.2-9, py/1.2, -1))

        #####################################################################################################################################
        base.enableParticles()
        self.t = loader.loadModel("teapot") # for the particle enhancer
        self.t.setScale(10)
        self.t.setPos(-10, -20, -1)
        self.t.reparentTo(render)
        #self.setupLights()
        self.p = ParticleEffect()
        self.p.setScale(1000)
        self.loadParticleConfig('smoke.ptf') # looks like a storm at night
        self.p.setScale(20)




        #################################################3

        # Create a floater object, which floats 2 units above person.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.person)
        self.floater.setZ(2.0)

        # Accept the control keys for movement and rotation


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

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.person.getX(), self.person.getY() + 10, 2)

        self.cTrav = CollisionTraverser()

    
        self.personCol = CollisionNode('person')
        self.personCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5))
        self.personCol.addSolid(CollisionSphere(center=(0, -0.25, 4), radius=1.5))
        self.personCol.setFromCollideMask(CollideMask.bit(0))
        self.personCol.setIntoCollideMask(CollideMask.allOff())
        self.personColNp = self.person.attachNewNode(self.personCol)
        self.personPusher = CollisionHandlerPusher()
        self.personPusher.horizontal = True

        self.personPusher.addCollider(self.personColNp, self.person)
        self.cTrav.addCollider(self.personColNp, self.personPusher)

        
        self.personGroundRay = CollisionRay()
        self.personGroundRay.setOrigin(0, 0, 9)
        self.personGroundRay.setDirection(0, 0, -1)
        self.personGroundCol = CollisionNode('personRay')
        self.personGroundCol.addSolid(self.personGroundRay)
        self.personGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.personGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.personGroundColNp = self.person.attachNewNode(self.personGroundCol)
        self.personGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.personGroundColNp, self.personGroundHandler)

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

       
   

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, .2))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((.2, .2, .2, 1))
        directionalLight.setSpecularColor((.1, .1, .1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

    def loadParticleConfig(self, filename):
        # Start of the code from steam.ptf
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(filename))
    
        self.p.start(self.t)
        self.p.setPos(3.000, 0.000, 2.250)




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


    def move(self, task):

      
        dt = globalClock.getDt()
       

        #z = abs(py)
        self.person.setX(self.person, 4 * dt)
        self.person.setX(self.person, -4 * dt)

        ## this is how the Panda finds his friend

        if px < 0 :
            #if self.person.getPos() - self.person2.getPos() < (0, 0, 0) :
            if self.person.getY() - self.person2.getY() < 6 :
            #self.person.getPos(personStartPos + (0, py, 1.5))
                self.person.setY(self.person, 0 * dt)
                self.person.stop()
                self.person.pose("walk", 5)
                self.isMoving = False
            else:
                self.person.setY(self.person, py * dt)
                self.person.setX(self.person, px * dt)
                self.person.setH(self.person, px/(abs(px)+6)* dt)
        else:
            if self.person.getY() - self.person2.getY() < 6 :
            #self.person.getPos(personStartPos + (0, py, 1.5))
                self.person.setY(self.person, 0 * dt)
                self.person.stop()
                self.person.pose("walk", 5)
                self.isMoving = False
            else:
                self.person.setY(self.person, py * dt)
                self.person.setX(self.person, px * dt)
                self.person.setH(self.person, px/(abs(px)+6)* dt)


        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

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

    

        entries = list(self.personGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.person.setZ(entry.getSurfacePoint(render).getZ())

     

        entries = list(self.camGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.camera.setZ(entry.getSurfacePoint(render).getZ() + 3.5)
        if self.camera.getZ() < self.person.getZ() + 4.0:
            self.camera.setZ(self.person.getZ() + 4.0)

       
        self.camera.lookAt(self.floater)

        return task.cont
Exemple #21
0
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)

        base.render.setAttrib(LightRampAttrib.makeHdr0())

        # Configure depth pre-pass
        prepass_pass = lionrender.DepthScenePass()

        # Configure scene pass
        scene_fb_props = FrameBufferProperties()
        scene_fb_props.set_rgb_color(True)
        scene_fb_props.set_rgba_bits(8, 8, 8, 0)
        scene_fb_props.set_depth_bits(32)
        scene_pass = lionrender.ScenePass(
            frame_buffer_properties=scene_fb_props,
            clear_color=LColor(0.53, 0.80, 0.92, 1),
            share_depth_with=prepass_pass)
        scene_pass.node_path.set_depth_write(False)

        # Configure post processing
        filter_pass = lionrender.FilterPass(fragment_path='shaders/fsq.frag')
        filter_pass.node_path.set_shader_input('inputTexture',
                                               scene_pass.output)

        # Enable FXAA
        fxaa_pass = lionrender.FxaaFilterPass()
        fxaa_pass.node_path.set_shader_input('inputTexture',
                                             filter_pass.output)

        # Output result
        fxaa_pass.output_to(render2d)

        # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "cam-left": 0,
            "cam-right": 0,
        }

        # Post the instructions
        self.title = addTitle(
            "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward")
        self.inst5 = addInstructions(0.30, "[Down Arrow]: Walk Ralph Backward")
        self.inst6 = addInstructions(0.36, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.42, "[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)

        # We do not have a skybox, so we will just use a sky blue background color
        self.setBackgroundColor(0.53, 0.80, 0.92, 1)

        # 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 + (0, 0, 1.5))

        # Create a floater object, which floats 2 units above ralph.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.ralph)
        self.floater.setZ(2.0)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["backward", True])
        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("s", self.setKey, ["cam-right", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["backward", False])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])
        self.accept("v", self.toggleCards)

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

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2)

        self.cTrav = CollisionTraverser()

        # Use a CollisionHandlerPusher to handle collisions between Ralph and
        # the environment. Ralph is added as a "from" object which will be
        # "pushed" out of the environment if he walks into obstacles.
        #
        # Ralph is composed of two spheres, one around the torso and one
        # around the head.  They are slightly oversized since we want Ralph to
        # keep some distance from obstacles.
        self.ralphCol = CollisionNode('ralph')
        self.ralphCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5))
        self.ralphCol.addSolid(
            CollisionSphere(center=(0, -0.25, 4), radius=1.5))
        self.ralphCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphCol.setIntoCollideMask(CollideMask.allOff())
        self.ralphColNp = self.ralph.attachNewNode(self.ralphCol)
        self.ralphPusher = CollisionHandlerPusher()
        self.ralphPusher.horizontal = True

        # Note that we need to add ralph both to the pusher and to the
        # traverser; the pusher needs to know which node to push back when a
        # collision occurs!
        self.ralphPusher.addCollider(self.ralphColNp, self.ralph)
        self.cTrav.addCollider(self.ralphColNp, self.ralphPusher)

        # 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.
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 9)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphGroundCol.setIntoCollideMask(CollideMask.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, 9)
        self.camGroundRay.setDirection(0, 0, -1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.camGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

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

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

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))

        # Clean up texture attributes
        for texture in self.render.find_all_textures():
            texture.set_format(Texture.F_srgb)

    # 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 that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

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

        if self.keyMap["cam-left"]:
            self.camera.setX(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setX(self.camera, +20 * dt)

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

        if self.keyMap["left"]:
            self.ralph.setH(self.ralph.getH() + 300 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 300 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -20 * dt)
        if self.keyMap["backward"]:
            self.ralph.setY(self.ralph, +10 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        currentAnim = self.ralph.getCurrentAnim()

        if self.keyMap["forward"]:
            if currentAnim != "run":
                self.ralph.loop("run")
        elif self.keyMap["backward"]:
            # Play the walk animation backwards.
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(-1.0, "walk")
        elif self.keyMap["left"] or self.keyMap["right"]:
            if currentAnim != "walk":
                self.ralph.loop("walk")
            self.ralph.setPlayRate(1.0, "walk")
        else:
            if currentAnim is not None:
                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() - self.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if camdist > 10.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10))
            camdist = 10.0
        if camdist < 5.0:
            self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist))
            camdist = 5.0

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z

        entries = list(self.ralphGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.ralph.setZ(entry.getSurfacePoint(render).getZ())

        # Keep the camera at one unit above the terrain,
        # or two units above ralph, whichever is greater.

        entries = list(self.camGroundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        for entry in entries:
            if entry.getIntoNode().getName() == "terrain":
                self.camera.setZ(entry.getSurfacePoint(render).getZ() + 1.5)
        if self.camera.getZ() < self.ralph.getZ() + 2.0:
            self.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.camera.lookAt(self.floater)

        return task.cont

    def toggleCards(self):
        self.bufferViewer.toggleEnable()
Exemple #22
0
class Player:

    STATE_IDLE = "Idle"
    STATE_WALK = "Walk"
    STATE_RUN = "Run"
    STATE_JUMP = "Jump"
    STATE_RUNJUMP = "RunJump"
    STATE_FALL = "Fall"
    STATE_DUCK = "Duck"
    STATE_UN_DUCK = "UnDuck"
    STATE_FLOAT = "Float"
    STATE_SWIM = "Swim"
    SUB_STATE_GRAB = "Grab"

    JUMP_ACCEL = 3.5
    FALL_ACCEL = -9.81

    TERRAIN_NONE = 0
    TERRAIN_GROUND = 1
    TERRAIN_WATER = 2
    TERRAIN_AIR = 3

    DUCK_FRAME_COUNT = 0
    DUCK_FRAME_MID = 0

    SUNK_CUTOFF = -0.9

    def __init__(self, base):
        self.base = base
        self.keyState = {
            "WalkFw": False,
            "WalkBw": False,
            "Run": False,
            "RotateL": False,
            "RotateR": False,
            "Jump": False,
            "Duck": False
        }
        self.isKeyDown = self.base.mouseWatcherNode.isButtonDown
        self.state = Player.STATE_IDLE
        self.sub_state = None
        self.walkDir = 0
        self.rotationDir = 0
        self.zVelocity = 0
        self.zOffset = None
        self.jumpHeight = None
        self.terrainZone = Player.TERRAIN_NONE
        self.terrainSurfZ = None
        self.waterDepth = 0
        self.collidedObjects = list()
        # actor
        anims = {
            "idle": "models/player-idle",
            "walk": "models/player-walk",
            "run": "models/player-run",
            "jump": "models/player-jump",
            "duck": "models/player-duck",
            "float": "models/player-float",
            "swim": "models/player-swim",
            "grab": "models/player-grab"
        }
        self.actor = Actor("models/player", anims)
        self.actor.reparentTo(self.base.render)
        self.actor.setH(200)
        log.debug("actor tight bounds is %s" %
                  str(self.actor.getTightBounds()))
        # animation info
        Player.DUCK_FRAME_COUNT = self.actor.getNumFrames("duck")
        Player.DUCK_FRAME_MID = int(Player.DUCK_FRAME_COUNT / 2)
        # camara point
        self.camNode = NodePath("camNode")
        self.camNode.reparentTo(self.actor)
        self.camNode.setPos(0, 0, 1)
        # collision
        #   ray
        collRay = CollisionRay(0, 0, 1.5, 0, 0, -1)
        collRayN = CollisionNode("playerCollRay")
        collRayN.addSolid(collRay)
        collRayN.setFromCollideMask(1)
        collRayN.setIntoCollideMask(CollideMask.allOff())
        collRayNP = self.actor.attachNewNode(collRayN)
        self.collQRay = CollisionHandlerQueue()
        self.base.cTrav.addCollider(collRayNP, self.collQRay)
        #   sphere mask 2
        collSphere2 = CollisionSphere(0, 0, 0.5, 0.25)
        collSphere2N = CollisionNode("playerCollSphere2")
        collSphere2N.addSolid(collSphere2)
        collSphere2N.setFromCollideMask(2)
        collSphere2N.setIntoCollideMask(CollideMask.allOff())
        self.collSphere2NP = self.actor.attachNewNode(collSphere2N)
        self.collPSphere = CollisionHandlerPusher()
        self.collPSphere.addCollider(self.collSphere2NP, self.actor)
        self.base.cTrav.addCollider(self.collSphere2NP, self.collPSphere)
        # key events
        self.base.accept("i", self.dump_info)
        # task
        self.base.taskMgr.add(self.update, "playerUpdateTask")

    def defineKeys(self):
        for k in self.keyState.keys():
            self.keyState[k] = False
        if self.isKeyDown(KeyboardButton.up()):
            self.keyState["WalkFw"] = True
        if self.isKeyDown(KeyboardButton.down()):
            self.keyState["WalkBw"] = True
        if self.isKeyDown(KeyboardButton.left()):
            self.keyState["RotateL"] = True
        if self.isKeyDown(KeyboardButton.right()):
            self.keyState["RotateR"] = True
        if self.isKeyDown(KeyboardButton.shift()):
            self.keyState["Run"] = True
        if self.isKeyDown(KeyboardButton.space()):
            self.keyState["Jump"] = True
        if self.isKeyDown(KeyboardButton.asciiKey("d")):
            self.keyState["Duck"] = True

    def defineState(self):
        #
        newState = self.state
        # keys states
        ks = self.keyState
        # state force
        if self.zOffset > 0.2 and self.state != Player.STATE_FALL:
            newState = Player.STATE_FALL
        # from Idle -> Walk, Jump
        if self.state == Player.STATE_IDLE:
            # Walk
            if ks["WalkFw"] or ks["WalkBw"] or ks["RotateL"] or ks["RotateR"]:
                newState = Player.STATE_WALK
            elif ks["Jump"]:
                newState = Player.STATE_JUMP
            elif ks["Duck"]:
                newState = Player.STATE_DUCK
        # from Walk, Run -> Walk, Run, Idle; from Run -> Jump
        elif self.state == Player.STATE_WALK or self.state == Player.STATE_RUN:
            if ks["Run"] and self.state != Player.STATE_RUN and self.terrainZone != Player.TERRAIN_WATER:
                newState = Player.STATE_RUN
            elif not ks["Run"] and self.state == Player.STATE_RUN:
                newState = Player.STATE_WALK
            if ks["WalkFw"]:
                self.walkDir = -1
            elif ks["WalkBw"]:
                self.walkDir = 1
            elif not ks["WalkFw"] and not ks["WalkBw"]:
                self.walkDir = 0
            if ks["RotateL"]:
                self.rotationDir = 1
            elif ks["RotateR"]:
                self.rotationDir = -1
            elif not ks["RotateL"] and not ks["RotateR"]:
                self.rotationDir = 0
            if ks["Jump"]:
                newState = Player.STATE_RUNJUMP
            if self.walkDir == 0 and self.rotationDir == 0:
                newState = Player.STATE_IDLE
        # from Jump -> Fall
        elif self.state == Player.STATE_JUMP or self.state == Player.STATE_RUNJUMP:
            if self.zVelocity > 0:
                newState = Player.STATE_FALL
        # from Fall -> Idle
        elif self.state == Player.STATE_FALL:
            if self.zOffset <= 0:
                newState = Player.STATE_IDLE
                self.jumpHeight = None
                self.zVelocity = 0
                self.walkDir = 0
        # from Duck -> UnDuck
        elif self.state == Player.STATE_DUCK:
            if not ks["Duck"]:
                newState = Player.STATE_UN_DUCK
        # from UnDuck -> Idle
        elif self.state == Player.STATE_UN_DUCK:
            if not self.actor.getCurrentAnim() == "duck":
                newState = Player.STATE_IDLE
        return newState

    def processState(self, dt):
        # terrain sdjustment
        if self.zOffset <= 0.2 and not self.state == Player.STATE_FALL:
            self.actor.setZ(self.terrainSurfZ)
        # idle
        if self.state == Player.STATE_IDLE:
            self.collSphere2NP.setZ(0)
        # walk
        if self.walkDir != 0:
            if self.zVelocity == 0:
                speed = 3.6 if self.state == Player.STATE_RUN else 2.4
            else:
                speed = 3.2
            if self.terrainZone == Player.TERRAIN_WATER:
                speed *= 0.5
            self.actor.setY(self.actor, speed * self.walkDir * dt)
        if self.rotationDir != 0:
            self.actor.setH(self.actor.getH() + 3.5 * self.rotationDir)
        # jump
        if self.state == Player.STATE_JUMP or self.state == Player.STATE_RUNJUMP:
            self.zVelocity = Player.JUMP_ACCEL
            log.debug("jump start at v=%f" % self.zVelocity)
            if self.state == Player.STATE_RUNJUMP:
                self.walkDir = -1
        # fall
        if self.state == Player.STATE_FALL:
            dZ = self.zVelocity * dt
            dV = Player.FALL_ACCEL * dt
            curZ = self.actor.getZ()
            newZ = curZ + dZ
            if self.jumpHeight == None and newZ < curZ:
                self.jumpHeight = self.zOffset
                log.debug("jump height=%f" % self.jumpHeight)
            log.debug(
                "falling... dt=%(dt)f getZ=%(getZ)f v=%(v)f dZ=%(dZ)f newZ=%(newZ)f dV=%(dV)f zOffset=%(zOff)f"
                % {
                    "dt": dt,
                    "getZ": self.actor.getZ(),
                    "v": self.zVelocity,
                    "dZ": dZ,
                    "newZ": newZ,
                    "dV": dV,
                    "zOff": self.zOffset
                })
            if newZ < self.terrainSurfZ: newZ = self.terrainSurfZ
            self.actor.setZ(newZ)
            self.zVelocity += dV
        # duck
        if self.state == Player.STATE_DUCK:
            if self.actor.getCurrentAnim() == "duck":
                collSphrZ = (self.actor.getCurrentFrame("duck") /
                             Player.DUCK_FRAME_MID) * 0.25
                self.collSphere2NP.setZ(-collSphrZ)

    def processTerrainRelation(
            self):  # -> [terrainZone, terrainSurfZ, zOffset, waterDepth]
        collEntries = self.collQRay.getEntries()
        newZone = None
        #
        if len(collEntries) == 0:
            #log.error("out of terrain, pos=%s"%str(self.actor.getPos()))
            newZone = Player.TERRAIN_NONE
            if newZone != self.terrainZone:
                self.onTerrainZoneChanged(Player.TERRAIN_NONE)
            self.terrainZone = newZone
            return Player.TERRAIN_NONE, 0, 0, 0
        #
        newZone = Player.TERRAIN_NONE
        gndZ, wtrZ = -1000, -1000
        waterDepth = 0
        for entry in collEntries:
            eName = entry.getIntoNodePath().getName()
            eZ = entry.getSurfacePoint(self.base.render).getZ()
            if eName.startswith("Water"):
                wtrZ = eZ
                if wtrZ > gndZ:
                    newZone = Player.TERRAIN_WATER
            else:
                if eZ > gndZ: gndZ = eZ
                if gndZ > wtrZ:
                    newZone = Player.TERRAIN_GROUND
        if newZone == Player.TERRAIN_WATER:
            waterDepth = gndZ - wtrZ
            #log.debug("water depth is %f"%waterDepth)
        zOffset = self.actor.getZ() - gndZ
        return newZone, gndZ, zOffset, waterDepth

    def onTerrainZoneChanged(self, zone):
        log.debug("terrain zone chaged to: %i" % zone)

    def onStateChanged(self, newState):
        curState = self.state
        log.debug("state change %s -> %s" % (str(curState), str(newState)))
        #self.actor.stop()
        if newState == Player.STATE_IDLE:
            self.actor.loop("idle")
        elif newState == Player.STATE_WALK:
            self.actor.setPlayRate(4.0, "walk")
            self.actor.loop("walk")
        elif newState == Player.STATE_RUN:
            self.actor.loop("run")
        elif newState == Player.STATE_JUMP or newState == Player.STATE_RUNJUMP:
            self.actor.setPlayRate(1.4, "jump")
            self.actor.play("jump", fromFrame=20, toFrame=59)
        elif newState == Player.STATE_DUCK:
            self.actor.play("duck", fromFrame=0, toFrame=Player.DUCK_FRAME_MID)
        elif newState == Player.STATE_UN_DUCK:
            initFrame = Player.DUCK_FRAME_MID
            if self.actor.getCurrentAnim() == "duck":
                initFrame = Player.DUCK_FRAME_COUNT - self.actor.getCurrentFrame(
                    "duck")
            self.actor.stop()
            self.actor.play("duck",
                            fromFrame=initFrame,
                            toFrame=Player.DUCK_FRAME_COUNT)

    def updateCollidedObjectsList(self):
        pass

    def update(self, task):
        # clock
        dt = self.base.taskMgr.globalClock.getDt()
        # keys
        self.defineKeys()
        # terrain relation
        newZone, self.terrainSurfZ, self.zOffset, self.waterDepth = self.processTerrainRelation(
        )
        if newZone != self.terrainZone:
            self.terrainZone = newZone
            self.onTerrainZoneChanged(self.terrainZone)
        # obstacles relation
        self.updateCollidedObjectsList()
        # state
        newState = self.defineState()
        if self.state != newState:
            self.onStateChanged(newState)
            self.state = newState
        self.processState(dt)
        # move
        return task.cont

    def dump_info(self):
        info = "position: %s\n" % str(self.actor.getPos())
        info += "hpr: %s\n" % str(self.actor.getHpr())
        info += "state: %s; sub_state: %s\n" % (str(
            self.state), str(self.sub_state))
        info += "terrainZone: %s\n" % str(self.terrainZone)
        info += "terrainSurfZ: %s\n" % str(self.terrainSurfZ)
        info += "zOffset: %s\n" % str(self.zOffset)
        log.info("*INFO:\n%s" % info)
Exemple #23
0
class Physics:
    def __init__(self):
        self.rayCTrav = CollisionTraverser("collision traverser for ray tests")
        #self.pusher = PhysicsCollisionHandler()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addInPattern('%fn-in-%in')
        self.pusher.addOutPattern('%fn-out-%in')
        self.pusher.addInPattern('%fn-in')
        self.pusher.addOutPattern('%fn-out')

    def startPhysics(self):
        #self.actorNode = ActorNode("playerPhysicsControler")
        #base.physicsMgr.attachPhysicalNode(self.actorNode)
        #self.actorNode.getPhysicsObject().setMass(self.player_mass)
        #self.mainNode = render.attachNewNode(self.actorNode)
        self.mainNode = render.attachNewNode("CharacterColliders")
        self.reparentTo(self.mainNode)

        charCollisions = self.mainNode.attachNewNode(CollisionNode(self.char_collision_name))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0))
        charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/2.0, self.player_height/4.0))
        charCollisions.node().setIntoCollideMask(BitMask32(0x80))  # 1000 0000
        if self.show_collisions:
            charCollisions.show()
        self.pusher.addCollider(charCollisions, self.mainNode)
        base.cTrav.addCollider(charCollisions, self.pusher)

        charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray"))
        charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1))
        #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1)))
        charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff())
        charFFootCollisions.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            charFFootCollisions.show()

        self.floor_handler = CollisionHandlerFloor()
        self.floor_handler.addCollider(charFFootCollisions, self.mainNode)
        #self.floor_handler.setOffset(0)
        self.floor_handler.setMaxVelocity(5)
        base.cTrav.addCollider(charFFootCollisions, self.floor_handler)

        self.accept("{}-in".format(self.char_collision_name), self.checkCharCollisions)

        self.raytest_segment = CollisionSegment(0, 1)
        self.raytest_np = render.attachNewNode(CollisionNode("testRay"))
        self.raytest_np.node().addSolid(self.raytest_segment)
        self.raytest_np.node().setIntoCollideMask(BitMask32.allOff())
        self.raytest_np.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            self.raytest_np.show()

        self.raytest_queue = CollisionHandlerQueue()
        self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue)

    def stopPhysics(self):
        self.raytest_segment.removeNode()
        self.pusher.clearColliders()
        self.floor_handler.clearColliders()
        self.rayCTrav.clearColliders()

    def updatePlayerPos(self, speed, heading, dt):
        if heading is not None:
            self.mainNode.setH(camera, heading)
            self.mainNode.setP(0)
            self.mainNode.setR(0)
        self.mainNode.setFluidPos(self.mainNode, speed)
        self.doStep()

    def checkCharCollisions(self, args):
        self.doStep()

    def doStep(self):
        # do the step height check
        tmpNP = self.mainNode.attachNewNode("temporary")
        tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight)
        pointA = self.mainNode.getPos(render)
        pointA.setZ(pointA.getZ() + self.player_height/1.8)
        pointB = tmpNP.getPos(render)
        if pointA == pointB: return
        char_step_collision = self.getFirstCollisionInLine(pointA, pointB)
        tmpNP.removeNode()
        if char_step_collision is not None:
            self.mainNode.setFluidZ(char_step_collision.getZ())
            return True
        return False

    def getFirstCollisionInLine(self, pointA, pointB):
        """A simple raycast check which will return the first collision point as
        seen from point A towards pointB"""
        self.raytest_segment.setPointA(pointA)
        self.raytest_segment.setPointB(pointB)
        self.rayCTrav.traverse(render)
        self.raytest_queue.sortEntries()
        pos = None
        if self.raytest_queue.getNumEntries() > 0:
            pos = self.raytest_queue.getEntry(0).getSurfacePoint(render)
        return pos
class Project(ShowBase):
    def __init__(self):

        ShowBase.__init__(self)
        self.win.setClearColor((0.455, 0.816, 0.945, 1))

        self.keyMap = {
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "jump": 0,
            "action": 0
        }

        # Mise en place des instructions
        self.title = addTitle("Project : 'Escape the forest'")
        self.inst1 = addInstructions(0.06, "[ECHAP]: Quit")
        self.inst2 = addInstructions(0.12, "[Left arrow]: Turn Freddy left")
        self.inst3 = addInstructions(0.18, "[Right arrow]: Turn Freddy right")
        self.inst4 = addInstructions(0.24,
                                     "[Top arrow]: Make Freddy move forward")
        self.inst5 = addInstructions(0.30,
                                     "Bottom arrow]: Make Freddy move back")
        self.inst6 = addInstructions(0.36, "[Space]: Make Freddy jump")
        self.inst7 = addInstructions(0.42, "[A]: Operate the lever")

        # 3D objects
        self.map = loader.loadModel("obj/Map.egg.pz")
        self.map.reparentTo(render)

        self.walls = loader.loadModel("obj/Wall.egg")
        self.walls.reparentTo(render)

        self.bridge = Actor("obj/Bridge.egg", {"Drop": "obj/Bridge.egg"})
        self.bridge.reparentTo(render)
        self.bridge.pose("Drop", 0)

        self.lever = Actor("obj/Lever.egg", {"OnOff": "obj/Lever.egg"})
        self.lever.reparentTo(render)
        self.lever.setPos(0, 12, 1)
        self.lever.pose("OnOff", 0)

        self.lever1 = Actor("obj/Lever.egg", {"OnOff": "obj/Lever.egg"})
        self.lever1.reparentTo(render)
        self.lever1.setPos(50, 16, 1)
        self.lever1.pose("OnOff", 0)

        self.lever2 = Actor("obj/Lever.egg", {"OnOff": "obj/Lever.egg"})
        self.lever2.reparentTo(render)
        self.lever2.setPos(22, 92, 1)
        self.lever2.pose("OnOff", 0)

        self.dirt = Actor("obj/Dirt.egg", {"Up": "obj/Dirt.egg"})
        self.dirt.reparentTo(render)

        self.stone = Actor("obj/Stone.egg", {"Fall": "obj/Stone.egg"})
        self.stone.reparentTo(render)

        # Creation of the main character, Freddy
        FreddyStartPos = (8, -8, 1.5)
        self.Freddy = Actor("obj/Freddy.egg", {
            "Run": "obj/Run.egg",
            "Pose": "obj/Pose.egg"
        })
        self.Freddy.reparentTo(render)
        self.Freddy.setScale(1.4)
        self.Freddy.setPos(FreddyStartPos)
        self.Freddy.setH(180)

        winsound.PlaySound("sound/music.wav", winsound.SND_ASYNC)

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.Freddy)
        self.floater.setZ(0)

        # Controls for move and interact

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["backward", True])
        self.accept("space", self.setKey, ["jump", True])
        self.accept("a", self.setKey, ["action", True])

        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["backward", False])
        self.accept("space-up", self.setKey, ["jump", False])
        self.accept("a-up", self.setKey, ["action", False])

        taskMgr.add(self.movement, "Movement")

        self.moving = False

        self.disableMouse()

        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))

        # Collisions
        self.cTrav = CollisionTraverser()
        self.pusher = CollisionHandlerPusher()
        self.FreddyGroundHandler = CollisionHandlerQueue()
        self.FreddyGroundSphere = CollisionSphere(
            0, 0, 0.5, 0.3)  #Coordinates of the center and radius
        self.FreddyGroundCol = CollisionNode('freddySphere')
        self.FreddyGroundCol.addSolid(self.FreddyGroundSphere)
        self.FreddyGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.FreddyGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.FreddyGroundColNp = self.Freddy.attachNewNode(
            self.FreddyGroundCol)
        self.cTrav.addCollider(self.FreddyGroundColNp,
                               self.FreddyGroundHandler)

        self.BridgeHandler = CollisionHandlerQueue()
        self.BridgeBox = CollisionBox((1, 17, 0), (5, 16.8, 10))
        self.BridgeCol = CollisionNode('bridgeBox')
        self.BridgeCol.addSolid(self.BridgeBox)
        self.BridgeCol.setFromCollideMask(BitMask32.allOff())
        self.BridgeCol.setIntoCollideMask(BitMask32.bit(0))
        self.BridgeColNp = self.bridge.attachNewNode(self.BridgeCol)
        self.cTrav.addCollider(self.BridgeColNp, self.BridgeHandler)
        self.pusher.addCollider(self.FreddyGroundColNp, self.BridgeColNp)

        self.StoneHandler = CollisionHandlerQueue()
        self.StoneBox = CollisionBox((39, 27, 0), (41, 31, 3))
        self.StoneCol = CollisionNode('stoneBox')
        self.StoneCol.addSolid(self.StoneBox)
        self.StoneCol.setFromCollideMask(BitMask32.allOff())
        self.StoneCol.setIntoCollideMask(BitMask32.bit(0))
        self.StoneColNp = self.stone.attachNewNode(self.StoneCol)
        self.cTrav.addCollider(self.StoneColNp, self.StoneHandler)
        self.pusher.addCollider(self.FreddyGroundColNp, self.StoneColNp)

        self.DirtHandler = CollisionHandlerQueue()
        self.DirtBox = CollisionBox((15, 83, 0), (13, 82.5, 5))
        self.DirtCol = CollisionNode('dirtBox')
        self.DirtCol.addSolid(self.DirtBox)
        self.DirtCol.setFromCollideMask(BitMask32.allOff())
        self.DirtCol.setIntoCollideMask(BitMask32.bit(0))
        self.DirtColNp = self.dirt.attachNewNode(self.DirtCol)
        self.cTrav.addCollider(self.DirtColNp, self.DirtHandler)
        self.pusher.addCollider(self.FreddyGroundColNp, self.DirtColNp)

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

    def movement(self, task):
        dt = globalClock.getDt()
        startpos = self.Freddy.getPos()

        speed = -5

        if self.keyMap["left"]:
            self.Freddy.setH(-90)
            self.Freddy.setY(self.Freddy, speed * dt)
        if self.keyMap["right"]:
            self.Freddy.setH(90)
            self.Freddy.setY(self.Freddy, speed * dt)
        if self.keyMap["forward"]:
            self.Freddy.setH(180)
            self.Freddy.setY(self.Freddy, speed * dt)
        if self.keyMap["backward"]:
            self.Freddy.setH(0)
            self.Freddy.setY(self.Freddy, speed * dt)

        relative_speed = 5 * math.sqrt(2) - 5
        if self.keyMap["left"] and self.keyMap["forward"]:
            self.Freddy.setH(-135)
            self.Freddy.setY(self.Freddy, relative_speed * dt)

        if self.keyMap["left"] and self.keyMap["backward"]:
            self.Freddy.setH(-45)
            self.Freddy.setY(self.Freddy, relative_speed * dt)

        if self.keyMap["right"] and self.keyMap["forward"]:
            self.Freddy.setH(135)
            self.Freddy.setY(self.Freddy, relative_speed * dt)

        if self.keyMap["right"] and self.keyMap["backward"]:
            self.Freddy.setH(45)
            self.Freddy.setY(self.Freddy, relative_speed * dt)

        deltax = self.lever.getX() - self.Freddy.getX()
        deltay = self.lever.getY() - self.Freddy.getY()
        deltaz = self.lever.getZ() - self.Freddy.getZ()

        deltax1 = self.lever1.getX() - self.Freddy.getX()
        deltay1 = self.lever1.getY() - self.Freddy.getY()
        deltaz1 = self.lever1.getZ() - self.Freddy.getZ()

        deltax2 = self.lever2.getX() - self.Freddy.getX()
        deltay2 = self.lever2.getY() - self.Freddy.getY()
        deltaz2 = self.lever2.getZ() - self.Freddy.getZ()

        delta = math.sqrt(deltax**2 + deltay**2 + deltaz**2)
        delta1 = math.sqrt(deltax1**2 + deltay1**2 + deltaz1**2)
        delta2 = math.sqrt(deltax2**2 + deltay2**2 + deltaz2**2)

        Animb = self.bridge.getAnimControl("Drop")
        self.bridgeOpen = Animb.getFrame()
        Anims = self.stone.getAnimControl("Fall")
        self.stoneOpen = Anims.getFrame()
        Animd = self.dirt.getAnimControl("Up")
        self.dirtOpen = Animd.getFrame()

        if delta < 3 and self.keyMap["action"]:
            if self.bridgeOpen == 0:
                self.lever.play("OnOff")
                self.BridgeCol.setIntoCollideMask(BitMask32.allOff())
                self.bridge.play("Drop")

        if delta1 < 3 and self.keyMap["action"]:
            if self.stoneOpen == 0:
                self.lever1.play("OnOff")
                self.StoneCol.setIntoCollideMask(BitMask32.allOff())
                self.stone.play("Fall")

        if delta2 < 3 and self.keyMap["action"]:
            if self.dirtOpen == 0:
                self.lever2.play("OnOff")
                self.DirtCol.setIntoCollideMask(BitMask32.allOff())
                self.dirt.play("Up")

        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap[
                "right"] or self.keyMap["backward"]:
            if self.moving is False:
                self.Freddy.loop("Run")
                self.moving = True
        else:
            if self.moving:
                self.Freddy.stop()
                self.Freddy.loop("Pose")
                self.moving = False

        if self.Freddy.getZ() < 1:
            self.Freddy.setZ(1)
        dt = globalClock.getDt()
        maxZ = 3.5
        if self.keyMap["jump"] == True and self.Freddy.getZ() <= 2:
            self.Freddy.setZ(self.Freddy.getZ() + 5 * dt)
            if self.Freddy.getZ() >= maxZ:
                self.Freddy.setZ(maxZ)
        if self.keyMap["jump"] == False and self.Freddy.getZ() >= 1:
            self.Freddy.setZ(self.Freddy, -2 * dt)

        # Collisions again
        self.cTrav.traverse(render)
        entries = []
        for i in range(self.FreddyGroundHandler.getNumEntries()):
            entry = self.FreddyGroundHandler.getEntry(i)
            entries.append(entry)
        if (len(entries) > 0) and (
            (entries[0].getIntoNode().getName() == "Htbox") or
            (entries[0].getIntoNode().getName() == "bridgeBox") or
            (entries[0].getIntoNode().getName() == "stoneBox") or
            (entries[0].getIntoNode().getName() == "dirtBox")):
            self.Freddy.setPos(startpos)

        camx = self.Freddy.getX() - self.camera.getX()
        if camx > 8.625 or camx < 8.625:
            self.camera.setX(self.Freddy.getX() + 8.625)

        camy = self.Freddy.getY() - self.camera.getY()
        if camy > -18.375 or camy < -18.375:
            self.camera.setY(self.Freddy.getY() - 18.375)

        camz = self.Freddy.getZ() - self.Freddy.getZ()
        if camz > 13.125 or camz < 13.125:
            self.camera.setZ(self.Freddy.getZ() + 13.125)

        self.camera.lookAt(self.floater)

        return task.cont
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)
        self.orbCollisionHandler = CollisionHandlerQueue()
        self.cTrav = CollisionTraverser()
        self.cTrav.setRespectPrevTransform(True)

        #hbPath = NodePath()

        utilsKristina2.setUpKeys(self)
        utilsKristina2.loadModels(self)
        utilsKristina2.setUpLighting(self)
        utilsKristina2.setUpFloatingSpheres(self)
        utilsKristina2.setUpRalphsShot(self)
        utilsKristina2.setUpCamera(self)
        utilsKristina2.setUpCollisionSpheres(self)
        self.healthTxt = utilsKristina2.addInstructions(.06,"Health: 100")
        self.orbTxt = utilsKristina2.addInstructions(.18,"Orbs: 0")

        self.vec = LVector3(0,1,0)#vector for pawns shot

        # Create a frame
        #frame = DirectFrame(text = "main", scale = 0.001)
        # Add button
        #bar = DirectWaitBar(text = "", value = 50, pos = (0,.4,.4))
        #bar.reparent(render)

        # Game state variables
        self.isMoving = False
        self.jumping = False
        self.vz = 0
        self.numOrbs = 0
        self.healthCount = 100

        #self.shotList = []




        #self.sphere = CollisionBox((self.ralph.getX() + -10,self.ralph.getY(),self.ralph.getZ()),10,10,10)
        self.sphere = CollisionSphere(0,-5,4,3)
        self.sphere3 = CollisionSphere(0,5,5,3)
        self.sphere4 = CollisionSphere(-4,0,5,2)
        self.sphere5 = CollisionSphere(4,0,5,2)
        self.sphere2 = CollisionSphere(0,0,3,2)
        self.cnodePath = self.ralph.attachNewNode((CollisionNode("ralphColNode")))
        self.cnodePath2 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck")))
        self.cnodePath3 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck2")))
        self.cnodePath4 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck3")))
        self.cnodePath5 = self.ralph.attachNewNode((CollisionNode("ralphWallCheck4")))
        self.cnodePath.node().addSolid(self.sphere2)
        self.cnodePath2.node().addSolid(self.sphere)
        self.cnodePath3.node().addSolid(self.sphere3)
        self.cnodePath4.node().addSolid(self.sphere4)
        self.cnodePath5.node().addSolid(self.sphere5)
        #self.cnodePath.node().addSolid(self.sphere2)
        self.cnodePath.show()
        #self.cnodePath2.show()
        #self.cnodePath3.show()
        #self.cnodePath4.show()
        #self.cnodePath5.show()
        self.cTrav.addCollider(self.cnodePath2, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath3, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath4, self.orbCollisionHandler)
        self.cTrav.addCollider(self.cnodePath5, self.orbCollisionHandler)


        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.cnodePath, self.ralph)

        #self.cTrav.addCollider(self.cnodePath, self.ralphCollisionHandler)
        self.cTrav.addCollider(self.cnodePath, self.pusher)


        self.chrisLastShotTime = globalClock.getFrameTime()
        self.chrisTimer = globalClock.getDt()

        #def __init__(self, pos,showbase, colPathName, dir, length):
        self.chrisList = [utilsKristina2.chris((15,0,0.5),self,"chrisColPath0","X",6), utilsKristina2.chris((18,29,0.5),self,"chrisColPath1","X",6),
                          utilsKristina2.chris((-6,67,0.5),self,"chrisColPath2","X",6), utilsKristina2.chris((-41,72,0.5),self,"chrisColPath7","X",6)]
                          #,utilsKristina2.chris((-42,106,0.5),self,"chrisColPath3","X",6)]#, utilsKristina2.chris((-62,108,0.5),self,"chrisColPath4","X",6),
                          #utilsKristina2.chris((-74,70,0.5),self,"chrisColPath5","y",6)]
        #def _init_(self,showbase,pos,color,speed,radius):
        self.orbList = [utilsKristina2.orb(self,(0,0,2),(0,0,1,1),20,4)]

        self.donutList = [utilsKristina2.donut(self,(0,0,2),40,3)]

        self.cameraCollided = False
        self.ralphSpeed = 60
        self.ralphHit = False
        self.ralphRedTime = 0
        self.ralphLife=True

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

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


    def startEnemyThread(self):
        showbase = self
        class enemyThread(threading.Thread):
            def run(self):
                dt = globalClock.getDt()
                for chris in showbase.chrisList:
                    chris.moveChris(dt,showbase,showbase.chrisList)

    def moveChris(self,task):
        dt = globalClock.getDt()
        for chris in self.chrisList:
            chris.moveChris(dt,self,self.chrisList)
        return task.cont

    # 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 that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()
        #utilsKristina2.moveChris(self,dt)
        #self.chris2.moveChris(dt,self)
        #self.startEnemyThread()


        if globalClock.getFrameTime()- self.ralphRedTime > .3 and self.ralphHit == True:
                self.ralph.clearColor()
                self.ralphHit = False

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

        if self.keyMap["cam-left"]:
            self.camera.setZ(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setZ(self.camera, +20 * dt)

        # 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"]:
            self.ralph.setH(self.ralph.getH() + 75 * dt)
            #self.camera.setX(self.camera, +15.5 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 75 * dt)
            #self.camera.setX(self.camera, -15.5 * dt)
        if self.keyMap["forward"]:
            self.ralph.setFluidY(self.ralph, -1*self.ralphSpeed * dt)
            #self.camera.setY(self.camera, -35 * dt)
        if self.keyMap["back"]:
            self.ralph.setFluidY(self.ralph, self.ralphSpeed * dt)
            #self.camera.setY(self.camera, 35 * dt)
        if self.keyMap["space"]:
            if self.jumping is False:
            #self.ralph.setZ(self.ralph.getZ() + 100 * dt)
                self.jumping = True
                self.vz = 8

        if self.keyMap["c"] or self.keyMap["enter"]:
            if self.keyMap["c"]:
                self.keyMap["c"]=False
            if self.keyMap["enter"]:
                self.keyMap["enter"] = False
            self.shotList[self.shotCount].lpivot.setPos(self.ralph.getPos())
            self.shotList[self.shotCount].lpivot.setZ(self.ralph.getZ() + .5)
            self.shotList[self.shotCount].lpivot.setX(self.ralph.getX() - .25)
            print self.ralph.getPos()

            #self.shotList.append(rShot)
            #self.lightpivot3.setPos(self.ralph.getPos())
            #self.lightpivot3.setZ(self.ralph.getZ() + .5)
            #self.lightpivot3.setX(self.ralph.getX() - .25)
            #self.myShot.setHpr(self.ralph.getHpr())
            #parent to ralph
            #node = NodePath("tmp")
            #node.setHpr(self.ralph.getHpr())
            #vec = render.getRelativeVector(node,(0,-1,0))
            #self.myShotVec = vec

            node = NodePath("tmp")
            node.setHpr(self.ralph.getHpr())
            vec = render.getRelativeVector(node,(0,-1,0))
            self.shotList[self.shotCount].vec = vec
            self.shotCount = (self.shotCount + 1) % 10


        for rs in self.shotList:
            rs.lpivot.setPos(rs.lpivot.getPos() + rs.vec * dt * 25 )
            #if shot is too far stop updating



        if self.jumping is True:
            self.vz = self.vz - 16* dt
            self.ralph.setZ(self.ralph.getZ() + self.vz * dt )
            if self.ralph.getZ() < 0:
                self.ralph.setZ(0)
                self.jumping = False
        else:
            if self.ralph.getZ() < 0.25:
                self.ralph.setZ(0.25)
            elif self.ralph.getZ() > 0.25:
                self.ralph.setZ(self.ralph.getZ() -7 * dt)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"] or self.keyMap["space"] or self.keyMap["forward"] or self.keyMap["back"]:
            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

        # update pawns shot or set up new shot after it reaches a certain distance
        node = NodePath("tmp")
        node.setHpr(self.pawn.getHpr())
        vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
        self.shot.setPos(self.shot.getPos() + self.vec * dt * 10 )
        if self.shot.getY() < -15 or self.shot.getY() > 30 or self.shot.getX() < 5 or self.shot.getX() > 15:
            self.shot.setPos(self.pawn.getPos() + (0,0,0))
            self.vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
            self.vec = render.getRelativeVector(node,(random.random() * random.randrange(-1,2),random.random() + 1,0))

        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.
        #self.camera.lookAt(self.floater)
        camvec = self.ralph.getPos() - self.camera.getPos()
        #camvec = Vec3(0,camvec.getY(),0)
        camdist = camvec.length()
        x = self.camera.getZ()
        camvec.normalize()
        #if camdist > 6.0:
        #    self.camera.setPos(self.camera.getPos() + camvec * (camdist - 6))
        #if camdist < 6.0:
        #    self.camera.setPos(self.camera.getPos() - camvec * (6 - camdist))

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #self.cTrav.traverse(render)

        # Adjust camera so it stays at same height
        if self.cameraCollided == False:
            if self.camera.getZ() < self.ralph.getZ() + 1 or self.camera.getZ() > self.ralph.getZ() + 1:
                self.camera.setZ(self.ralph.getZ() + 1)

        # 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.camera.lookAt(self.floater)


        entries = list(self.orbCollisionHandler.getEntries())
        if(len(entries) > 0):
            #self.lightpivot.reparentTo(NodePath())
            orbCollected = False
            self.cameraCollided = False
            self.ralphSpeed = 65
            for entry in self.orbCollisionHandler.getEntries():
                #print(entry)
                fromColNp = entry.getFromNodePath()
                toColNp = entry.getIntoNodePath()
                if fromColNp.getName() == "orbColPath" and toColNp.getName() == "ralphColNode":
                    if orbCollected == False:
                        fromColNp.getParent().reparentTo(NodePath())
                        self.orbTxt.destroy()
                        self.numOrbs += 1
                        str1 = "Orbs: " + str(self.numOrbs)
                        self.orbTxt = utilsKristina2.addInstructions(.18, str1)
                        orbCollected = True
                elif toColNp.getName() == "orbColPath" and fromColNp.getName() == "ralphColNode":
                    if orbCollected == False:
                        toColNp.getParent().reparentTo(NodePath())
                        self.orbTxt.destroy()
                        self.numOrbs += 1
                        str1 = "Orbs: " + str(self.numOrbs)
                        self.orbTxt = utilsKristina2.addInstructions(.18, str1)
                        orbCollected = True
                elif toColNp.getName() == "ralphOrbColPath" and (fromColNp.getName()[:-1] == "chrisColPath" or fromColNp.getName()[:-2] == "chrisColPath"):
                    toColNp.getParent().setZ(20)
                    for chriss in self.chrisList:
                        if chriss.chrisColName == fromColNp.getName():
                            chris = chriss
                            break

                    chris.chrisHealth = chris.chrisHealth - 1
                    chris.chris.setColor(1,0,0,1)
                    chris.chrisHit = True
                    chris.chrisRedTime = globalClock.getFrameTime()
                    #print chris.chrisRedTime
                    if chris.chrisHealth < 0:
                        fromColNp.getParent().removeNode()
                        chris.chrisAlive = False
                        chris.chrisShot.setZ(26)
                elif (toColNp.getName()[:-1] == "chrisColPath" or toColNp.getName()[:-2] == "chrisColPath") and fromColNp.getName() == "ralphOrbColPath":
                    fromColNp.getParent().setZ(20)
                    for chriss in self.chrisList:
                        if chriss.chrisColName == toColNp.getName():
                            chris = chriss
                            break

                    chris.chrisHealth = chris.chrisHealth - 1
                    chris.chris.setColor(1,0,0,1)
                    chris.chrisHit = True
                    chris.chrisRedTime = globalClock.getFrameTime()
                    #print chris.chrisRedTime
                    if chris.chrisHealth < 0:
                        toColNp.getParent().removeNode()
                        chris.chrisAlive = False
                        chris.chrisShot.setZ(26)
                elif toColNp.getName() == "enemyOrbColPath" and fromColNp.getName() == "ralphColNode":
                    toColNp.getParent().setZ(26)
                    self.healthTxt.destroy()
                    self.healthCount -= 3
                    str1 = "Health: " + str(self.healthCount)
                    self.healthTxt = utilsKristina2.addInstructions(.06, str1)
                    self.ralphHit = True
                    self.ralph.setColor((1,0,0,1))
                    self.ralphRedTime = globalClock.getFrameTime()
                    if self.healthCount <=0:
                        sys.exit()
                elif toColNp.getName() == "ralphColNode" and fromColNp.getName() == "enemyOrbColPath":
                    fromColNp.getParent().setZ(26)
                    self.healthTxt.destroy()
                    self.healthCount -= 3
                    str1 = "Health: " + str(self.healthCount)
                    self.healthTxt = utilsKristina2.addInstructions(.06, str1)
                    self.ralphHit = True
                    self.ralph.setColor((1,0,0,1))
                    self.ralphRedTime = globalClock.getFrameTime()
                    if self.healthCount <=0:
                        sys.exit()
                elif fromColNp.getName() == "ralphOrbColPath" and toColNp.getName() == "allinclusive":
                    fromColNp.getParent().setZ(50)
                elif toColNp.getName() == "ralphOrbColPath" and fromColNp.getName() == "allinclusive":
                    toColNp.getParent().setZ(50)
                elif fromColNp.getName() == "enemyOrbWallCheck" and toColNp.getName() == "allinclusive":
                    fromColNp.getParent().setZ(50)
                    #print toColNp.getName()
                elif toColNp.getName() == "enemyOrbWallCheck" and fromColNp.getName() == "allinclusive":
                    toColNp.getParent().setZ(50)
                    #print fromColNp.getName()

                elif fromColNp.getName() == "ralphWallCheck" and toColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(0,-1,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #fromColNp.getParent().setZ(26)
                    self.ralphSpeed = 25
                elif toColNp.getName() == "ralphWallCheck" and fromColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(0,-1,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #print "wtf"
                    #toColNp.getParent().setZ(26)
                    self.ralphSpeed = 25
                elif fromColNp.getName() == "ralphWallCheck2" and toColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(0,1,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #fromColNp.getParent().setZ(26)
                    self.ralphSpeed = 25
                elif toColNp.getName() == "ralphWallCheck2" and fromColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(0,1,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #self.camera.setPos(self.ralph.getPos())
                    #self.cameraCollided = True
                    self.ralphSpeed = 25
                elif fromColNp.getName() == "ralphWallCheck3" and toColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(-1,0,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #fromColNp.getParent().setZ(26)
                    self.ralphSpeed = 25
                    print "3"
                elif toColNp.getName() == "ralphWallCheck3" and fromColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(-1,0,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #self.camera.setPos(self.ralph.getPos())
                    #self.cameraCollided = True
                    self.ralphSpeed = 25
                    print "3"
                elif fromColNp.getName() == "ralphWallCheck4" and toColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(1,0,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #fromColNp.getParent().setZ(26)
                    self.ralphSpeed = 25
                    print "4"
                elif toColNp.getName() == "ralphWallCheck4" and fromColNp.getName() == "allinclusive":
                    #node = NodePath("tmp")
                    #node.setHpr(self.ralph.getHpr())
                    #vec = render.getRelativeVector(node,(1,0,0))
                    #self.ralph.setPos(self.ralph.getPos()-vec)
                    #self.camera.setPos(self.ralph.getPos())
                    #self.cameraCollided = True
                    self.ralphSpeed = 25
                    print "4"





        return task.cont
class RoamingRalphDemo(ShowBase):
    def __init__(self):
        # Set up the window, camera, etc.
        ShowBase.__init__(self)
	#self.setupCD()

        # Set the background color to black
       # self.win.setClearColor((0.6, 0.6, 1.0, 1.0))
#	self.fog = Fog('myFog')
#	self.fog.setColor(0, 0, 0)
#	self.fog.setExpDensity(.05)
#	render.setFog(self.fog)	
       # This is used to store which keys are currently pressed.
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0, "c":0, "back":0, "space":0}

        # Post the instructions
        #self.title = addTitle(
         #   "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.06, "[ESC]: Quit")
        self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward")
        #self.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left")
        #self.inst7 = addInstructions(0.36, "[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.room = loader.loadModel("models/room2.egg")
        self.room.reparentTo(render)
        #self.room.setScale(.1)
        self.room.setPos(0,0,-5)
        self.room.setShaderAuto()
	#self.room.writeBamFile("myRoom1.bam")
	#self.room.setColor(1,.3,.3,1)

	self.room2 = loader.loadModel("models/abstractroom2")
        self.room2.reparentTo(render)
        self.room2.setScale(.1)
        self.room2.setPos(-12,0,0)

        # Create the main character, Ralph

        #ralphStartPos = LVecBase3F(0,0,0) #self.room.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(0,0,0)
	#cs = CollisionSphere(0, 0, 0, 1)
	#cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
	#cnodePath.node().addSolid(cs)
	#cnodePath.node().setPos(0,0,0)
	#cnodePath.show()	
	
	self.gianteye = loader.loadModel("models/gianteye")
	self.gianteye.reparentTo(render)
	self.gianteye.setScale(.1)
	self.gianteye.setPos(10,10,0)	
	
	#self.bluefinal = loader.loadModel("models/chrysalis")
	#self.bluefinal.reparentTo(render)
	#self.bluefinal.setScale(.1)
	#self.bluefinal.setPos(7,7,0)	
	
	#self.blue = loader.loadModel("models/blue1")
	#self.blue.reparentTo(render)
	#self.blue.setScale(.1)
	#self.blue.setPos(10,5,0)
	
	self.chik = loader.loadModel("models/chik")
	self.chik.reparentTo(render)
	self.chik.setScale(.1)
	self.chik.setPos(3,13,0)	

        self.pawn = loader.loadModel("pawn")
        self.pawn.reparentTo(render)
        self.pawn.setPos(0,0,0)

        self.shot = loader.loadModel("models/icosphere.egg")
        self.shot.reparentTo(render)
        self.shot.setScale(.5)
        self.shot.setPos(0,0,1)
        self.shot.setColor(1,.3,.3,1)

        self.myShot = loader.loadModel("models/icosphere.egg")
        #self.myShot.reparentTo(render)
        self.myShot.setScale(.1)
        self.myShot.setPos(0,0,1)
        self.myShotVec = LVector3(0,0,0)

        self.lightpivot3 = render.attachNewNode("lightpivot3")
        self.lightpivot3.setPos(0, 0, 0)
        self.lightpivot3.hprInterval(10, LPoint3(0, 0, 0)).loop()
        plight3 = PointLight('plight2')
        plight3.setColor((0, .3,0, 1))
        plight3.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp3 = self.lightpivot3.attachNewNode(plight3)
        plnp3.setPos(0, 0, 0)
        self.room2.setLight(plnp3)
        self.room.setLight(plnp3)
        sphere3 = loader.loadModel("models/icosphere")
        sphere3.reparentTo(plnp3)
        sphere3.setScale(0.1)
        sphere3.setColor((0,1,0,1))

        # Create a floater object, which floats 2 units above ralph.  We
        # use this as a target for the camera to look at.

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(self.ralph)
        self.floater.setZ(8.0)

        # Accept the control keys for movement and rotation

        self.accept("escape", sys.exit)
        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["back", True])
        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("s", self.setKey, ["cam-right", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["back", False])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("s-up", self.setKey, ["cam-right", False])

        self.accept("space", self.setKey, ["space", True])
        self.accept("space-up", self.setKey, ["space", False])

        self.accept("c",self.setKey,["c",True])
        self.accept("c-up",self.setKey,["c",False])

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

        # Game state variables
        self.isMoving = False
        self.jumping = False
        self.vz = 0

        # Set up the camera
        self.disableMouse()
        self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 7, 3)
        self.camLens.setFov(60)

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

        def setupCollision(self):
	    cs = CollisionSphere(0,0,2,1)
	    cnodePath = self.ralph.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(cs)
	    cnodePath.show()
	    #for o in self.OBS:
		#ct = CollisionTube(0,0,0, 0,0,1, 0.5)
		#cn = o.attachNewNode(CollisionNode('ocnode'))
		#cn.node().addSolid(ct)
		#cn.show()
	    eyecs = CollisionSphere(0,0,4,5)
	    cnodePath = self.gianteye.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	 
	    eyecs = CollisionSphere(0,0,4,2)
	    cnodePath = self.chik.attachNewNode(CollisionNode('cnode'))
	    cnodePath.node().addSolid(eyecs)
	    cnodePath.show()	    
    
	    pusher = CollisionHandlerPusher()
	    pusher.addCollider(cnodePath, self.player)
	    self.cTrav = CollisionTraverser()
	    self.cTrav.add_collider(cnodePath,pusher)
	    self.cTrav.showCollisions(render)
	self.walls = self.room2.find("**/wall_collide")
	#self.walls.node().setIntoCollideMask(BitMask32.bit(0))

        self.cTrav = CollisionTraverser()
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0, 0, 9)
        self.ralphGroundRay.setDirection(0, 0, -1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.ralphGroundCol.setIntoCollideMask(CollideMask.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, 9)
        self.camGroundRay.setDirection(0, 0, -1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.camGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()

        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        self.sphere = CollisionSphere(0,0,4,2)
        self.sphere2 = CollisionSphere(0,0,2,2)
        self.cnodePath = self.ralph.attachNewNode((CollisionNode('cnode')))
        self.cnodePath.node().addSolid(self.sphere)
        self.cnodePath.node().addSolid(self.sphere2)
        self.cnodePath.show()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.cnodePath, self.ralph)
        self.cTrav.add_collider(self.cnodePath, self.pusher)
	
	self.eyecs = CollisionSphere(0,0,22,25)
	self.cnodePath1 = self.gianteye.attachNewNode(CollisionNode('cnode'))
	self.cnodePath1.node().addSolid(self.eyecs)
	self.cnodePath1.show()	
	self.pusher1 = CollisionHandlerPusher()
	self.pusher1.addCollider(self.cnodePath1, self.gianteye)
	self.cTrav.add_collider(self.cnodePath1, self.pusher1)	
	self.cTrav.showCollisions(render)
	
	self.eyeGroundRay = CollisionRay()
        self.eyeGroundRay.setOrigin(0, 0, 9)
        self.eyeGroundRay.setDirection(0, 0, -1)
        self.eyeGroundCol = CollisionNode('eyeRay')
        self.eyeGroundCol.addSolid(self.eyeGroundRay)
        self.eyeGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.eyeGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.eyeGroundColNp = self.gianteye.attachNewNode(self.eyeGroundCol)
        self.eyeGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.eyeGroundColNp, self.eyeGroundHandler)		

	self.chikcs = CollisionSphere(0,0,11,20)
	self.cnodePath2 = self.chik.attachNewNode(CollisionNode('cnode'))
	self.cnodePath2.node().addSolid(self.chikcs)
	self.cnodePath2.show()
	self.pusher2 = CollisionHandlerPusher()
	self.pusher2.addCollider(self.cnodePath, self.chik)
	self.cTrav.add_collider(self.cnodePath, self.pusher2)	
	self.cTrav.showCollisions(render)	
	
	self.chikGroundRay = CollisionRay()
        self.chikGroundRay.setOrigin(0, 0, 9)
        self.chikGroundRay.setDirection(0, 0, -1)
        self.chikGroundCol = CollisionNode('chikRay')
        self.chikGroundCol.addSolid(self.chikGroundRay)
        self.chikGroundCol.setFromCollideMask(CollideMask.bit(0))
        self.chikGroundCol.setIntoCollideMask(CollideMask.allOff())
        self.chikGroundColNp = self.chik.attachNewNode(self.chikGroundCol)
        self.chikGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.chikGroundColNp, self.chikGroundHandler)	
	

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

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

        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor((.3, .3, .3, .4))
        ambientLight2 = AmbientLight("ambientLight2")
        ambientLight2.setColor((1, 1, 1, 10))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((0, 0, -2))
        directionalLight.setColor((1, 1, 1, 1))
        directionalLight.setSpecularColor((1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        #self.environ.setLight(self.environ.attachNewNode(ambientLight2))
        render.setLight(render.attachNewNode(directionalLight))

        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(0, 0, 1.6)
        self.lightpivot.hprInterval(20, LPoint3(360, 0, 0)).loop()
        plight = PointLight('plight')
        plight.setColor((.7, .3, 0, 1))
        plight.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(5, 0, 0)
        self.room.setLight(plnp)
        sphere = loader.loadModel("models/icosphere")
        sphere.reparentTo(plnp)
        sphere.setScale(0.1)
        sphere.setColor((1,1,0,1))

        self.lightpivot2 = render.attachNewNode("lightpivot")
        self.lightpivot2.setPos(-16, 0, 1.6)
        self.lightpivot2.hprInterval(20, LPoint3(360, 0, 0)).loop()
        plight2 = PointLight('plight2')
        plight2.setColor((0, .4,.8, 1))
        plight2.setAttenuation(LVector3(0.7, 0.05, 0))
        plnp2 = self.lightpivot2.attachNewNode(plight2)
        plnp2.setPos(5, 0, 0)
        self.room2.setLight(plnp2)
        sphere2 = loader.loadModel("models/icosphere")
        sphere2.reparentTo(plnp2)
        sphere2.setScale(0.2)
        sphere2.setColor((0,0,1,1))

        self.vec = LVector3(0,1,0) 
	
    # 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 that elapsed since last frame.  We multiply this with
        # the desired speed in order to find out with which distance to move
        # in order to achieve that desired speed.
        dt = globalClock.getDt()

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

        if self.keyMap["cam-left"]:
            self.camera.setZ(self.camera, -20 * dt)
        if self.keyMap["cam-right"]:
            self.camera.setZ(self.camera, +20 * dt)

        # 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"]:
            self.ralph.setH(self.ralph.getH() + 150 * dt)
            #self.floater.setH(self.floater.getH() + 300 * dt)
            self.camera.setX(self.camera, +15.5 * dt)
        if self.keyMap["right"]:
            self.ralph.setH(self.ralph.getH() - 150 * dt)
            self.camera.setX(self.camera, -15.5 * dt)
        if self.keyMap["forward"]:
            self.ralph.setY(self.ralph, -35 * dt)
        if self.keyMap["back"]:
            self.ralph.setY(self.ralph, +35 * dt)
        if self.keyMap["c"]:
            if self.jumping is False:
            #self.ralph.setH(self.ralph.getH() + 300 * dt)
            #self.ralph.setZ(self.ralph.getZ() + 100 * dt)
                self.jumping = True
                self.vz = 7

        if self.keyMap["space"]:
            self.lightpivot3.setPos(self.ralph.getPos())
            self.lightpivot3.setZ(self.ralph.getZ() + .5)
            self.lightpivot3.setX(self.ralph.getX() - .25)
            #self.myShot.setHpr(self.ralph.getHpr())
            #parent
            node = NodePath("tmp")
            node.setHpr(self.ralph.getHpr())
            vec = render.getRelativeVector(node,(0,-1,0))
            self.myShotVec = vec

        self.lightpivot3.setPos(self.lightpivot3.getPos() + self.myShotVec * dt * 15 )

        if self.jumping is True:
            self.vz = self.vz - 16* dt
            self.ralph.setZ(self.ralph.getZ() + self.vz * dt )
            entries = list(self.ralphGroundHandler.getEntries())
            entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
            if len(entries) > 0 :
                if self.ralph.getZ() < 0:#entries[0].getSurfacePoint(render).getZ():
                    #self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
                    self.ralph.setZ(0)
                    self.jumping = False
        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"] or self.keyMap["c"] or self.keyMap["forward"] or self.keyMap["back"]:
            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

        node = NodePath("tmp")
        node.setHpr(self.ralph.getHpr())
        vec = render.getRelativeVector(node,(1,0,0))

        #self.ralph.setPos(self.ralph.getPos() + vec * dt * 20)

        node = NodePath("tmp")
        #self.pawn.getH()
        node.setHpr(self.pawn.getHpr())
        vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
        self.shot.setPos(self.shot.getPos() + self.vec * dt * 10 )
        if self.shot.getY() < -15 or self.shot.getY() > 15 or self.shot.getX() < -15 or self.shot.getX() > 15:
            self.shot.setPos(self.pawn.getPos() + (0,0,0))
            self.vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))
            self.vec = render.getRelativeVector(node,(random.random() * -0.8,random.random() + 1,0))

        # 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() - self.camera.getPos()
        #camvec.setZ(self.camera.getZ())
        camdist = camvec.length()
        x = self.camera.getZ()
        camvec.normalize()
        if camdist > 6.0:
            self.camera.setPos(self.camera.getPos() + camvec * (camdist - 6))
            camdist = 10.0
            #self.camera.setZ(self.camera, x)
        if camdist < 6.0:
            self.camera.setPos(self.camera.getPos() - camvec * (6 - camdist))
            camdist = 5.0
            #self.camera.setZ(self.camera, x)

        # Normally, we would have to call traverse() to check for collisions.
        # However, the class ShowBase that we inherit from has a task to do
        # this for us, if we assign a CollisionTraverser to self.cTrav.
        #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 = list(self.ralphGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        if self.jumping == False:
            if len(entries) > 0:# and entries[0].getIntoNode().getName() == "terrain":
                #self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
                pass
            else:
                self.ralph.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.

        entries = list(self.camGroundHandler.getEntries())
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())

        #if len(entries) > 0 and entries[0].getIntoNode().getName() == "ground":
            #self.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.5)
        if self.camera.getZ() < self.ralph.getZ() + 1 or self.camera.getZ() > self.ralph.getZ() + 1:
            self.camera.setZ(self.ralph.getZ() + 1)

        #self.camera.setZ(self.ralph.getZ() + 1.5)
        #self.camera.setP(self.camera, 130)

        # 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.camera.lookAt(self.floater)

        return task.cont
Exemple #27
0
class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        #Background sound (does not play infinitely)
        self.backgroundSound = base.loader.loadSfx("sounds/DireDireDocks.mp3")

        taskMgr.add(self.update, "moveTask")
        
        #Disable the mouse so that we may use it for our control scheme.
        self.props = WindowProperties()
        self.props.setSize(1920, 1080)
        self.props.setFullscreen(True)
        self.props.setCursorHidden(True)
        base.win.requestProperties(self.props)
        base.disableMouse()
        
        self.buildKeyMap()
        self.inMenu = True
        self.menuScreen = OnscreenImage("titlescreen.png", (0, .01, 0))
        self.menu()

    def initialize(self):
        self.timer = 0
        base.enableParticles()
        #base.setFrameRateMeter(True)

        ##########
        #
        # SETUP COLLISION HANDLERS AND FLAMIE'S MODEL
        #
        ##########
        
        #Create the collision handlers in order to build the level.
        WALL_MASK = BitMask32.bit(2)
        FLOOR_MASK = BitMask32.bit(1)
        
        #Start up the collision system
        self.cTrav = CollisionTraverser()

        #Determine how collisions with walls will be handled
        self.wallHandler = CollisionHandlerPusher()
        self.bobbing = False

        #Setup flamie's model
        self.flamieNP = base.render.attachNewNode(ActorNode('flamieNP'))
        self.flamieNP.reparentTo(base.render)
        self.flamie = loader.loadModel('models/Flame/body')
        self.flamie.setScale(.5)
        self.flamie.setTransparency(TransparencyAttrib.MAlpha)
        self.flamie.setAlphaScale(0)
        self.flamie.reparentTo(self.flamieNP)
        self.flamie.setCollideMask(BitMask32.allOff())
        flameLight = DirectionalLight("flameLight")
        fl = self.flamie.attachNewNode(flameLight)
        fl.setColor(255, 255, 255, 1)
        flameLight.setDirection((-5, -5, -5))
        self.flamie.setLight(fl)


        self.flamie2 = loader.loadModel("models/p.obj")
        self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f7.png"))
        self.flamie2.reparentTo(self.flamieNP)
        self.flamie2.setScale(4)
        self.flamie2OriZ = 2
        self.flamie2.setPos(-6.5, 0, self.flamie2OriZ) #(length, depth, height)
        self.flamie2.setLight(fl)
        self.flamie2.setTransparency(TransparencyAttrib.MAlpha)
        self.flamieFire = PointLight('fire')
        self.flamieFire.setColor(VBase4(1,1,1,1))
        self.flamieFire.setAttenuation((1,0,1))
        plnp = render.attachNewNode(self.flamieFire)
        plnp.setPos(self.flamieNP.getPos())
        self.flamielight = AmbientLight('light')
        self.flamielight.setColor(VBase4(1, 0.5, 0.6, 1))

        self.flamielight = self.flamie2.attachNewNode(self.flamielight)
        self.flamie2.setLight(self.flamielight)
        self.flamie2.setLight(plnp)
        self.mayFlamieBob = True

        #self.flamie2.setAlphaScale(0.5)

        '''self.tree = loader.loadModel("models/p2.obj")
        self.tree.setTexture(loader.loadTexture("deadTree.png"))
        self.tree.reparentTo(render)
        self.tree.setScale(4)
        self.tree.setPos(25,25,0) #(length, depth, height)
        self.tree.setLight(fl)
        self.tree.setTransparency(TransparencyAttrib.MAlpha)
        self.treelight = AmbientLight('light')
        self.treelight.setColor(VBase4(0.9, 0.9, 0.6, 1))
        self.treelight = self.tree.attachNewNode(self.treelight)
        self.tree.setLight(self.treelight)'''

        x = 150
        y = 20
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(7)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 4
        y = 90
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(6)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 3
        y = 120
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(4)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        x = 200
        y = 20
        offset1 = 0
        treeList2 = [loader.loadModel("models/p2.obj") for i in range(4)]
        for j in treeList2:
            k = random.randint(1, 100)
            if k%5 is 1 or k%5 is 2:
                j.setTexture(loader.loadTexture("deadTree.png"))
            else:
                j.setTexture(loader.loadTexture("tree.png"))
            j.reparentTo(render)
            j.setScale(random.randint(4,7))
            j.setTransparency(TransparencyAttrib.MAlpha)
            j.setPos(x + 3*offset1, y + 4*offset1, 0)
            treelight = AmbientLight('light')
            treelight = j.attachNewNode(treelight)
            j.setLight(treelight)
            offset1 = offset1 + random.randint(4, 10)

        ### Something that should look like water ###
        w = loader.loadModel("models/flatP.obj")
        w.setTexture(loader.loadTexture("ice.png"))
        w.reparentTo(render)
        w.setScale(75)
        w.setTransparency(TransparencyAttrib.MAlpha)
        w.setAlphaScale(.7)
        w.setLight(treelight)
        w.setPos(-200, 0, -10)

        self.waterOrigiZ = -10
        self.waterSecZ = -95
        self.waterThirdZ = -120
        self.water = w

        ### Reskying the sky ###
        w = loader.loadModel("models/biggerFlatP.obj")
        w.setTexture(loader.loadTexture("models/n2.jpg"))
        w.reparentTo(self.flamie2)
        w.setScale(15)
        w.setLight(treelight)
        w.setPos(-200, 450, -200) #(length, depth, height)

        #Give flamie gravity
        self.floorHandler = CollisionHandlerGravity()
        self.floorHandler.setGravity(9.81+100)
        self.floorHandler.setMaxVelocity(100)
        

        ##########
        #
        # GENERATING LEVEL PARTS
        #
        ##########
        self.ice_reset = ()
        self.start = PlatformSeg(LVector3(0,0,0))
        self.start.generateAllParts(render)
        self.checkpointCreator(70, 90, self.start.pos.z, 10)
        self.floater = False
        
        for p in self.start.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)

        
        self.lostWood = LostWood(LVector3(self.start.pos.x + 750, self.start.parts[0].pos.y + self.start.parts[0].wid, self.start.pos.z))
        self.lostWood.generateAllParts(render)
        self.checkpointCreator(self.lostWood.pos.x+120, self.lostWood.pos.y+150, self.lostWood.pos.z,20)
        self.checkpointCreator(self.lostWood.parts[6].pos.x + self.lostWood.parts[6].len/2, self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid/2, self.lostWood.pos.z, 40)
        
        for p in self.lostWood.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)
            
        self.cave = Cave(LVector3(self.lostWood.pos.x + 1100, self.lostWood.pos.y + 2000, self.lostWood.pos.z - 50))
        self.cave.generateAllParts(render)
        self.checkpointCreator(self.cave.thirdRoomParts[5].pos.x + self.cave.thirdRoomParts[5].len/2,
                               self.cave.thirdRoomParts[5].pos.y + self.cave.thirdRoomParts[5].wid/2,
                               self.cave.thirdRoomParts[5].pos.z, 30)
        
        for p in self.cave.parts:
            if isinstance(p, Prism):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, p.dep, 'terraincollision', 'wallcollision')
            if isinstance(p, Square):
                self.collisionBoxCreator(p.pos.x, p.pos.y, p.pos.z, p.len, p.wid, 3,  'terraincollision', 'wallcollision')
            if isinstance(p, IceCube):
                p.model.setCollideMask(BitMask32.allOff())
                self.ice_reset += (p,)
                iceCubefloor= p.model.find("**/iceFloor")
                iceCubewall = p.model.find("**/iceWall")
                iceCubefloor.node().setIntoCollideMask(FLOOR_MASK)
                iceCubewall.node().setIntoCollideMask(WALL_MASK)

        self.end = End(LVector3(self.cave.thirdRoomParts[8].pos.x - 200,
                       self.cave.thirdRoomParts[8].pos.y + self.cave.thirdRoomParts[8].wid,
                       self.cave.thirdRoomParts[8].pos.z))
        self.end.generate(render)
        self.collisionBoxCreator(self.end.floor.pos.x, self.end.floor.pos.y, self.end.floor.pos.z,
                                 self.end.floor.len, self.end.floor.wid, self.end.floor.dep,
                                 'terraincollision', 'wallcollision')
        #########
        # DRAWING THE CABIN AND FINAL CAMPFIRE
        #########
        self.checkpointCreator(self.end.floor.pos.x + self.end.floor.len/2,
                               self.end.floor.pos.y + self.end.floor.wid/2,
                               self.end.floor.pos.z, 30)
        self.cabin = loader.loadModel("models/p2.obj")
        self.cabin.setTexture(loader.loadTexture("models/cabin.png"))
        self.cabin.setScale(50)
        self.cabin.reparentTo(render)
        self.cabin.setPos(self.end.floor.pos.x + self.end.floor.len/2,
                          self.end.floor.pos.y + self.end.floor.wid/1.1,
                          self.end.floor.pos.z)
        self.cabin.setTransparency(TransparencyAttrib.MAlpha)
        

        #Manually creating starting position. Copy and paste the first three parameters of the checkpoint you want to start at.
        self.startPos = LVector3(70, 90, self.start.pos.z)
        self.flamieNP.setPos(self.startPos)


        '''#Testing the tree model
        self.tree = loader.loadModel('models/Tree/log')
        self.tree.reparentTo(render)
        self.tree.setPos(-50,0,100)
        self.tree.setScale(2)'''

        '''#Add sky background
        self.sky = loader.loadModel('models/sphere.obj')
        self.sky.reparentTo(self.camera)
        self.sky.set_two_sided(True)
        self.skyTexture = loader.loadTexture("models/n2.jpg")
        self.sky.setTexture(self.skyTexture)
        self.sky.set_bin('background', 0)
        self.sky.set_depth_write(False)
        self.sky.set_compass()'''

        ##########
        #
        # CREATE FLAMIE'S COLLISION GEOMETRY
        #
        ##########
        
        #Give flamie a collision sphere in order to collide with walls
        flamieCollider = self.flamie.attachNewNode(CollisionNode('flamiecnode'))
        flamieCollider.node().addSolid(CollisionSphere(0,0,0,5))
        flamieCollider.node().setFromCollideMask(WALL_MASK)
        flamieCollider.node().setIntoCollideMask(BitMask32.allOff())
        self.wallHandler.addCollider(flamieCollider, self.flamieNP)
        self.cTrav.addCollider(flamieCollider, self.wallHandler)

        #Give flamie a collision ray to collide with the floor
        flamieRay = self.flamie.attachNewNode(CollisionNode('flamieRay'))
        flamieRay.node().addSolid(CollisionRay(0,0,8,0,0,-1))
        flamieRay.node().setFromCollideMask(FLOOR_MASK)
        flamieRay.node().setIntoCollideMask(BitMask32.allOff())
        self.floorHandler.addCollider(flamieRay, self.flamieNP)
        self.cTrav.addCollider(flamieRay, self.floorHandler)

        #Add a sensor that lets us melt ice cubes without standing on the cube.
        meltSensor = self.flamie.attachNewNode(CollisionNode('meltSensor'))
        cs = CollisionSphere(-2,0,10, 50)
        meltSensor.node().addSolid(cs)
        meltSensor.node().setFromCollideMask(WALL_MASK)
        meltSensor.node().setIntoCollideMask(BitMask32.allOff())
        cs.setTangible(0)
        self.wallHandler.addCollider(meltSensor, self.flamieNP)
        self.cTrav.addCollider(meltSensor, self.wallHandler)
        self.wallHandler.addInPattern('%fn-into-%in')
        self.wallHandler.addAgainPattern('%fn-again-%in')
        self.accept('meltSensor-into-iceWall', self.melt)
        self.accept('meltSensor-again-iceWall', self.melt)
        self.accept('meltSensor-into-checkpointCol', self.newstart)
        
        #Add in an event handle to prevent the jumping glitch found on the bobbing ice cubes.
        self.floorHandler.addInPattern('%fn-into-%in')
        self.floorHandler.addAgainPattern('%fn-again-%in')
        self.floorHandler.addOutPattern('%fn-out-%in')
        self.accept('flamieRay-into-iceFloor', self.jittercancel)
        self.accept('flamieRay-again-iceFloor', self.jittercancel)
        self.accept('flamieRay-out-iceFloor', self.jittercanceloff)

        
        #Uncomment these lines to see flamie's collision geometry
        #flamieCollider.show()
        #flamieRay.show()
        #meltSensor.show()

        #Uncomment this line to see the actual collisions.
        #self.cTrav.showCollisions(render)
        
        #This plane is found at the very bottom of the level and adds global gravity.
        killfloor = CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,-1000)))
        killfloorCol = CollisionNode('kfcollision')
        killfloorCol.addSolid(killfloor)
        killfloorCol.setIntoCollideMask(BitMask32.bit(1))
        killfloorColNp = self.render.attachNewNode(killfloorCol)

        ####################
        #
        #   Setting light so that we could see the definition in the walls
        #
        ####################
        
        render.setShaderAuto()
        self.dlight = DirectionalLight('dlight')
        self.dlight.setColor(LVector4(0.3, 0.1, 0.7, 1))
        dlnp = render.attachNewNode(self.dlight)
        dlnp.setHpr(90, 20, 0)
        render.setLight(dlnp)

        self.alight = render.attachNewNode(AmbientLight("Ambient"))
        self.alight.node().setColor(LVector4(0.5, 0.5, 1, .1))
        render.setLight(self.alight)

        self.snow = loader.loadTexture("models/ground.jpg")

        #Create a floater object and have it float 2 units above fireball.
        #And use this as a target for the camera to focus on.
        #This idea is taken from the roaming ralph sample that came with the
        #Panda3D SDK.
        self.camFocus = NodePath(PandaNode("floater"))
        self.camFocus.reparentTo(render)
        self.camFocusCurrZ = self.flamie.getZ() + 10

        #The camera is locked to the avatar so it always follows regardless of movement.
        self.camera.reparentTo(render)
        self.cameraTargetHeight = 8.0
        self.cameraDistance = 100
        self.cameraHeightModes = (self.start.parts[0].pos.z + 45, self.start.parts[0].pos.z + 125, self.camFocus.getZ() + 10, self.camFocus.getZ() + 150,
                                  self.end.floor.pos.z + 10)
        self.cameraHeight = self.cameraHeightModes[0]

        
    #################
    #   Changes Camera orientation depending on where the player is in the stage to compensate for the fact that
    #   the player has no direct control of the camera.
    #   Checks using the arrays from the level parts.
    ##################
    def cameraModes(self, delta):
        #Is the fireball within the platforming section between the starting area and the lost woods?
        #Is the fireball near the simple platforming sections of the LostWoods?
        #Is the fireball near the drop off point into the cave?
        #Is the fireball near the entrance to the second room in the cave?
        #If yes to any of these, bring the camera up to give a bird's eye view of the platforming
        if ((self.flamieNP.getX() > self.start.parts[1].pos.x and self.flamieNP.getY() > self.start.parts[1].pos.y - self.start.parts[1].wid
            and self.flamieNP.getX() < self.lostWood.parts[0].pos.x)
            or (self.flamieNP.getX() > self.lostWood.parts[0].pos.x + self.lostWood.parts[0].len/1.1
                and self.flamieNP.getX() < self.lostWood.parts[2].pos.x + self.lostWood.parts[0].len/11
                and self.flamieNP.getY() < self.lostWood.parts[0].pos.y + self.lostWood.parts[0].wid)
            or (self.flamieNP.getY() > self.cave.parts[0].pos.y - 20 and self.flamieNP.getY() <= self.cave.parts[0].pos.y + self.cave.parts[0].wid/2)
            or (self.flamieNP.getX() < self.cave.parts[1].pos.x + self.cave.parts[1].wid/10 and self.flamieNP.getY() >= self.cave.parts[1].pos.x)):
                camMode = 1
        #Is the fireball in the beginning of the cave area?
        #If yes, bring the camera closer
        elif self.flamieNP.getY() > self.cave.parts[1].pos.y - self.cave.parts[0].wid/2 and self.flamieNP.getY() < self.cave.thirdRoomParts[5].pos.y:
            camMode = 2
        else:
            camMode = 0

        if self.flamieNP.getY() >= self.cave.thirdRoomParts[6].pos.y:
            self.cave.thirdRoomParts[0].hide()
            camMode = 3
        if self.flamieNP.getY() >= self.cave.thirdRoomParts[8].pos.y + self.cave.thirdRoomParts[8].wid/1.5:
            camMode = 4

        self.lerpCam(camMode, delta)

    def lerpCam(self, camMode, delta):
        CAMLERPSPEED = 25
        if camMode == 0:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
        elif camMode == 1:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta >= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    if self.cameraHeight < self.cameraHeightModes[camMode]:
                        self.cameraHeight = self.cameraHeight + CAMLERPSPEED * delta
                    else:
                        self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
        elif camMode == 2:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                    self.camFocusCurrZ = self.flamieNP.getZ() + 10
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * delta
                    self.camFocusCurrZ = self.flamieNP.getZ() + 10
        elif camMode == 3:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight + CAMLERPSPEED * 3 * delta >= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight + CAMLERPSPEED * 3 * delta
        elif camMode == 4:
            if not self.cameraHeight == self.cameraHeightModes[camMode]:
                if self.cameraHeight - CAMLERPSPEED * 3 * delta <= self.cameraHeightModes[camMode]:
                    self.cameraHeight = self.cameraHeightModes[camMode]
                else:
                    self.cameraHeight = self.cameraHeight - CAMLERPSPEED * 3 * delta

    def waterControl(self, delta):
        WATERLERPSPEED = .75
        if self.flamieNP.getY() <= self.lostWood.parts[6].pos.y + self.lostWood.parts[6].wid/2:
            if not self.water.getZ() == self.waterOrigiZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterOrigiZ and self.water.getZ() > self.waterOrigiZ:
                    self.water.setZ(self.waterOrigiZ)
                elif self.water.getZ() + WATERLERPSPEED * delta > self.waterOrigiZ and self.water.getZ() < self.waterOrigiZ:
                    self.water.setZ(self.waterOrigiZ)
                else:
                    if self.water.getZ() > self.waterOrigiZ:
                        self.water.setZ(self.water, - WATERLERPSPEED * delta)
                        if self.water.getZ() < self.waterOrigiZ:
                            self.water.setZ(self.waterOrigiZ)
                    else:
                        self.water.setZ(self.water, + WATERLERPSPEED * delta)
                        if self.water.getZ() > self.waterOrigiZ:
                            self.water.setZ(self.waterOrigiZ)
        elif self.flamieNP.getY() <= self.cave.parts[1].pos.y:
            if not self.water.getZ() == self.waterSecZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterSecZ:
                    self.water.setZ(self.waterSecZ)
                else:
                    self.water.setZ(self.water, - WATERLERPSPEED * delta)
        else:
            if not self.water.getZ() == self.waterThirdZ:
                if self.water.getZ() - WATERLERPSPEED * delta < self.waterThirdZ:
                    self.water.setZ(self.waterThirdZ)
                else:
                    self.water.setZ(self.water, - WATERLERPSPEED * delta)
        
        
    def reset(self):
        self.flamieNP.setPos(self.startPos)
        self.camFocusCurrZ = self.flamieNP.getZ() + 10
        for p in self.ice_reset:
            p.model.setScale(p.original_scale)
        
    def jump(self, dt):
        if self.bobbing:
            if self.floorHandler.getAirborneHeight() < 0.15:
                self.floorHandler.addVelocity(60) 
        elif self.floorHandler.isOnGround():
            self.floorHandler.addVelocity(60)

    def jittercancel(self, collEntry):
        model = collEntry.getIntoNodePath().getParent()
        modelRef = model.getPythonTag("iceRef")
        if model.getScale()[0] > 1.2:
            model.setScale(model.getScale()- modelRef.meltspeed)

        self.bobbing = True

    def jittercanceloff(self, collEntry):
        self.bobbing = False

    def melt(self, collEntry):
        model = collEntry.getIntoNodePath().getParent()
        modelRef = model.getPythonTag("iceRef")
        if model.getScale()[0] > 1.2 and self.bobbing != True:
            model.setScale(model.getScale()- modelRef.meltspeed)

    def newstart(self, collEntry):
        entry = collEntry.getInto().getCenter()
        self.startPos = (entry[0]+10, entry[1]+10, entry[2] +10)
        cp = loader.loadModel('models/Campfire/fire')
        cp.setPos(entry[0],entry[1], entry[2])
        cp.reparentTo(render)
            
    def buildKeyMap(self):
        self.keyMap = {"left": 0, "right": 0, "forward": 0, "back": 0, "down": 0, "up": 0, "lookUp": 0, "lookDown": 0, "lookLeft": 0, "lookRight": 0}

        #I changed the control scheme let me know if you would like me to try something else.
        #WASD for movement, space for jump
        self.accept("escape", sys.exit)
        self.accept("a", self.setKey, ["left", True])
        self.accept("a-up", self.setKey, ["left", False])
        self.accept("d", self.setKey, ["right", True])
        self.accept("d-up", self.setKey, ["right", False])
        self.accept("w", self.setKey, ["forward", True])
        self.accept("w-up", self.setKey, ["forward", False])
        self.accept("s", self.setKey, ["back", True])
        self.accept("s-up", self.setKey, ["back", False])
        self.accept("space", self.setKey, ["down", True])
        self.accept("space-up", self.setKey, ["down", False])
        self.accept("shift", self.setKey, ["up", True])
        self.accept("shift-up", self.setKey, ["up", False])

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

    def update(self, task):
        delta = globalClock.getDt()
        if not self.inMenu:
            SPEED = 125
            #Variable that holds what direction the player is inputting
            fblr = 0
            self.timer += delta * 25

            self.killPlane = self.water.getZ() - 25
            if self.flamieNP.getZ() < self.killPlane:
                self.reset()
                
            if self.keyMap["left"]:
                fblr = 1
                old_fblr = fblr
                self.flamieNP.setX(self.flamie, - SPEED * delta)
            if self.keyMap["right"]:
                fblr = 2
                old_fblr = fblr
                self.flamieNP.setX(self.flamie, + SPEED * delta)
            if self.keyMap["forward"]:
                fblr = 3
                old_fblr = fblr
                self.flamieNP.setY(self.flamie, + SPEED * delta)
            if self.keyMap["back"]:
                fblr = 4
                old_fblr = fblr
                self.flamieNP.setY(self.flamie, - SPEED * delta)
            if self.keyMap["up"]:
                #self.flamieNP.setZ(self.flamie, - SPEED * dt)
                self.reset()
                #self.cameraDistance = 20+self.cameraDistance
            if self.keyMap["down"] and self.timer > 1:
                #self.flamieNP.setZ(self.flamie, + SPEED * dt)
                self.timer = 0
                self.jump(delta)
                
            if fblr == 1:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f8.png"))
            elif fblr == 2:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f6.png"))
            elif fblr == 3:
                if old_fblr == 1:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f1.png"))
                elif old_fblr == 2:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f4.png"))
                else:
                    self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f3.png"))
            else:
                self.flamie2.setTexture(loader.loadTexture("models/flamie2D/f7.png"))

            if self.floorHandler.isOnGround:
                self.flamieBob(delta)

            #The camera control is borrowed from Kristina's Tech Demo
            #This is also a demo found at: http://www.panda3d.org/forums/viewtopic.php?t=8452

            '''# mouse-controlled camera begins

            # Use mouse input to turn both the Character and the Camera
            if base.mouseWatcherNode.hasMouse():
                md = base.win.getPointer(0)
                x = md.getX()
                y = md.getY()
                deltaX = md.getX() - 200
                deltaY = md.getY() - 200
                # reset mouse cursor position
                base.win.movePointer(0, 200, 200)
                # alter flamie's yaw by an amount proportionate to deltaX
                self.flamie.setH(self.flamie.getH() - 0.3* deltaX)
                # find the new camera pitch and clamp it to a reasonable range
                self.cameraPitch = self.cameraPitch + 0.1 * deltaY
                if (self.cameraPitch < -60): self.cameraPitch = -60
                if (self.cameraPitch >  80): self.cameraPitch =  80
                base.camera.setHpr(0,self.cameraPitch,0)
                # set the camera at around ralph's middle
                # We should pivot around here instead of the view target which is noticebly higher
                base.camera.setPos(0,0,self.cameraTargetHeight/2)
                # back the camera out to its proper distance
                base.camera.setY(base.camera,self.cameraDistance)

            # point the camera at the view target
            viewTarget = Point3(0,0,self.cameraTargetHeight)
            base.camera.lookAt(viewTarget)
            # reposition the end of the  camera's obstruction ray trace
            #self.cameraRay.setPointB(base.camera.getPos())

            # mouse-controlled camera ends'''

            self.waterControl(delta)
            self.water.setX(self.flamieNP.getX() - 250)
            self.water.setY(self.flamieNP.getY() - 250)
            self.cameraModes(delta)
            base.camera.setPos(self.flamieNP.getX(), self.flamieNP.getY() - self.cameraDistance, self.cameraHeight)
            self.camFocus.setPos(self.flamieNP.getX(), self.flamieNP.getY(), self.camFocusCurrZ)
            base.camera.lookAt(self.camFocus)


            '''
            ######################
            #
            # SIMPLE OCCLUSION FOR START AREA
            #
            ######################

            for p in self.start.parts:
                if p.type == 'IceCube':
                    if math.fabs((math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY()))
                    - math.sqrt((self.camFocus.getX() * self.camFocus.getX()) + (self.camFocus.getY() * self.camFocus.getY())))) <= 400:
                        p.show()
                        #Ice cube movement
                        p.bob(delta)
                    else:
                        p.hide()
                    
                if p.type == 'Prism':
                    if p.type == 'Prism':
                        if math.fabs((math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y))
                        - math.sqrt((self.camFocus.getX() * self.camFocus.getX()) + (self.camFocus.getY() * self.camFocus.getY())))) <= 1000:
                            p.show()
                        else:
                            p.hide()


            ######################
            #
            # SIMPLE OCCLUSION FOR CAVE PARTS
            #
            ######################
            for p in self.cave.parts:
                if p.type == 'Prism':
                    if math.fabs((math.sqrt((p.pos.x * p.pos.x) + (p.pos.y * p.pos.y))
                    - math.sqrt((self.flamieNP.getX() * self.flamieNP.getX()) + (self.flamieNP.getY() * self.flamieNP.getY())))) <= 2500:
                        p.show()
                    else:
                        p.hide()
                    
                if p.type == 'IceCube':
                    if math.fabs((math.sqrt((p.model.getX() * p.model.getX()) + (p.model.getY() * p.model.getY()))
                    - math.sqrt((self.flamieNP.getX() * self.flamieNP.getX()) + (self.flamieNP.getY() * self.flamieNP.getY())))) <= 2000:
                        p.show()

                        #Ice cube movement
                        self.cave.moveIceCubes(delta/25)
                        for p in self.cave.iceCubesThirdRoom:
                            p.bob(delta/25)
                        for p in self.cave.iceCubesSecondRoom:
                            p.bob(delta/25)
                        self.cave.bigCube.bob(delta/25)

                        for p in self.start.iceCubes:
                            p.bob(delta)
                    else:
                        p.hide()
            '''

            #Ice cube movement
            self.cave.moveIceCubes(delta)
            for p in self.cave.iceCubesThirdRoom:
                p.bob(delta)
            for p in self.cave.iceCubesSecondRoom:
                p.bob(delta)
            self.cave.bigCube.bob(delta)

            for p in self.start.iceCubes:
                p.bob(delta)

        elif self.inMenu:
            self.menu()


            

        if self.backgroundSound.status() is not self.backgroundSound.PLAYING:
            self.backgroundSound.play()

            
        return task.cont

    def menu(self):
        if self.keyMap["down"]:
            self.inMenu = False
            self.menuScreen.destroy()
            self.initialize()
            

    def flamieBob(self, delta):
        if self.mayFlamieBob:
            self.flamie2.setZ(self.flamie2.getZ() + .5*delta)
            if self.flamie2.getZ() - self.flamie2OriZ > 1:
                self.mayFlamieBob = False
        else:
            self.flamie2.setZ(self.flamie2.getZ() - .5*delta)
            if self.flamie2.getZ() - self.flamie2OriZ < -2:
                self.mayFlamieBob = True
        
    #Function to create a box collision using six polygon. The top face is created as terrain and thus provides gravity.
    #While the rest of the faces only act as wall pushers.
    def collisionBoxCreator(self, posx, posy, posz, length, width, height, floorname, wallname):
        ret = ()
        #Create top face
        terrain = CollisionPolygon(Point3(posx, posy+width, posz), Point3(posx, posy, posz),
                                Point3(posx+length, posy, posz), Point3(posx+length, posy+width, posz))
        terrainCol = CollisionNode(floorname)
        terrainCol.addSolid(terrain)
        terrainCol.setIntoCollideMask(BitMask32.bit(1))
        terrainColNp = self.render.attachNewNode(terrainCol)
        self.cTrav.addCollider(terrainColNp, self.floorHandler)
        ret += (terrainColNp,)
    
        #Create left face
        sideLeft = CollisionPolygon(Point3(posx, posy+width, posz-height), Point3(posx, posy, posz-height),
                                Point3(posx, posy, posz), Point3(posx, posy+width, posz))
        sideLeftCol = CollisionNode(wallname)
        sideLeftCol.addSolid(sideLeft)
        sideLeftCol.setIntoCollideMask(BitMask32.bit(2))
        sideLeftColNp = self.render.attachNewNode(sideLeftCol)
        self.cTrav.addCollider(sideLeftColNp, self.wallHandler)
        ret += (sideLeftColNp,)
        
        #Create right face
        sideRight = CollisionPolygon(Point3(posx+length, posy+width, posz), Point3(posx+length, posy, posz),
                                Point3(posx+length, posy, posz-height), Point3(posx+length, posy+width, posz-height))
        sideRightCol = CollisionNode(wallname)
        sideRightCol.addSolid(sideRight)
        sideRightCol.setIntoCollideMask(BitMask32.bit(2))
        sideRightColNp = self.render.attachNewNode(sideRightCol)
        self.cTrav.addCollider(sideRightColNp, self.wallHandler)
        ret += (sideRightColNp,)
        
        #Create front face
        sideFront = CollisionPolygon(Point3(posx, posy+width, posz-height), Point3(posx, posy+width, posz),
                                Point3(posx+length, posy+width, posz), Point3(posx+length, posy+width, posz-height))
        sideFrontCol = CollisionNode(wallname)
        sideFrontCol.addSolid(sideFront)
        sideFrontCol.setIntoCollideMask(BitMask32.bit(2))
        sideFrontColNp = self.render.attachNewNode(sideFrontCol)
        self.cTrav.addCollider(sideFrontColNp, self.wallHandler)
        ret += (sideFrontColNp,)
        
        #Create back face
        sideBack = CollisionPolygon(Point3(posx, posy, posz), Point3(posx, posy, posz-height),
                                Point3(posx+length, posy, posz-height), Point3(posx+length, posy, posz))
        sideBackCol = CollisionNode(wallname)
        sideBackCol.addSolid(sideBack)
        sideBackCol.setIntoCollideMask(BitMask32.bit(2))
        sideBackColNp = self.render.attachNewNode(sideBackCol)
        self.cTrav.addCollider(sideBackColNp, self.wallHandler)
        ret += (sideBackColNp,)

        #Create bottom face
        sideBot = CollisionPolygon(Point3(posx, posy, posz-height), Point3(posx, posy+width, posz-height),
                                Point3(posx+length, posy+width, posz-height), Point3(posx+length, posy, posz-height))
        sideBotCol = CollisionNode(wallname)
        sideBotCol.addSolid(sideBot)
        sideBotCol.setIntoCollideMask(BitMask32.bit(2))
        sideBotColNp = self.render.attachNewNode(sideBotCol)
        self.cTrav.addCollider(sideBotColNp, self.wallHandler)
        ret += (sideBotColNp,)

        #Uncomment these lines to see the collision polygons.
        '''terrainColNp.show()
        sideLeftColNp.show()
        sideRightColNp.show()
        sideFrontColNp.show()
        sideBackColNp.show()
        sideBotColNp.show()'''

        return ret
        #Old way of creating box collisions (left here for reference)
        '''box = CollisionBox((posx+(length/2), posy+(width/2),-(posz+height/2)), length/2, width/2, height/2)
        boxCol = CollisionNode('testcollision')
        boxCol.addSolid(box)
        boxCol.setIntoCollideMask(BitMask32.bit(2))
        boxColNp = self.render.attachNewNode(boxCol)
        boxHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(boxColNp, self.wallHandler)

        #Uncomment this line to see the collision solids.
        #boxColNp.show()'''

    def checkpointCreator(self, posx, posy, posz, radius):
        cp = loader.loadModel('models/Campfire/logs')
        cp.setPos(posx,posy, posz)
        cp.reparentTo(render)
        checkpoint = CollisionSphere(cp.getX(),cp.getY(),cp.getZ(),radius)
        checkpoint.setTangible(0)
        checkpointCol = CollisionNode('checkpointCol')
        checkpointCol.addSolid(checkpoint)
        checkpointCol.setIntoCollideMask(BitMask32.bit(2))
        checkpointColNp = self.render.attachNewNode(checkpointCol)
        self.cTrav.addCollider(checkpointColNp, self.wallHandler)
Exemple #28
0
class Labrintth(ShowBase):

    def __init__(self):

          #from panda3d bump mapping demo
        # Configure the parallax mapping settings (these are just the defaults)
        loadPrcFileData("", "parallax-mapping-samples 3\n"
                            "parallax-mapping-scale 0.1")

        # Initialize the ShowBase class from which we inherit, which will
        # create a window and set up everything we need for rendering into it.
        ShowBase.__init__(self)


        #titles from panda3d bumb mapping demo
        # Check video card capabilities.
        if not self.win.getGsg().getSupportsBasicShaders():
            addTitle("Bump Mapping: "
                "Video driver reports that Cg shaders are not supported.")
            return

        self.playerHealth = 10
        self.loseHealth = True


        brickTexture = loader.loadTexture("models/brick-c.jpg")

        self.lstWalls = makeMaze()
        self.ptGrid = makePointGrid()

        #self.camera.setPos(self.ptGrid[len(self.ptGrid)-1][0])                                           
        self.focus = LVector3(0,1000,30)
     
        for row in range(len(self.ptGrid)):
            for col in range(len(self.ptGrid[row])):
                for n in range(2):
                    
                    #wall model made by 'TheCreator', https://free3d.com/3d-model/brick-wall-51172.html
                    self.wall = loader.loadModel("models/walls")
                    self.wall.setTexture(brickTexture)
                    self.wall.setScale(25.3)
                    self.wall.setPos(self.ptGrid[row][col])
                    self.wallC = self.wall.find("**/collideWall")
                    self.wallC.node().setIntoCollideMask(BitMask32.bit(0))
                    self.wallC.show()

                    #right of cell
                    if n == 0:
                        if self.lstWalls[row][col][n] == 1: 
                            self.wall.setX(self.wall, 1.05)
                            self.wall.setZ(5)
                            self.wall.reparentTo(render)

                    #down of cell
                    else: 
                        if self.lstWalls[row][col][n] == 1:
                            self.wall.setHpr(90,0,0)
                            self.wall.setX(self.wall, -3)    
                            self.wall.setZ(5)      
                            self.wall.reparentTo(render)

                    
        self.spacing = self.ptGrid[0][1][0] - self.ptGrid[0][0][0]

        self.exit = loader.loadModel('models/walls')
        self.exit.setScale(25.3)
        self.exit.setColorScale(0.6,0.6,1,1)

        self.exitCoord, wall = generateDoor(self.ptGrid, self.lstWalls)
        self.exitPos = self.ptGrid[self.exitCoord[0]][self.exitCoord[1]]
        self.exit.setPos(self.exitPos)

        for n in range(2):
            if n == 0:
                if wall[n] == 2: 
                    self.exit.setX(self.exit, 1.15)
                    self.exit.setZ(5)

            #down of cell
            else: 
                if wall[n] == 2:
                    self.exit.setHpr(90,0,0)
                    self.exit.setX(self.exit, -3.2)
                    self.exit.setZ(5)         

        self.exit.reparentTo(render)
        self.exit.detachNode()

        numPpl = 15 #make first pos minotaur
        pplLst = []
        pplLst = generatePosLst(pplLst, numPpl, self.ptGrid, self.spacing)


        targetPos = pplLst[random.randint(1, len(pplLst)-1)]
        print('target:',targetPos)

        #ball model from panda3D ball in maze demo
        num = 0
        for pos in range(1, len(pplLst)):
            num += 1

            #if the person in the list is the minotaur's target, set it's 
            #name to self.target
            if pplLst[pos] == targetPos:
                self.target = loader.loadModel("models/alfred")
                self.target.setPos(pplLst[pos])
                self.target.setScale(5)
                self.target.reparentTo(render)

                self.targetK = self.target.attachNewNode(CollisionNode('targetDie'))
                self.targetK.node().addSolid(CollisionSphere(0, 0, 5, 6))
                self.targetK.node().setIntoCollideMask(BitMask32.bit(2))
                #self.targetK.show()

                self.targetS = self.target.attachNewNode(CollisionNode('targetSave'))
                self.targetS.node().addSolid(CollisionSphere(0, 0, 5, 6))
                self.targetS.node().setIntoCollideMask(BitMask32.bit(1))
                #self.targetS.show()

            #otherwise, keep it as a self.ppl
            else: 
                self.ppl = loader.loadModel("models/alfred")
                self.ppl.setPos(pplLst[pos])
                self.ppl.setScale(5)

                #put a tag on each person so we can tell them apart
                self.ppl.setTag('personNum', str(num))
                self.ppl.reparentTo(render)
  
                #make it so that the people can be collision detected
                self.pplC = self.ppl.attachNewNode(CollisionNode('pplCollision'))
                self.pplC.node().addSolid(CollisionSphere(0, 0, 5, 7))
                self.pplC.node().setIntoCollideMask(BitMask32.bit(1))
                self.pplC.setTag('personCNum', str(num))
                #self.pplC.show()
        
        #first index in pplLst = minotar
        minotaurPos = pplLst[0]

        #Minotaur 3d model by 'Clint Bellanger' https://opengameart.org/content/minotaur
        self.minotaur = Actor("models/TheMinotaur")
        self.minotaur.setPos(minotaurPos)
        self.minotaur.setScale(25)
        self.minotaur.reparentTo(render)


        minotaurTexture = loader.loadTexture("models/catfur.jpg")
        self.minotaur.setTexture(minotaurTexture)

        self.minC = self.minotaur.attachNewNode(CollisionNode('minCollision'))
        self.minC.node().addSolid(CollisionSphere(0 , 0, 1, 0.5))
        self.minC.node().setFromCollideMask(BitMask32.bit(2))
        #self.minC.node().setIntoCollideMask(BitMask32.bit(1))
        #self.minC.show()

        self.minBat = self.minotaur.attachNewNode(CollisionNode('battle'))
        self.minBat.node().addSolid(CollisionSphere(0, 0, 1, 4.3))
        self.minBat.node().setIntoCollideMask(BitMask32.bit(1))
        self.minBat.show()

        self.minHit = self.minotaur.attachNewNode(CollisionNode('hit'))
        self.minHit.node().addSolid(CollisionSphere(0, 0, 1.5, 0.4))
        self.minHit.node().setIntoCollideMask(BitMask32.bit(3))

        self.minAtk = self.minotaur.attachNewNode(CollisionNode('attack'))
        self.minAtk.node().addSolid(CollisionSphere(0, 0, 1.85, 0.4))
        self.minAtk.node().setIntoCollideMask(BitMask32.bit(4))
        self.minAtk.show()

        self.cTrav = CollisionTraverser()
        self.cHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.minC, self.cHandler)
        self.cTrav.addCollider(self.minAtk, self.cHandler)

        self.minotaurObj = Minotaur(self.minotaur.getPos())

        #find the path the minotaur takes to kill the person
        self.killPath = self.minotaurObj.findPerson(minotaurPos, targetPos, self.ptGrid, self.lstWalls, self.spacing)
        self.minSpeed = 1
        self.sleepDelay = 13
        self.killFlag = True
        self.killDone = False
        self.killPause = False
        self.killPaused = False

        self.hit = False
        self.hurtTime = 0
        self.minDied = False
        self.minTimeDied = 0
        self.attackTrig = False
        self.warningTrig = True

        taskMgr.add(self.minotaurKilling, "minotaurKilling")
        taskMgr.add(self.minotaurDie, 'minotaurDied')
        taskMgr.add(self.pauseKill, 'pauseKill')

        self.saved = 0
        self.addSaved = False
        self.saveTrig = False

        taskMgr.add(self.displaySaved, "saved")
        
        #collisions
        #create a ball for collisions 
        self.camBall = loader.loadModel("models/ball")
        self.camBall.setPos(self.spacing/2, self.spacing/2, -1)
        self.camBall.setScale(10)
        #self.camBall.setColorScale(0, 1, 0.7, 1)
        self.camBall.reparentTo(render)

        self.playerPos = (0,0,0)
        
        self.camBallC = self.camBall.find("**/ball")
        #self.camBallC = self.camBall.attachNewNode(CollisionNode('camCollision'))
        #self.camBallC.node().addSolid(CollisionSphere(0, 0, 0, 1.2))
        self.camBallC.node().setFromCollideMask(BitMask32.bit(0))

        self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(self.camBallC, self.camBall)

        self.cTrav.addCollider(self.camBallC, self.pusher)
        self.camBallC.setPos(0,0.0002,0)

        self.camC = self.camera.attachNewNode(CollisionNode('cameraCollision'))
        self.camC.node().addSolid(CollisionSphere(0, 0, 0, 0.01))
        self.camC.node().setFromCollideMask(BitMask32.bit(1))
        self.camC.node().setIntoCollideMask(BitMask32.bit(4))
        self.camC.show()

        self.cTrav.addCollider(self.camC, self.cHandler)

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

        #sting-sword model created by  KangaroOz 3D, from: https://www.turbosquid.com/FullPreview/Index.cfm/ID/1125944
        self.sword = loader.loadModel('models/sting-sword')
        self.sword.wrtReparentTo(self.camBall)
        self.sword.detachNode()
        
        self.sword.setY(1)
        self.sword.setX(0.5)
        self.sword.setZ(0.2)
        self.sword.setScale(0.07)


        self.swordC = self.sword.attachNewNode(CollisionNode('stab'))
        self.swordC.node().addSolid(CollisionSphere(0, 25, 0, 2))
        self.swordC.node().setFromCollideMask(BitMask32.bit(3))
        #self.swordC.show()

        self.attacked = False
        self.stabbing = False

        self.cTrav.add_collider(self.swordC, self.cHandler)


        swordTexture = loader.loadTexture("models/Sting_Emissive.png")
        self.sword.setTexture(swordTexture)

        self.stabDelay = 0

        self.redBarL = loader.loadModel('models/walls')
        self.redBarL.setScale(3)
        self.redBarL.setColorScale(250,0,0,1)
        self.redBarL.setPos(38.5, 60,5)
        self.redBarL.wrtReparentTo(self.camBall)
        self.redBarL.detachNode()

        self.redBarR = loader.loadModel('models/walls')
        self.redBarR.setScale(3)
        self.redBarR.setColorScale(250,0,0,1)
        self.redBarR.setPos(55.7,60,5)
        self.redBarR.wrtReparentTo(self.camBall)
        self.redBarR.detachNode()
        
        self.hurtTimeP = 0

        #make list of controls 
        self.keyMap = {
            "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0,\
             "cam-right": 0, "stab":0, "map": 0, "instrMode":0, "gameMode":0}

        # Make the mouse invisible, turn off normal mouse controls
        self.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
       

        # Set the current viewing target
        self.heading = 0
        self.pitch = 0
        self.last = 0

        self.startMode = True
        self.startTrig = True
        self.startDestroy = True
        self.instrMode = False
        self.instrTrig = True
        self.instrShown = False
        self.instrDestroy = True
        self.gameMode = False

        self.bkGround = loader.loadModel('models/walls')
        self.bkGround.reparentTo(self.camBall)
        self.bkGround.setColorScale(0,0.5,0.55,1)
        self.bkGround.setPos(-1,3,0)

        taskMgr.add(self.showStart, "start-screen")


        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])

        self.accept("o", self.setKey, ["instrMode", True])
        self.accept("p", self.setKey, ["gameMode", True])

        self.accept("arrow_left", self.setKey, ["left", True])
        self.accept("arrow_right", self.setKey, ["right", True])
        self.accept("arrow_up", self.setKey, ["forward", True])
        self.accept("arrow_down", self.setKey, ["backward", True])
        self.accept("w", self.setKey, ["stab", True])
        self.accept("s", self.setKey, ["down", True])
        self.accept("arrow_left-up", self.setKey, ["left", False])
        self.accept("arrow_right-up", self.setKey, ["right", False])
        self.accept("arrow_up-up", self.setKey, ["forward", False])
        self.accept("arrow_down-up", self.setKey, ["backward", False])
        self.accept("w-up", self.setKey, ["stab", False])
        self.accept("s-up", self.setKey, ["down", False])


        self.accept("a", self.setKey, ["cam-left", True])
        self.accept("d", self.setKey, ["cam-right", True])
        self.accept("a-up", self.setKey, ["cam-left", False])
        self.accept("d-up", self.setKey, ["cam-right", False])

        self.accept("space", self.setKey, ["map", True])
        self.accept("space-up", self.setKey, ["map", False])


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

    def startKill(self): 
        try:
            self.target.setColorScale(250,0,0,1)
        except: 
            pass
        intervalL = self.intervalLst()

        self.kill = Sequence(intervalL[0], name = 'kill person')
        for i in range(1, len(intervalL)):
            self.kill.append(intervalL[i])
        self.kill.start()

    def pauseKill(self, task):
        print(self.killPaused, self.killPause)
        if self.gameMode == True:

            if self.killDone == True:
                self.kill.finish()
               
            if self.killPaused == False and self.killPause == True:
                print('hmmmmmmmmmmmm')
                self.kill.pause()
                self.killPaused = True

            if self.killPaused == True and self.killPause == False:
                self.kill.resume()
                self.killPaused = False

        return Task.cont

    def intervalLst(self):
        intervals = []
        for i in range(len(self.killPath)):
            intervals += [self.minotaur.posInterval(self.minSpeed, Point3(self.killPath[i]))]
        return intervals

    def stab(self, task):
        timer = globalClock.getFrameTime()
        
        speed = 0.2
        stabIn = LerpPosInterval(self.sword, speed, Point3(0,4,0.2))
        stabOut = LerpPosInterval(self.sword, speed, Point3(0.5,1,0.2))
        stab = Sequence(stabIn, stabOut, name = 'stab')
        stab.start()

        self.stabbing = True 

        if self.hit == True: 
            self.minotaurObj.hit()

            self.hurtTime = globalClock.getFrameTime()
            self.hurtShow(task)
            
            self.hit = False
            self.stabbing = False


    def hurtShow(self,  task):
        if self.hit == True:
            timer = globalClock.getFrameTime()
            if timer - self.hurtTime < 2:
                self.minotaur.setColorScale(180,0,0,1)
        return Task.cont

    def attack(self, task):
        if self.attackTrig == True:
            speed = 1
            turnSpeed = 0.5
            attackPos, distance, direction = self.minotaurObj.attack(self.camera.getPos(), self.minotaur.getPos(), \
                self.ptGrid, self.spacing, self.lstWalls)
            origPt = self.minotaur.getPos()
            if attackPos != None:
                attack = LerpPosInterval(self.minotaur, speed, Point3(attackPos))
                turnToPlayer = LerpHprInterval(self.minotaur, turnSpeed, self.minotaurObj.facePlayer(direction))
                if distance == 'short':
                    retract = LerpPosInterval(self.minotaur, speed, origPt)
                    attackSeq = Sequence(turnToPlayer, attack, retract, name = 'attack')
                    attackSeq.start()
                else: 
                    attackSeq = Sequence(turnToPlayer, attack, name = 'attack')
                    attackSeq.start()

            self.attackTrig = False

            
    def attackShow(self, task):
        if self.attacked == True:
            timer = globalClock.getFrameTime()
            if timer - self.hurtTimeP < 2:
                self.redBarL.reparentTo(self.camBall)
                self.redBarR.reparentTo(self.camBall)
            if self.loseHealth == True:
                self.playerHealth -= 10
                print(self.playerHealth)
                self.loseHealth = False

        return Task.cont


    def displaySaved(self, task):
        if self.gameMode == True:
            if self.saved == 0 and self.saveTrig == False:
                msg = 'Saved: ' + str(self.saved)
                self.displSaved = OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05,
                                shadow=(0, 0, 0, 1),parent=base.a2dTopLeft, align=TextNode.ALeft,
                                 pos=(0.05, -1.9))
                self.saveTrig = True
            
            if self.addSaved == True and self.saveTrig == True and self.saved > 0:
                print('here')
                self.displSaved.destroy()
                msg = 'Saved: ' + str(self.saved)
                self.displSaved = OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05,
                                shadow=(0, 0, 0, 1),parent=base.a2dTopLeft, align=TextNode.ALeft,
                                 pos=(0.05, -1.9))
                self.addSaved = False

        return Task.cont
        
    def minotaurKilling(self, task):
        if self.gameMode == True:
            #timer for minotaur sleeping
            timer = globalClock.getFrameTime()
            timeLeft = self.sleepDelay - int(timer)

            #put up the instructions before the minotaur wakes up
            if timeLeft >= 0:

                if self.warningTrig == True:
                    if timeLeft == 1:
                        msg = "You have 1 second to find the Minotaur before he wakes up!"
                    elif timeLeft == 0:
                        msg = "He's awake!"
                    else: 
                        msg = "You have " + str(timeLeft) + " seconds to find the Minotaur before he wakes up!"
                    
                    self.warning = OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                shadow=(0, 0, 0, 1),parent=base.a2dTopLeft, align=TextNode.ALeft,
                                 pos=(0.05, -0.08))
                    self.displayWarning = timer
                    self.warningTrig = False

                if timer - self.displayWarning > 0.92: 
                    self.warning.destroy()
                    self.warningTrig = True

            if timeLeft < 0:
                self.warning.destroy()

            #wake the minotaur up after time ends
            if timeLeft < 0 and self.killFlag == True:
                self.startKill()
                self.killFlag = False

            #make sure minotaur is always the right color
            if timer - self.hurtTime > 2:
                self.minotaur.setColorScaleOff()

            if timer - self.hurtTimeP > 2:
                self.redBarL.detachNode()
                self.redBarR.detachNode()

            if self.minDied == True:
                if timer - self.minTimeDied > 20:
                    self.minotaur.detachNode()
                    self.exit.reparentTo(render)
                    self.showRopes()

            if timer - self.hurtTimeP > 2:
                    self.loseHealth = True

        return Task.cont

    def minotaurDie(self, task):

        if self.minotaurObj.health <= 0 and self.minDied == False:
            dieSpeed = 3
            die = LerpHprInterval(self.minotaur, dieSpeed, (self.camera.getX(), 90, 5))
            die.start()
            self.minDied = True
            self.minTimeDied = globalClock.getDt()

        return Task.cont

    def showropes(self):
        ropeHeight = 30
        lastRope = findExitPos(self.exitPos, self.ptGrid, self.spacing)

        playerPos = findPlayerPos(self.camera.getPos(), self.spacing)
        playerPos = (playerPos[0], playerPos[1], ropeHeight)

        ropePath, ropeDir = findExit(playerPos, lastRope, self.ptGrid, self.lstWalls, self.spacing)
        lastDir = findDir(self.exitCoord, self.ptGrid)

        if ropeDir != None:
            ropeDir += [lastDir]

        #gold texture found at https://www.google.com/url?sa=i&source=images&cd=&cad=r\
        #ja&uact=8&ved=2ahUKEwjw76Lbv4rfAhVpvFkKHY3JDPYQjRx6BAgBEAU&url=http%3A%2F\
        #%2Fmetal.graphics%2Fgraphic%2Fbrushed%2Fgold-texture%2F&psig=AOvVaw1q3Yu\
        #xuuGvetU4fhA1cIqh&ust=1544161415078294
        
        goldTexture = loader.loadTexture("models/gold.jpg")
        if ropePath != None:

            #rope model by Robert J. Smith, https://www.cgtrader.com/free-3d-models/industrial/tool/knot-rope
            for pos in range(len(ropePath)):
                rope = loader.loadModel("models/rope1")
                rope.setPos(ropePath[pos])
                rope.setScale(3.6)
                rope.setZ(-5)

                if pos < len(ropeDir):
                    if ropeDir[pos] == 'e':
                        rope.setHpr(76,0,0)
                        rope.setX(rope.getX() + 75)
                        rope.setY(rope.getY() + 5)
                    if ropeDir[pos] == 'n':
                        rope.setHpr(166,0,0)
                        rope.setY(rope.getY() + 65)
                    if ropeDir[pos] == 'w':
                        rope.setHpr(256,0,0)
                        rope.setX(rope.getX() - 60)
                        rope.setY(rope.getY() - 9)
                    if ropeDir[pos] == 's':
                        rope.setHpr(-14,0,0)
                        rope.setY(rope.getY() - 70)
                        rope.setX(rope.getX() + 15)
                rope.setTexture(goldTexture)
                rope.reparentTo(render)

    def lostGame(self):
        lose = loader.loadModel('models/walls')
        lose.reparentTo(self.camBall)
        lose.setColorScale(0.1,0.1,0.1,1)
        lose.setPos(-1,3,0)

    def showStart(self, task):
        startMsg = "Welcome to Daedalus's Creation." 
        startMsg2 = "You have to kill the minotaur, navegate the labyrinth, and save the others."+"You have 30 seconds to find the Minotaur before he wakes up and starts killing your people."
        startMsg3 = "Good luck doing what no man has done before."
        startMsg4 = "Press 'o' for instructions on how to play."

        if self.startMode == True and self.startTrig == True:
            self.start = OnscreenText(text=startMsg, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                shadow=(0, 0, 0, 1),parent=base.aspect2d, pos = (0,0.5), align=TextNode.ACenter, wordwrap= 15)
            self.start2 = OnscreenText(text=startMsg2, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,0.2), wordwrap= 20)

            self.start3 = OnscreenText(text=startMsg3, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,-0.2), wordwrap= 25)
            self.start4 = OnscreenText(text=startMsg4, style=1, fg=(1, 1, 1, 1), scale=0.1,
                                shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,-0.5), wordwrap= 25)
            self.startTrig = False

        if self.startMode == False and self.startDestroy == True: 
            self.start.destroy()
            self.start2.destroy()
            self.start3.destroy()
            self.start4.destroy()
            self.startDestroy = False

            task.remove()

        return Task.cont

    def showInstr(self):

        instrMsg = "Press the right and left arrow keys to move right and left."
        instrMsg1 = "Press the up and down arrow keys to move forwards and backwards."
        instrMsg2 = "Press the 'a' key to turn the camera left."
        instrMsg3 = "Press the 'd' key to turn the camera right."
        instrMsg4 = "Press the space key for a map of the labyrinth"
        instrMsg5 = "Press the 'w' key to attack." 
        instrMsg6 = "Press the 'p' key to start the game."

        if self.instrMode == True and self.instrTrig == True:

            self.instr = OnscreenText(text=instrMsg, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, pos = (0,0.7), align=TextNode.ACenter, wordwrap= 30)
            self.instr1 = OnscreenText(text=instrMsg1, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, pos = (0,0.5), align=TextNode.ACenter, wordwrap= 20)
            self.instr2 = OnscreenText(text=instrMsg2, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,0.2), wordwrap= 20)
            self.instr3 = OnscreenText(text=instrMsg3, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,0), wordwrap= 25)
            self.instr4 = OnscreenText(text=instrMsg4, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,-0.2), wordwrap= 25)
            self.instr5 = OnscreenText(text=instrMsg5, style=1, fg=(1, 1, 1, 1), scale=0.08,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,-0.4), wordwrap= 25)
            self.instr6 = OnscreenText(text=instrMsg6, style=1, fg=(1, 1, 1, 1), scale=0.1,
                                    shadow=(0, 0, 0, 1),parent=base.aspect2d, align=TextNode.ACenter, pos = (0,-0.6), wordwrap= 25)
            self.instrTrig = False
            self.instrShown = True

    def endInstr(self):

        if self.instrMode == False and self.instrDestroy == True and self.instrShown == True: 
            self.instr.destroy()
            self.instr1.destroy()
            self.instr2.destroy()
            self.instr3.destroy()
            self.instr4.destroy()
            self.instr5.destroy()
            self.instr6.destroy()
            self.instrDestroy = False

    #make the person disappear when it's touched
    def disappear(self,task):

        for i in range(self.cHandler.getNumEntries()):

            entry = self.cHandler.getEntry(i)
            fromNode = entry.getFromNodePath()
            intoNode = entry.getIntoNodePath()
            intoName = entry.getIntoNode().getName()
            fromName = entry.getFromNode().getName()

            #if the collision was with a person
            if (intoName == 'pplCollision' and fromName == 'cameraCollision'):
                num = intoNode.getTag("personCNum")
                tag = '**/=personNum=' + num
                #finds the person player collided into and removes them
                person = render.find(tag)
                person.removeNode()

                #add one to saved counter
                self.saved += 1
                self.addSaved = True
                self.displSaved.destroy()
                return Task.cont


            if intoName == 'targetSave' and fromName == 'cameraCollision':
                print('saved!')
                self.target.removeNode()
                self.saved += 1
                self.addSaved = True
                return Task.cont
            
            if intoName == 'targetDie' and fromName == 'minCollision':
                print('ahhhhhhhhh!')
                self.target.removeNode()
                self.killDone = True
                return Task.cont

            #if minotaur gets stabbed by player
            if intoName == 'hit' and fromName == 'stab':

                if self.stabbing == True:
                    self.hit = True
                return Task.cont

            if intoName == 'cameraCollision' and fromName == 'attack':
                print('attacked!!!!!')
                self.attacked = True
                self.hurtTimeP = globalClock.getFrameTime()
                self.attackShow(task)

                if self.playerHealth < 0:
                    self.lostGame()
                return Task.cont

            if (intoName == 'battle' and fromName == 'cameraCollision' and self.killFlag == False) \
                or (intoName == 'minCollision' and fromName == 'cameraCollision' and self.killFlag == False):
                print('pause')
                self.killPause = True 
                return Task.cont

            else: 
                print('hereeeee')
                self.killPause = False

            print('killPause', self.killPause)
        return Task.cont

    #structure from panda3d bump mapping demo
    def controlCamera(self, task):

        dt = globalClock.getDt()
       
        self.camera.setHpr(self.heading, self.pitch, 0)
        self.camBall.setHpr(self.heading, self.pitch, 0)
        dir = self.camera.getMat().getRow3(1)

        camPos = (self.camBall.getPos()[0], self.camBall.getPos()[1], 6)
        self.camera.setPos(camPos)

        if self.keyMap["instrMode"] == True: 
            self.startMode = False
            self.instrMode = True
            self.showInstr()

        if self.keyMap["gameMode"] == True:
            self.instrMode = False
            self.gameMode = True
            self.bkGround.detachNode()
            self.endInstr()

        if self.gameMode == True:

            #move camera right and left
            if self.keyMap["left"]:
                self.camBall.setX(self.camBall, -10*dt)
            if self.keyMap["right"]:
                self.camBall.setX(self.camBall, +10*dt)
            if self.keyMap["forward"]:
                self.camBall.setY(self.camBall, +10*dt)
            if self.keyMap["backward"]:
                self.camBall.setY(self.camBall, -10*dt)
           

            #rotate camera
            if self.keyMap["cam-right"]:
                self.heading = self.heading -  100*dt
            if self.keyMap["cam-left"]:
                self.heading = self.heading +  100*dt
            self.focus = self.camera.getPos() + (dir * 5)
            self.last = task.time

            
            if self.keyMap['stab']:
                timer = globalClock.getFrameTime()
                if timer - self.stabDelay > 0.5:
                    self.stab(task)
                    self.stabDelay = timer
                    self.attack(task)
                    self.attackTrig = True
                    
            #show map 
            if self.keyMap["map"] == True:
                center = (len(self.ptGrid))/2*self.spacing
                self.camera.setPos(center,center, 1.8*len(self.ptGrid)*self.spacing)
                self.camera.lookAt(center, center, 0)
                self.sword.detachNode()
                if self.killFlag == False and self.killPause == True:
                    self.kill.pause()

                self.camBall.reparentTo(render)
                self.camBall.setScale(20)
                self.camBall.setColorScale(0, 0.5, 1, 1)

            if self.keyMap["map"] == False and self.startMode == False and self.instrMode == False:
                self.sword.reparentTo(self.camBall)
                self.camBall.setColorScaleOff()
                self.camBall.setScale(10)

        
        return Task.cont
Exemple #29
0
class CogdoFlyingCollisions(GravityWalker):
    wantFloorSphere = 0

    def __init__(self):
        GravityWalker.__init__(self, gravity=0.0)

    def initializeCollisions(self,
                             collisionTraverser,
                             avatarNodePath,
                             avatarRadius=1.4,
                             floorOffset=1.0,
                             reach=1.0):
        self.cHeadSphereNodePath = None
        self.cFloorEventSphereNodePath = None
        self.setupHeadSphere(avatarNodePath)
        self.setupFloorEventSphere(avatarNodePath,
                                   ToontownGlobals.FloorEventBitmask,
                                   avatarRadius)
        GravityWalker.initializeCollisions(self, collisionTraverser,
                                           avatarNodePath, avatarRadius,
                                           floorOffset, reach)
        return

    def setupWallSphere(self, bitmask, avatarRadius):
        self.avatarRadius = avatarRadius
        cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75,
                                  self.avatarRadius)
        cSphereNode = CollisionNode('Flyer.cWallSphereNode')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        if config.GetBool('want-fluid-pusher', 0):
            self.pusher = CollisionHandlerFluidPusher()
        else:
            self.pusher = CollisionHandlerPusher()
        self.pusher.addCollider(cSphereNodePath, self.avatarNodePath)
        self.cWallSphereNodePath = cSphereNodePath

    def setupEventSphere(self, bitmask, avatarRadius):
        self.avatarRadius = avatarRadius
        cSphere = CollisionSphere(0.0, 0.0, self.avatarRadius + 0.75,
                                  self.avatarRadius * 1.04)
        cSphere.setTangible(0)
        cSphereNode = CollisionNode('Flyer.cEventSphereNode')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.event = CollisionHandlerEvent()
        self.event.addInPattern('enter%in')
        self.event.addOutPattern('exit%in')
        self.cEventSphereNodePath = cSphereNodePath

    def setupRay(self, bitmask, floorOffset, reach):
        cRay = CollisionRay(0.0, 0.0, 3.0, 0.0, 0.0, -1.0)
        cRayNode = CollisionNode('Flyer.cRayNode')
        cRayNode.addSolid(cRay)
        self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
        cRayNode.setFromCollideMask(bitmask)
        cRayNode.setIntoCollideMask(BitMask32.allOff())
        self.lifter = CollisionHandlerGravity()
        self.lifter.setLegacyMode(self._legacyLifter)
        self.lifter.setGravity(self.getGravity(0))
        self.lifter.addInPattern('%fn-enter-%in')
        self.lifter.addAgainPattern('%fn-again-%in')
        self.lifter.addOutPattern('%fn-exit-%in')
        self.lifter.setOffset(floorOffset)
        self.lifter.setReach(reach)
        self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath)

    def setupHeadSphere(self, avatarNodePath):
        collSphere = CollisionSphere(0, 0, 0, 1)
        collSphere.setTangible(1)
        collNode = CollisionNode('Flyer.cHeadCollSphere')
        collNode.setFromCollideMask(ToontownGlobals.CeilingBitmask)
        collNode.setIntoCollideMask(BitMask32.allOff())
        collNode.addSolid(collSphere)
        self.cHeadSphereNodePath = avatarNodePath.attachNewNode(collNode)
        self.cHeadSphereNodePath.setZ(base.localAvatar.getHeight() + 1.0)
        self.headCollisionEvent = CollisionHandlerEvent()
        self.headCollisionEvent.addInPattern('%fn-enter-%in')
        self.headCollisionEvent.addOutPattern('%fn-exit-%in')
        base.cTrav.addCollider(self.cHeadSphereNodePath,
                               self.headCollisionEvent)

    def setupFloorEventSphere(self, avatarNodePath, bitmask, avatarRadius):
        cSphere = CollisionSphere(0.0, 0.0, 0.0, 0.75)
        cSphereNode = CollisionNode('Flyer.cFloorEventSphere')
        cSphereNode.addSolid(cSphere)
        cSphereNodePath = avatarNodePath.attachNewNode(cSphereNode)
        cSphereNode.setFromCollideMask(bitmask)
        cSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.floorCollisionEvent = CollisionHandlerEvent()
        self.floorCollisionEvent.addInPattern('%fn-enter-%in')
        self.floorCollisionEvent.addAgainPattern('%fn-again-%in')
        self.floorCollisionEvent.addOutPattern('%fn-exit-%in')
        base.cTrav.addCollider(cSphereNodePath, self.floorCollisionEvent)
        self.cFloorEventSphereNodePath = cSphereNodePath

    def deleteCollisions(self):
        GravityWalker.deleteCollisions(self)
        if self.cHeadSphereNodePath != None:
            base.cTrav.removeCollider(self.cHeadSphereNodePath)
            self.cHeadSphereNodePath.detachNode()
            self.cHeadSphereNodePath = None
            self.headCollisionsEvent = None
        if self.cFloorEventSphereNodePath != None:
            base.cTrav.removeCollider(self.cFloorEventSphereNodePath)
            self.cFloorEventSphereNodePath.detachNode()
            self.cFloorEventSphereNodePath = None
            self.floorCollisionEvent = None
        self.cRayNodePath.detachNode()
        del self.cRayNodePath
        self.cEventSphereNodePath.detachNode()
        del self.cEventSphereNodePath
        return

    def setCollisionsActive(self, active=1):
        if self.collisionsActive != active:
            if self.cHeadSphereNodePath != None:
                base.cTrav.removeCollider(self.cHeadSphereNodePath)
                if active:
                    base.cTrav.addCollider(self.cHeadSphereNodePath,
                                           self.headCollisionEvent)
            if self.cFloorEventSphereNodePath != None:
                base.cTrav.removeCollider(self.cFloorEventSphereNodePath)
                if active:
                    base.cTrav.addCollider(self.cFloorEventSphereNodePath,
                                           self.floorCollisionEvent)
        GravityWalker.setCollisionsActive(self, active)
        return

    def enableAvatarControls(self):
        pass

    def disableAvatarControls(self):
        pass

    def handleAvatarControls(self, task):
        pass
Exemple #30
0
class TheWorld(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.params = {
            "mouse_x": 0,
            "mouse_y": 0,
        }

        self.disableMouse()
        self.cmd_mgr = commandmgr.TheWorldCommandMgr(self)
        util.hidden_relative_mouse(self)
        for cmd_str, cmd_fn in self.cmd_mgr.mapping.items():
            self.accept(cmd_str, cmd_fn)

        # environment
        self.setBackgroundColor(.0, .0, .0, 1)

        # # ground
        self.ground_cube = self.loader.loadModel("cuby.gltf")
        self.ground_cube.setColor(1, 1, 1, 1)
        ground_cube_size = Vec3(2, 2, .4)
        self.ground_cube.setScale(ground_cube_size)

        self.ground = self.render.attachNewNode("ground")

        grid_size = 5
        grid_max = grid_size - 1
        dist = 8
        grid_coordinates = itertools.product(range(grid_size),
                                             range(grid_size))

        def normalize(x_y):
            x, y = x_y
            return (x - grid_max / 2) * dist, (y - grid_max / 2) * dist

        for x, y in map(normalize, grid_coordinates):
            placeholder = self.ground.attachNewNode("placeholder")
            placeholder.setPos(x, y, -ground_cube_size.z)
            self.ground_cube.instanceTo(placeholder)

            # collision ground
            coll_node = CollisionNode(f"ground_{x}_{y}")
            coll_node.setFromCollideMask(CollideMask.allOff())
            coll_node.setIntoCollideMask(CollideMask.bit(0))
            nodepath = placeholder.attachNewNode(coll_node)
            nodepath.node().addSolid(
                CollisionBox(Point3(0, 0, 0), ground_cube_size.x,
                             ground_cube_size.y, ground_cube_size.z))

        # lighting
        ambient_light = AmbientLight("ambient_light")
        ambient_light.setColor((.2, .2, .2, 1))
        alight = self.render.attachNewNode(ambient_light)
        self.render.setLight(alight)

        # actor
        self.actor_obj = Actor(self, self.render, "cuby.gltf")
        self.actor = self.actor_obj.node
        self.actor.setColor(cube_color)

        # # collision actor
        self.cTrav = CollisionTraverser('traverser')
        self.cTrav.showCollisions(self.actor)

        self.actor_coll = CollisionNode('actor')
        self.actor_coll.addSolid(CollisionBox(Point3(0, 0, 0), 1, 1, 1))
        self.actor_coll.setFromCollideMask(CollideMask.bit(0))
        self.actor_coll.setIntoCollideMask(CollideMask.allOff())
        self.actor_coll_np = self.actor.attachNewNode(self.actor_coll)
        self.pusher = CollisionHandlerPusher()

        self.pusher.addCollider(self.actor_coll_np, self.actor)
        self.cTrav.addCollider(self.actor_coll_np, self.pusher)

        # lighting
        self.centerlight_np = self.render.attachNewNode("basiclightcenter")
        self.centerlight_np.hprInterval(4, (360, 0, 0)).loop()

        d, h = 8, 1
        self.basic_point_light((-d, 0, h), (.0, .0, .7, 1), "left_light")
        self.basic_point_light((d, 0, h), (.0, .7, 0, 1), "right_light")
        self.basic_point_light((0, d, h), (.7, .0, .0, 1), "front_light")
        self.basic_point_light((0, -d, h), (1, 1, 1, 1), "back_light")

        self.actor_stater = Stater(self.actor)
        self.cmd_mgr.set_actor_stater(self.actor_stater)
        self.actor_mover = Mover(self, self.actor_obj, self.actor_stater)

        self.camera.wrtReparentTo(self.actor)
        self.camera.setPos(Vec3(0, 4, 1).normalized() * cam_dist)
        self.camera.lookAt(0, 0, 0)

        self.taskMgr.add(self.update_params, "paramsTask")
        self.taskMgr.add(self.actor_mover.execute, "moveTask")
        self.taskMgr.add(self.log, "logTask")

        self.render.setShaderAuto()

    def update_params(self, task):
        if self.mouseWatcherNode.hasMouse():
            self.params["mouse_x"] = self.mouseWatcherNode.getMouseX()
            self.params["mouse_y"] = self.mouseWatcherNode.getMouseY()
            self.win.movePointer(0,
                                 self.win.getProperties().getXSize() // 2,
                                 self.win.getProperties().getYSize() // 2)
        self.params["actor_pos"] = self.actor.getPos()
        return Task.cont

    def log(self, task):
        return Task.cont

    def basic_point_light(self,
                          position,
                          color,
                          name,
                          attenuation=(1, 0, 0.02)):
        light = PointLight(name)
        light.setColor(color)
        light.setAttenuation(attenuation)
        # light.setShadowCaster(True)
        # light.getLens().setNearFar(5, 20)
        plight = self.centerlight_np.attachNewNode(light)
        plight.setPos(position)
        self.render.setLight(plight)

        light_cube = self.loader.loadModel("cuby.gltf")
        light_cube.reparentTo(plight)
        light_cube.setScale(0.25)
        material = Material()
        material.setEmission(color)
        light_cube.setMaterial(material)