Exemple #1
0
class World(DirectObject):
    def __init__(self):
        #turn off mouse control, otherwise camera is not repositionable
        self.lightables = []
        self.cameraPositions = [((0, 5000, 5300), (180, -35, 0)),((0, 3000, 1300), (180, -15, 0))]
        self.cameraIndex = 0
        base.disableMouse()
        base.enableParticles()
        self.setupLights()
        self.setupPicking()
        #Prepare the vehicular manslaughter!
        self.boosterLightNP = None
        self.flameLights = None
        self.player = Vehicle("models/panda-model", "panda-walk4", self)
        
        self.loadModels()
        # self.player.setPos(self.env.find("**/start_point").getPos())
        self.player.setPos(0,0,0)
        self.setupIntervals()
        camera.reparentTo(self.player)
        camera.setPosHpr(0, 5000, 5300, 180, -35, 0)
        self.setupCollisions()
        render.setShaderAuto() #you probably want to use this
        self.keyMap = {"left":0, "right":0, "forward":0, "backwards":0}
        taskMgr.add(self.player.move, "moveTask")
        
        #Give the vehicle direct access to the keyMap
        self.player.addKeyMap(self.keyMap)
        
        self.prevtime = 0
        self.isMoving = False
        self.speed_norm = 8
        self.speed = self.speed_norm
        self.accept("escape", sys.exit)
        
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("w", self.setKey, ["forward", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("d", self.setKey, ["right", 1])
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("a", self.setKey, ["left", 1])
        self.accept("arrow_down", self.setKey, ["backwards", 1])
        self.accept("s", self.setKey, ["backwards", 1])
        
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("w-up", self.setKey, ["forward", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("d-up", self.setKey, ["right", 0])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("a-up", self.setKey, ["left", 0])
        self.accept("arrow_down-up", self.setKey, ["backwards", 0])
        self.accept("s-up", self.setKey, ["backwards", 0])
        
        self.accept("mouse1", self.startShoot)
        self.accept("mouse1-up", self.stopShoot)
        self.accept("tab", self.shiftCamera)   
        self.accept("space", self.player.startBoosters)
        
        self.accept("ate-smiley", self.eat)
        self.accept("ground_collide", self.player.collider)
        self.p1 = ParticleEffect()
        self.p2 = ParticleEffect()
        
        #Show collisiony stuff
        base.cTrav.showCollisions(render)
        
    
    def setupPicking(self):
        self.picker = CollisionTraverser()
        self.pq     = CollisionHandlerQueue()
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP, self.pq)
        
        self.targetRoot = render.attachNewNode('targetRoot')
        self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
    
    def mouseTask(self, task):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.picker.traverse(self.targetRoot)
            if self.pq.getNumEntries() > 0:
                self.pq.sortEntries()
                i = int(self.pq.getEntry(0).getIntoNode().getTag('target'))
                print("Found target: " + str(i))
                  
        return Task.cont

    def setupIntervals(self):
        self.lightOn = LerpFunc(self.lightModify,
                            fromData=0,
                            toData=100,
                            duration=0.2,
                            blendType='noBlend',
                            extraArgs=[True],
                            name="LightUp")
        self.lightOff = LerpFunc(self.lightModify,
                            fromData=0,
                            toData=100,
                            duration=0.2,
                            blendType='noBlend',
                            extraArgs=[False],
                            name="LightDown")
                            
        self.cameraMove = None
        
    def setKey(self, key, value):
        self.keyMap[key] = value
        
    def setWorldLight(self, object):
        self.lightables.append(object)
        object.setLight(self.keyLightNP)
        object.setLight(self.fillLightNP)
        object.setLight(self.boosterLightNP)
        for light in self.flameLights:
            object.setLight(light[1])
        
    def shiftCamera(self):
        if self.cameraMove:
            self.cameraMove.finish()
        old = self.cameraIndex
        self.cameraIndex += 1
        if self.cameraIndex == len(self.cameraPositions):
            self.cameraIndex = 0
        self.cameraMove=LerpPosHprInterval(camera,
                                            .7, 
                                            self.cameraPositions[self.cameraIndex][0], 
                                            self.cameraPositions[self.cameraIndex][1],
                                            camera.getPos(), 
                                            camera.getHpr())
        self.cameraMove.start()
     
    def loadModels(self):
        """loads models into the world"""
        #eat no longer exists? Phooey
        
        self.flameLights = []
        shadowcam = Spotlight('shadowlight')
        shadowcam.setColor(VBase4(0,0,0,1))
        lens = PerspectiveLens()
        shadowcam.setLens(lens)
        shadowcam.setAttenuation(Point3(0, 0.001, 0.001))
        shadowNP = self.player.attachNewNode(shadowcam)
        shadowNP.setPos(0, -1400, 450)
        shadowNP.lookAt(self.player)
        shadowNP.setScale(200)
        shadowNP.node().setShadowCaster(True)
        self.flameLights.append((shadowcam, shadowNP))
        
        for i in range(2):
            slight = PointLight('plight')
            slight.setColor(VBase4(0, 0, 0, 1))
            slight.setAttenuation(Point3(0, 0.001, 0.001))
            slnp = self.player.attachNewNode(slight)
            slnp.setPos(0, -750 - (950 * i), 450)
            slnp.setHpr(180, 0, 0)
            slnp.setScale(200)
            self.flameLights.append((slight, slnp))
        
        self.player.setupBooster()
        
        #self.env = loader.loadModel("models/environment")
        #self.env.reparentTo(render)
        #self.env.setScale(.25)
        #self.env.setPos(-8, 42, 0)
        self.env = loader.loadModel("models/terrain2")      
        self.env.reparentTo(render)
        self.env.setPos(0,0,0)
        
        self.setWorldLight(self.env)
        
        #load targets
        self.targets = []
        for i in range (10):
            target = loader.loadModel("smiley")
            target.setScale(.5)
            target.setPos(random.uniform(-20, 20), random.uniform(-15, 15), 2)
            target.reparentTo(self.targetRoot)
            self.targets.append(target)
            self.setWorldLight(target)
        
    def setupLights(self):
        #ambient light
        self.ambientLight = AmbientLight("ambientLight")
        #four values, RGBA (alpha is largely irrelevent), value range is 0:1
        self.ambientLight.setColor((.10, .10, .10, 1))
        self.ambientLightNP = render.attachNewNode(self.ambientLight)
        #the nodepath that calls setLight is what gets illuminated by the light
        render.setLight(self.ambientLightNP)
        #call clearLight() to turn it off
        
        self.keyLight = DirectionalLight("keyLight")
        self.keyLight.setColor((.20,.20,.20, 1))
        self.keyLightNP = render.attachNewNode(self.keyLight)
        self.keyLightNP.setHpr(0, -26, 0)
        
        self.fillLight = DirectionalLight("fillLight")
        self.fillLight.setColor((.05,.05,.05, 1))
        self.fillLightNP = render.attachNewNode(self.fillLight)
        self.fillLightNP.setHpr(30, 0, 0)
        
    def drive(self):
        """compound interval for driveing"""
        #some interval methods:
        # start(), loop(), pause(), resume(), finish()
        # start() can take arguments: start(starttime, endtime, playrate)
        dist = 5
        angle = deg2Rad(self.player.getH())
        dx = dist * math.sin(angle)
        dy = dist * -math.cos(angle)
        playerdrive = Parallel(self.player.posInterval(1, (self.player.getX() + dx, self.player.getY() + dy, 0)), \
            self.player.actorInterval("drive", loop=1, duration=2))
        playerdrive.start()
        
    def setupCollisions(self):
        #instantiates a collision traverser and sets it to the default
        base.cTrav = CollisionTraverser()
        self.cHandler = CollisionHandlerEvent()
        #set pattern for event sent on collision
        # "%in" is substituted with the name of the into object
        self.cHandler.setInPattern("ate-%in")
        
        cSphere = CollisionSphere((0,0,200), 450) #because the player is scaled way down
        self.playerRay = CollisionRay()
        self.playerRay.setOrigin(0,0,2000)
        self.playerRay.setDirection(0,0,-1)
        self.playerNode = CollisionNode("playerRay")
        self.playerNode.addSolid(self.playerRay)
        self.playerNode.setFromCollideMask(BitMask32.bit(0))
        self.playerNode.setIntoCollideMask(BitMask32.allOff())
        self.playerNodePath = self.player.attachNewNode(self.playerNode)
        self.playerNodePath.show()
        self.playerGroundHandler = CollisionHandlerFloor()
        self.playerGroundHandler.addCollider(self.playerNodePath, self.player)
        base.cTrav.addCollider(self.playerNodePath, self.playerGroundHandler)
        
        cNode = CollisionNode("player")
        cNode.addSolid(cSphere)
        cNode.setIntoCollideMask(BitMask32.allOff()) #player is *only* a from object
        #cNode.setFromCollideMask(BitMask32.bit(0))
        cNodePath = self.player.attachNewNode(cNode)
        #registers a from object with the traverser with a corresponding handler
        base.cTrav.addCollider(cNodePath, self.cHandler)
        i = 0
        for target in self.targets:
            cSphere = CollisionSphere((0,0,0), 2)
            cNode = CollisionNode("smiley")
            cNode.addSolid(cSphere)
            cNode.setIntoCollideMask(BitMask32.bit(1))
            cNode.setTag('target', str(i))
            cNodePath = target.attachNewNode(cNode)
            i += 1
    
    def lightModify(self, t, which_way):
        if which_way: #which_way == true then make it brighter
            value = t/100 * MAX_LIGHT
        else: #which_way == true then make it darker
            value = (100 - t)/100 * MAX_LIGHT
        for light in self.flameLights:
            light[0].setColor(VBase4(value,value,value,1))
        
    def startShoot(self):
        self.loadParticleConfig('flamethrower4.ptf')
        self.lightOff.finish()
        self.lightOn.start()
        
    def stopShoot(self):
        self.p1.softStop()
        self.p2.softStop()
        self.lightOn.finish()
        self.lightOff.start()
        
    def loadParticleConfig(self, file):
        self.p1.reset()
        self.p1 = ParticleEffect()
        self.p1.loadConfig(Filename(file))        
        self.p1.start(self.player)
        self.p1.setPos(-250, -700, 275)
        self.p1.setHpr(0, 90, 0)
        self.p1.setScale(200)
        self.p1.setLightOff()
        self.p2.reset()
        self.p2 = ParticleEffect()
        self.p2.loadConfig(Filename(file))        
        self.p2.start(self.player)
        self.p2.setPos(250, -700, 275)
        self.p2.setHpr(0, 90, 0)
        self.p2.setScale(200)
        self.p2.setLightOff()
        
    def eat(self, cEntry):
        """handles the player eating a smiley"""
        #remove target from list of targets
        self.targets.remove(cEntry.getIntoNodePath().getParent())
        #remove from scene graph
        cEntry.getIntoNodePath().getParent().remove()
Exemple #2
0
class World(DirectObject):
    def __init__(self):
        self.winprops=WindowProperties()
        self.winprops.setCursorFilename(Filename.binaryFilename("question-icon.ico"))
        
        base.win.setClearColorActive(True)
        base.win.setClearColor(VBase4(0, 0, 0, 1))
        
        base.win.requestProperties(self.winprops) 
        self.enemyLights = []
        self.cameraPositions = [((0, 95, 75), (180, -27, 0)),((0, 55, 25), (180, -15, 0)),((0, -55, 25), (0, -15, 0))]
        self.cameraIndex = 0
        base.disableMouse()
        base.enableParticles()
        self.setupLights()
        self.setupPicking()
        #Prepare the vehicular manslaughter!
        self.boosterLightNP = None
        self.flameLights = None
        self.player = Vehicle("ralph_models/vampire_car", "ralph_models/vampire_car", self, "player")

        self.finalGas = None

        self.livesFrame = DirectFrame(frameColor=(0, 0, 0, 0), parent = base.a2dTopLeft)

        self.livesSprites = list()
        for i in range(0,self.player.health):
            sprite = OnscreenImage(image = 'images/healthicon.png', parent = self.livesFrame, scale = 0.08, pos = (0.2*i+0.1,0,-0.1))
            sprite.setTransparency(TransparencyAttrib.MAlpha)
            self.livesSprites.append(sprite)

        self.progressFrame = DirectFrame(frameColor=(0, 0, 0, 0), parent = base.a2dpTopRight)
        gasIcon = OnscreenImage(image = 'images/gas_icon.png', parent = self.progressFrame, scale = 0.04, pos = (-1,0,-0.05))
        # gasIcon.reparentTo(aspect2d)
        gasIcon.setTransparency(TransparencyAttrib.MAlpha)
                    
        # gasBar = OnscreenImage(image = 'images/gas_bar.png', parent = self.progressFrame, scale = 0.4)#, pos = (-0.9,0,-0.05))
        self.gasMax = DirectFrame(frameColor=(.133, .149, .149, 1),frameSize=(-1, 1, -1, 1), parent = self.progressFrame, scale = (0.432,1,0.055625), pos = (-.5,0,-0.04))
        self.gasLevel = DirectFrame(frameColor=(.433, .149, .149, 1),frameSize=(-1, -1, -1, 1), parent = self.progressFrame, scale = (0.432,1,0.055625), pos = (-.5,0,-0.04))
        gasBar = OnscreenImage(image = 'images/gas_bar_border.png', scale = (1,1,.9), pos = (-.0005,0,-0.04))
        gasBar.reparentTo(self.gasLevel)
        gasBar.setTransparency(TransparencyAttrib.MAlpha)

        timeBar = OnscreenImage(image = 'images/time_bar.png', parent = self.progressFrame, scale = (0.44,1,0.0525), pos = (-.47,0,-0.15))
        self.timePointer = OnscreenImage(image = 'images/time_bar_marker.png', parent = timeBar, scale = (0.05, 0, .2222), pos = (-.83,0,-0.15))
        # self.timePointer = OnscreenImage(image = 'images/time_bar_marker.png', parent = self.timeBar, scale = (0.44,1,0.0525), pos = (-.47,0,-0.2))
        timeBar.setTransparency(TransparencyAttrib.MAlpha)


        taskMgr.add(self.updateGasBar, "Update gas")

        self.loadModels()
        self.player.setPos(0,0,0)
        self.setupIntervals()
        camera.reparentTo(self.player)
        camera.setPos(self.cameraPositions[0][0][0],self.cameraPositions[0][0][1],self.cameraPositions[0][0][2])
        camera.setHpr(self.cameraPositions[0][1][0],self.cameraPositions[0][1][1],self.cameraPositions[0][1][2])
        self.setupCollisions()
        render.setShaderAuto() #you probably want to use this
        self.keyMap = {"left":0, "right":0, "forward":0, "backwards":0}
        taskMgr.add(self.player.move, "moveTask")
        
        #Give the vehicle direct access to the keyMap
        self.player.addKeyMap(self.keyMap)
        
        #Player Death
        taskMgr.add(self.deathChecker, "deathTask")
        
        #Sounds!
        self.loadSounds()
        self.currIcon = ""
        self.prevtime = 0
        self.isMoving = False
        self.accept("escape", sys.exit)
        
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("w", self.setKey, ["forward", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("d", self.setKey, ["right", 1])
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("a", self.setKey, ["left", 1])
        self.accept("arrow_down", self.setKey, ["backwards", 1])
        self.accept("s", self.setKey, ["backwards", 1])
        
        self.accept("arrow_up-up", self.setKey, ["forward", 0])
        self.accept("w-up", self.setKey, ["forward", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("d-up", self.setKey, ["right", 0])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("a-up", self.setKey, ["left", 0])
        self.accept("arrow_down-up", self.setKey, ["backwards", 0])
        self.accept("s-up", self.setKey, ["backwards", 0])
        
        self.accept("mouse1", self.startShoot)
        self.accept("mouse1-up", self.stopShoot)
        self.accept("mouse3", self.startDrain )
        self.accept("mouse3-up" , self.stopDrain)
        
        self.accept("tab", self.shiftCamera)   
        self.accept("space", self.player.startBoosters)
        
        self.accept("ate-smiley", self.eat)
        self.p1 = ParticleEffect()
        self.p2 = ParticleEffect()
        self.alan_var = False
        #Show collisiony stuff
        if DEBUG:
            base.cTrav.showCollisions(render)
        
        #f = open('testLog.txt', 'r+')
        #self.dfs(file = f)
        
        self.gasPlaying = False
        self.setLights()
    
        self.draining = False
        taskMgr.add(self.drain, 'drain')
        self.drainTime = 0.0
    
        self.flamethrowerActive = False
        self.gasLossTime = 0.0
        self.gasLossRate = 1.0    
        taskMgr.add(self.loseHealth, "loseGas")
        
        #After all the loading, we need to calculate our start time
        self.startTime = datetime.datetime.now()
        self.timeLimit = datetime.timedelta(seconds=175)
        
        timeInterval = LerpPosInterval(self.timePointer,
                                      self.timeLimit.seconds,
                                      (.8,0,-0.2))
        timeInterval.start()
    
        
        
    def setupPicking(self):
        self.picker = CollisionTraverser()
        self.pq     = CollisionHandlerQueue()
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP, self.pq)
        
        self.staticRoot = render.attachNewNode('staticRoot')
        self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
        
    def dfs(self, item = render, depth = 0, file = None):
        if file:
            file.write(("-" * depth) + item.getName() + ": \n")
        # print(("-" * depth) + item.getName() + ": ")
        for i in range(item.getNumNodes()):
            if file:
                file.write((" " * depth) + "+" + item.getNode(i).getName() + ": " + str(item.getNode(i).getClassType()) + "\n")
            # print((" " * depth) + "+" + item.getNode(i).getName() + ": " + str(item.getNode(i).getClassType()))
        for i in range(item.getNumChildren()):
            self.dfs(item.getChild(i), depth + 1, file)
            
    def startDrain(self):
        if not self.flamethrowerActive:
            prevDraining = self.draining #previous value of draining
            if base.mouseWatcherNode.hasMouse():
                mpos = base.mouseWatcherNode.getMouse()
                self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
                self.picker.traverse(self.staticRoot)
                if self.pq.getNumEntries() > 0:
                    self.pq.sortEntries()
                    for i in range(self.pq.getNumEntries()):
                        if self.pq.getEntry(i).getIntoNode().getTag('car') != "":
                            self.target = int(self.pq.getEntry(i).getIntoNode().getTag('car'))
                            self.draining = True
            #Start sounds if self.draining started
            if self.draining and not prevDraining:
                self.drainSound.play()

    def drain(self, task):
        if self.draining and task.time - self.drainTime > DRAIN_DELAY:
            carpos = self.staticCars[self.target].getPos()
            playerpos = self.player.getPos()
            dist = math.sqrt( (carpos[0] - playerpos[0])**2 + (carpos[1] - playerpos[1])**2 + (carpos[2] - playerpos[2])**2 )
            if self.gasList[self.target] > 0 and dist < DRAIN_DIST:
                if not self.gasPlaying:
                    self.gasP.reset()
                    self.gasP = ParticleEffect()  
                    self.gasP.loadConfig(Filename('oil.ptf'))        
                    self.gasP.start(self.player)
                    self.gasNode.lookAt(self.staticCars[self.target])
                    self.gasP.setPos(0,0,2)
                    self.gasP.setScale(1.5)
                    self.gasP.setLightOff()
                    self.gasPlaying = True
                    self.alan_var = False
                self.gasNode.lookAt(self.staticCars[self.target])
                self.gasP.setHpr(self.gasNode.getH() + 180, 90, 0)
                self.player.totalGas = self.player.totalGas + 1
                self.gasList[self.target] = self.gasList[self.target] - 1
            else:
                self.alan_var = True
            # print "TotalGas: " + str(self.player.totalGas)
            self.drainTime = task.time
        elif not self.draining or self.alan_var:
            self.gasP.softStop()
            self.drainSound.stop()
            self.gasPlaying = False
        return Task.cont
                     
    def stopDrain(self):
        self.draining = False
           
    def loseHealth(self, task):
        if task.time - self.gasLossTime > GAS_TIME:
            if self.player.direction != 0:
                self.player.totalGas = self.player.totalGas - self.gasLossRate
            elif self.flamethrowerActive:
                self.player.totalGas = self.player.totalGas - self.gasLossRate
            self.gasLossTime = task.time
            # print self.player.totalGas
        return Task.cont
           
    def mouseTask(self, task):
        j = -1
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.picker.traverse(self.staticRoot)
            if self.pq.getNumEntries() > 0:
                self.pq.sortEntries()
                for i in range(self.pq.getNumEntries()):
                    if self.pq.getEntry(i).getIntoNode().getTag('car') != "":
                        j = int(self.pq.getEntry(i).getIntoNode().getTag('car'))
                        carpos = self.staticCars[j].getPos()  
                        playerpos = self.player.getPos()
                        dist = math.sqrt( (carpos[0] - playerpos[0])**2 + (carpos[1] - playerpos[1])**2 + (carpos[2] - playerpos[2])**2 )
                        if self.gasList[j] > 0 and dist < DRAIN_DIST:
                            self.winprops.setCursorFilename(Filename.binaryFilename("vamp-icon.ico"))
                            base.win.requestProperties(self.winprops)
                        elif self.gasList[j] > 0:
                            self.winprops.setCursorFilename(Filename.binaryFilename("vamp-off.ico"))
                            base.win.requestProperties(self.winprops)
                        else:
                            self.winprops.setCursorFilename(Filename.binaryFilename("empty-icon.ico"))
                            base.win.requestProperties(self.winprops)
                        break
        if j == -1:
            self.winprops.setCursorFilename(Filename.binaryFilename("question-icon.ico"))
            base.win.requestProperties(self.winprops)
        #print j
        return Task.cont
    
    def setupIntervals(self):
        self.lightOn = LerpFunc(self.lightModify,
                            fromData=0,
                            toData=100,
                            duration=0.2,
                            blendType='noBlend',
                            extraArgs=[True],
                            name="LightUp")
        self.lightOff = LerpFunc(self.lightModify,
                            fromData=0,
                            toData=100,
                            duration=0.2,
                            blendType='noBlend',
                            extraArgs=[False],
                            name="LightDown")
                            
        self.cameraMove = None
 
    def setKey(self, key, value):
        self.keyMap[key] = value
        
    def setWorldLight(self, object):
        object.setLight(self.keyLightNP)
        object.setLight(self.fillLightNP)
        object.setLight(self.boosterLightNP)
        for light in self.enemyLights:
            object.setLight(light)
        
    def setLights(self):
        self.setWorldLight(self.player)
        self.setWorldLight(self.env)
        for enemy in self.enemies:
            self.setWorldLight(enemy)
        for car in self.staticCars:
            self.setWorldLight(car)
        
    def shiftCamera(self):
        if self.cameraMove:
            self.cameraMove.finish()
        old = self.cameraIndex
        self.cameraIndex += 1
        if self.cameraIndex == len(self.cameraPositions):
            self.cameraIndex = 0
        self.cameraMove=LerpPosHprInterval(camera,
                                            .7, 
                                            self.cameraPositions[self.cameraIndex][0], 
                                            self.cameraPositions[self.cameraIndex][1],
                                            camera.getPos(), 
                                            camera.getHpr())
        self.cameraMove.start()
      
    def loadModels(self):
        self.player.setupBooster()
        self.env = loader.loadModel("ralph_models/final_terrain")      
        self.env.reparentTo(render)
        self.env.setScale(8)
        
        # Gas particles
        self.gasP = ParticleEffect()
        self.gasNode = self.player.attachNewNode('gasNode')
        
        # Node Map
        map = Node.NodeMap("nodes.txt")
            
        # enemies    
        self.enemies = []
        file = open('levels/enemies.txt' )
        line = file.readline().rstrip()
        
        self.staticCars = []
        self.gasList = []
        for currCar in carLocations.cars:
            target = loader.loadModel("ralph_models/" + currCar['color'] + "_car")
            target.setPos(currCar['position'])
            target.setHpr(currCar['direction'])
            target.reparentTo(self.staticRoot)
            self.staticCars.append(target)
            self.gasList.append(currCar['gas'])
            
        while line != "" :
            nums = line.split(',')
            convertedNums = []
            for i in range(len(nums)):
                if i != 0:
                    convertedNums.append(int(nums[i]))
            nodePos = map.nodeList[int(nums[0])].getPos()
            newEnemy = Enemy.Enemy(map, convertedNums, self, nodePos[0], nodePos[1], nodePos[2] )
            self.enemies.append( newEnemy )
            taskMgr.add(newEnemy.move, "Enemy Move " + str(i), extraArgs = [map], appendTask = True)
            line = file.readline().rstrip()
            i = i + 1
                  
    def loadSounds(self):
        self.flamethrowerSound = base.loader.loadSfx("sound/dragonflameloop2.wav")
        self.flamethrowerEndSound = base.loader.loadSfx("sound/dragonflameend.wav")
        self.collideSound = base.loader.loadSfx("sound/collide.wav")
        self.drainSound = base.loader.loadSfx("sound/gas_pump.wav")
        self.drainSound.setLoop(True)
        
    def setupLights(self):
        #ambient light
        self.ambientLight = AmbientLight("ambientLight")
        #four values, RGBA (alpha is largely irrelevent), value range is 0:1
        self.ambientLight.setColor((.30, .30, .30, 1))
        self.ambientLightNP = render.attachNewNode(self.ambientLight)
        #the nodepath that calls setLight is what gets illuminated by the light
        render.setLight(self.ambientLightNP)
        #call clearLight() to turn it off
        
        self.keyLight = DirectionalLight("keyLight")
        self.keyLight.setColor((.50,.50,.50, 1))
        self.keyLightNP = render.attachNewNode(self.keyLight)
        self.keyLightNP.setHpr(0, -26, 0)
        
        self.fillLight = DirectionalLight("fillLight")
        self.fillLight.setColor((.05,.05,.05, 1))
        self.fillLightNP = render.attachNewNode(self.fillLight)
        self.fillLightNP.setHpr(30, 0, 0)
               
    def setupCollisions(self):       
        base.cTrav = CollisionTraverser() 
        self.playerRay = CollisionRay()
        self.playerRay.setOrigin(0,0,1000)
        self.playerRay.setDirection(0,0,-1)
        self.playerNode = CollisionNode("playerRay")
        self.playerNode.addSolid(self.playerRay)
        self.playerNode.setFromCollideMask(BitMask32.bit(0))
        self.playerNode.setIntoCollideMask(BitMask32.allOff())
        self.playerNodePath = self.player.attachNewNode(self.playerNode)
        self.playerNodePath.show()
        self.playerGroundHandler = CollisionHandlerQueue()
        base.cTrav.addCollider(self.playerNodePath, self.playerGroundHandler)
        
        envcNode1 = CollisionNode("lot_bottom")
        envcNode1.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(12.56, 19.182, 0), Point3(12.56, -21.261, 0),
                                Point3(-13.217, -21.261, 0), Point3(-13.217, 19.182, 0))
        envcNode1.addSolid(temp)
        
        envcNode2 = CollisionNode("lot_ramp_bottom")
        envcNode2.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(32.715, -14.923, 3.5), Point3(32.715, -21.261, 3.5),
                                Point3(12.56, -21.261, 0), Point3(12.56, -14.923, 0))
        envcNode2.addSolid(temp)
        
        envcNode3 = CollisionNode("lot_middle")
        envcNode3.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(42.715, -14.923, 3.5), Point3(42.715, -21.261, 3.5),
                                Point3(32.715, -21.261, 3.5), Point3(32.715, -14.923, 3.5))
        envcNode3.addSolid(temp)
        
        envcNode4 = CollisionNode("lot_ramp_top")
        envcNode4.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(42.715, -8.845, 6), Point3(42.715, -14.923, 3.5),
                                Point3(32.715, -14.923, 3.5), Point3(32.715, -8.845, 6))
        envcNode4.addSolid(temp)
        
        envcNode5 = CollisionNode("lot_top")
        envcNode5.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(42.715, 16.155, 6), Point3(42.715, -8.845, 6),
                                Point3(17.715, -8.845, 6), Point3(17.715, 16.155, 6))
        envcNode5.addSolid(temp)
        
        wallCNode = CollisionNode("fence")
        wallCNode.setFromCollideMask(BitMask32.bit(0))
        temp = CollisionPolygon(Point3(12.56, 19.182, 0), Point3(12.56, -14.923, 0),
                                Point3(12.56, -14.923, 10), Point3(12.56, 19.182, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(12.56, -14.923, 0), Point3(32.715, -14.923, 3.5),
                                Point3(32.715, -14.923, 10), Point3(12.56, -14.923, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(32.715, -14.923, 3.5), Point3(32.715, -8.845, 6),
                                Point3(32.715, -8.845, 10), Point3(32.715, -14.923, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(32.715, -8.845, 6), Point3(17.715, -8.845, 6),
                                Point3(17.715, -8.845, 10), Point3(32.715, -8.845, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(17.715, -8.845, 6), Point3(17.715, 16.155, 6),
                                Point3(17.715, 16.155, 10), Point3(17.715, -8.845, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(17.715, 16.155, 6), Point3(42.715, 16.155, 6),
                                Point3(42.715, 16.155, 10), Point3(17.715, 16.155, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(42.715, 16.155, 6), Point3(42.715, -8.845, 6),
                                Point3(42.715, -8.845, 10), Point3(42.715, 16.155, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(42.715, -8.845, 6), Point3(42.715, -14.923, 3.5),
                                Point3(42.715, -14.923, 10), Point3(42.715, -8.845, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(42.715, -14.923, 3.5), Point3(42.715, -21.261, 3.5),
                                Point3(42.715, -21.261, 10), Point3(42.715, -14.923, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(42.715, -21.261, 3.5), Point3(32.715, -21.261, 3.5),
                                Point3(32.715, -21.261, 10), Point3(42.715, -21.261, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(32.715, -21.261, 3.5), Point3(12.56, -21.261, 0),
                                Point3(12.56, -21.261, 10), Point3(32.715, -21.261, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(12.56, -21.261, 0), Point3(-13.217, -21.261, 0),
                                Point3(-13.217, -21.261, 10), Point3(12.56, -21.261, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(-13.217, -21.261, 0), Point3(-13.217, 19.182, 0),
                                Point3(-13.217, 19.182, 10), Point3(-13.217, -21.261, 10))
        wallCNode.addSolid(temp)
        temp = CollisionPolygon(Point3(-13.217, 19.182, 0), Point3(12.56, 19.182, 0),
                                Point3(12.56, 19.182, 10), Point3(-13.217, 19.182, 10))
        wallCNode.addSolid(temp)
        
        
        envcNodePath1 = self.env.attachNewNode(envcNode1)
        envcNodePath2 = self.env.attachNewNode(envcNode2)
        envcNodePath3 = self.env.attachNewNode(envcNode3)
        envcNodePath4 = self.env.attachNewNode(envcNode4)
        envcNodePath5 = self.env.attachNewNode(envcNode5)
        
        self.cHandler = CollisionHandlerEvent()
        pusher = CollisionHandlerPusher()
        
        self.wallNode = self.env.attachNewNode('wallNode')
        wallCNodePath = self.wallNode.attachNewNode(wallCNode)
        if DEBUG:
            wallCNodePath.show()
            
        cNode = CollisionNode("player")
        temp = CollisionSphere((0,-5.5,10), 4)
        cNode.addSolid(temp)
        temp = CollisionSphere((0,-0.5,10), 4)
        cNode.addSolid(temp)
        temp = CollisionSphere((0,3.5,10), 4)
        cNode.addSolid(temp)
        cNode.setIntoCollideMask(BitMask32.allOff()) #player is *only* a from object
        cNodePath = self.player.attachNewNode(cNode)
        
        if DEBUG:
            cNodePath.show()
            
        base.cTrav.addCollider(cNodePath, pusher)
        pusher.addCollider(cNodePath, self.player)
        pusher.addInPattern('%fn-into-%in')
        self.accept('player-into-fence', self.collideWithFence)
        self.accept('player-into-staticCar', self.collideOther)
        self.accept('player-into-droneNode', self.collideOther)
        
        self.playerLightCollision = CollisionHandlerEvent()
        self.playerLightCollision.addInPattern('into-%in')
        
        cNode2 = CollisionNode("playerinto")
        
        #cNode.addSolid(segment1)
        #cNode.addSolid(segment2)
        #cNode.addSolid(segment3)
        #cNode.addSolid(segment4)
        temp = CollisionSphere((0,-5.5,1), 4)
        cNode2.addSolid(temp)
        temp = CollisionSphere((0,-0.5,1), 4)
        cNode2.addSolid(temp)
        temp = CollisionSphere((0,3.5,1), 4)
        cNode2.addSolid(temp)
        cNode2.setFromCollideMask(BitMask32.allOff()) #player is *only* a from object
        cNodePath2 = self.player.attachNewNode(cNode2)
        if DEBUG:
            cNodePath2.show()
        
        # FLAMETHROWER COLLISIONS
        # left
        flamethrowerLeft = CollisionSegment()
        flamethrowerLeft.setPointA(-2 , -4, 10)
        flamethrowerLeft.setPointB( -2 , -20 , 10 ) 
        
        # middle
        flamethrowerMiddle = CollisionSegment()
        flamethrowerMiddle.setPointA(0 , -4, 10)
        flamethrowerMiddle.setPointB( 0 , -20 , 10 ) 
        
        # right
        flamethrowerRight = CollisionSegment()
        flamethrowerRight.setPointA(2, -4, 10)
        flamethrowerRight.setPointB( 2 , -20 , 10 ) 
        
        flamethrowerNode = CollisionNode("flamethrower")
        flamethrowerNode.addSolid(flamethrowerLeft)
        flamethrowerNode.addSolid(flamethrowerMiddle)
        flamethrowerNode.addSolid(flamethrowerRight)
        flamethrowerNode.setIntoCollideMask(BitMask32.allOff())
        flamethrowerNode.setFromCollideMask(BitMask32.allOn())
        flamethrowerNodePath = self.player.attachNewNode(flamethrowerNode)
        
        #flamethrowerNodePath.show()
        
        self.flamethrowerCollision = CollisionHandlerEvent()
        self.flamethrowerCollision.addInPattern('into-%in')
        base.cTrav.addCollider(flamethrowerNodePath, self.flamethrowerCollision)
        self.accept('into-droneNode', self.hitEnemy)
        
        for i in range(len(self.staticCars)):
            staticNode = CollisionNode("staticCar")
            temp = CollisionSphere((0,-5.2,10), 4)
            staticNode.addSolid(temp)
            temp = CollisionSphere((0,-0.5,10), 4)
            staticNode.addSolid(temp)
            temp = CollisionSphere((0,5.5,10), 4)
            staticNode.addSolid(temp)
            staticNode.setIntoCollideMask(BitMask32.bit(1))
            staticNode.setFromCollideMask(BitMask32.bit(0))
            staticNodePath = self.staticCars[i].attachNewNode(staticNode)
            temp = CollisionTube(0,7,3,0,-6,3,3.5)
            sN = CollisionNode("staticTube")
            sN.addSolid(temp)
            staticNode.setFromCollideMask(BitMask32.bit(0))
            sNP = self.staticCars[i].attachNewNode(sN)
            sN.setTag('car', str(i))
            
        self.enemyHandler = CollisionHandlerEvent()    
        for i in range(len(self.enemies)):
            collideNode = CollisionNode("droneNode")
            temp = CollisionSphere((0,0,10), 4)
            collideNode.addSolid(temp)
            collideNode.setIntoCollideMask(BitMask32.bit(1))
            collideNode.setFromCollideMask(BitMask32.bit(0))
            enemycollideNodePath = self.enemies[i].attachNewNode(collideNode)
            
            collideNode.setTag('enemy',str(i))
            
            self.enemies[i].lightRay = CollisionSegment()
            self.enemies[i].lightRay.setPointA(0, -4, 4)
            self.enemies[i].lightRay.setPointB( 0 , -100 , 0 ) 
            
            # left
            self.enemies[i].lightRayLeft = CollisionSegment()
            self.enemies[i].lightRayLeft.setPointA(0, -4, 4)
            self.enemies[i].lightRayLeft.setPointB( -5 , -100 , 0 ) 
            
            # right
            self.enemies[i].lightRayRight = CollisionSegment()
            self.enemies[i].lightRayRight.setPointA(0, -4, 4)
            self.enemies[i].lightRayRight.setPointB( 5 , -100 , 0 ) 
            
            self.enemies[i].lightRayNode = CollisionNode("lightRay")
            self.enemies[i].lightRayNode.addSolid(self.enemies[i].lightRay)
            self.enemies[i].lightRayNode.addSolid(self.enemies[i].lightRayLeft)
            self.enemies[i].lightRayNode.addSolid(self.enemies[i].lightRayRight)
            
            self.enemies[i].lightRayNode.setTag('enemy',str(i))
            
            self.enemies[i].lightRayNode.setIntoCollideMask(BitMask32.allOff())
            self.enemies[i].lightRayNodePath = self.enemies[i].attachNewNode(self.enemies[i].lightRayNode)
            if DEBUG:
                self.enemies[i].lightRayNodePath.show()
            
            base.cTrav.addCollider(self.enemies[i].lightRayNodePath, self.playerLightCollision)
        self.accept('into-playerinto', self.player.takeHit)
    
    def collideWithFence(self, entry):
        self.player.speed = self.player.speed * 0.9
        if self.collideSound.status() != AudioSound.PLAYING:
            self.collideSound.play()
    
    def collideOther(self, entry):
        self.player.speed = self.player.speed * 0.9
        if self.collideSound.status() != AudioSound.PLAYING:
            self.collideSound.play()
        
    def lightModify(self, t, which_way):

        if which_way: #which_way == true then make it brighter
            value = t/100 * MAX_LIGHT
        else: #which_way == true then make it darker
            value = (100 - t)/100 * MAX_LIGHT
        for light in self.flameLights:
            light[0].setColor(VBase4(value,value,value,1))
        
    def startShoot(self):
        self.loadParticleConfig('flamethrower6.ptf')
        #self.lightOff.finish()
        #self.lightOn.start()
        
        #Get the flame noise started!
        self.flamethrowerSound.setLoop(True)
        self.flamethrowerSound.play()
        self.flamethrowerActive = True
        self.draining = False
        self.gasLossRate = 2.0
        
    def stopShoot(self):
        self.p1.softStop()
        self.p2.softStop()
        #self.lightOn.finish()
        #self.lightOff.start()
        
        self.flamethrowerSound.stop()
        self.flamethrowerEndSound.play()
        self.flamethrowerActive = False
        self.gasLossRate = 1.0
        
    def hitEnemy(self, entry):
        if self.flamethrowerActive:
            index = int(entry.getIntoNode().getTag('enemy'))
            if self.enemies[index].phase != STOPPED:
                self.enemies[index].prevPhase = self.enemies[index].phase
                self.enemies[index].phase = STOPPED
                self.enemies[index].headlight1.setColor(VBase4(0, 0, 0, 0))
        
    def loadParticleConfig(self, file):
        self.p1.reset()
        self.p1 = ParticleEffect()
        self.p1.loadConfig(Filename(file))        
        self.p1.start(self.player)
        self.p1.setPos(-1.75, -10, 1.375)
        self.p1.setHpr(0, 90, 0)
        self.p1.setScale(2.0)
        self.p1.setLightOff()
        self.p2.reset()
        self.p2 = ParticleEffect()
        self.p2.loadConfig(Filename(file))        
        self.p2.start(self.player)
        self.p2.setPos(1.75, -10, 1.375)
        self.p2.setHpr(0, 90, 0)
        self.p2.setScale(2.0)
        self.p2.setLightOff()
        
    def eat(self, cEntry):
        """handles the player eating a smiley"""
        #remove target from list of targets
        self.targets.remove(cEntry.getIntoNodePath().getParent())
        #remove from scene graph
        cEntry.getIntoNodePath().getParent().remove()
           
    def changeMouseCursor(self, cursorFile):
        if self.currIcon != cursorFile:
            self.currIcon = cursorFile
            # winprops.getParentWindow().getXSize()
            # print winprops.getXSize()
            # print "test"
            self.winprops.setCursorFilename(Filename.binaryFilename(cursorFile))
    
    def deathChecker(self, task):
        font = loader.loadFont('fonts/beneg.ttf')

        #Check for out of time
        currTime = datetime.datetime.now()
        if currTime > self.startTime + self.timeLimit or self.player.totalGas >= MAX_GAS:
            #print "OUT OF TIME!!!!!!!!!!!"

            if self.finalGas is None:
                self.finalGas = self.player.totalGas
            
            taskMgr.doMethodLater(5, self.STOPGAME, 'tickTask')
            self.loading = OnscreenImage(image = 'images/victory.png', scale = (1.3333333,0, 1))
            self.text = OnscreenText(text = "Gas Collected%s" %(self.finalGas), font = font, pos = (0,.2), fg = (255,255,255,1))
        #Check for death
        elif self.player.dead:
            if self.finalGas is None:
                self.finalGas = self.player.totalGas

            #print "THE PLAYER IS DEAD!!!!!!!!!!"
            taskMgr.doMethodLater(5, self.STOPGAME, 'tickTask')
            self.loading = OnscreenImage(image = 'images/lose_death.png', scale = (1.3333333,0, 1))
            self.text = OnscreenText(text = "Gas Collected %s" %(self.finalGas), font = font, pos = (0,.1), fg = (255,255,255,1))
        elif self.player.totalGas <= 0:
            #print "YOU SUCK. YOU RAN OUT OF GAS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
            taskMgr.doMethodLater(5, self.STOPGAME, 'tickTask')
            self.loading = OnscreenImage(image = 'images/lose_nogas.png', scale = (1.3333333,0, 1))
        return Task.cont

        
    def updateGasBar(self, task):
        self.gasLevel['frameSize'] = (-1,(self.player.totalGas / MAX_GAS)*2 - 1, -1, 1)
        return Task.cont
    def STOPGAME(self, SOMETHNG):
        taskMgr.stop()