def throwObject(self, projectile=True):
     if not self.weapon:
         return
     self.acceptOnce('enter' + self.wsnp.node().getName(), self.handleWeaponCollision)
     self.playWeaponSound()
     if self.weapon:
         self.weapon.wrtReparentTo(render)
         self.weapon.setHpr(Vec3(0, 0, 0))
     if self.attack not in ('glowerpower', ):
         parent = self.suit.find('**/joint_Rhold')
     else:
         parent = self.suit.find('**/joint_head')
     startNP = parent.attachNewNode('startNp')
     startNP.lookAt(render, self.targetX, self.targetY, self.targetZ)
     pathNP = NodePath('throwPath')
     pathNP.reparentTo(startNP)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 50, 0)
     if self.attack in ('clipontie', 'powertie', 'halfwindsor'):
         self.weapon.setHpr(pathNP.getHpr(render))
     if projectile == True:
         self.throwTrajectory = ProjectileInterval(self.weapon, startPos=self.suit.find('**/joint_Rhold').getPos(render), endPos=pathNP.getPos(render), gravityMult=0.7, duration=1.0)
     else:
         self.weapon.setH(pathNP.getH(render))
         self.throwTrajectory = LerpPosInterval(self.weapon, duration=0.5, pos=pathNP.getPos(render), startPos=startNP.getPos(render) + (0,
                                                                                                                                         3,
                                                                                                                                         0))
     self.throwTrajectory.start()
     self.weapon_state = 'released'
     startNP.removeNode()
     del startNP
     pathNP.removeNode()
     del pathNP
示例#2
0
 def generateToonMoveTrack(self, toon):
     node = NodePath('tempNode')
     displacement = Vec3(toon.getPos(render) - self.getPos(render))
     displacement.setZ(0)
     displacement.normalize()
     movieDistance = self.movieNode.getDistance(self.rotateNode)
     displacement *= movieDistance
     node.reparentTo(render)
     node.setPos(displacement + self.getPos(render))
     node.lookAt(self)
     heading = PythonUtil.fitDestAngle2Src(toon.getH(render),
                                           node.getH(render))
     hpr = toon.getHpr(render)
     hpr.setX(heading)
     finalX = node.getX(render)
     finalY = node.getY(render)
     finalZ = node.getZ(render)
     node.removeNode()
     toonTrack = Sequence(
         Parallel(
             ActorInterval(toon, 'walk', loop=True, duration=1),
             Parallel(
                 LerpPosInterval(toon,
                                 1.0,
                                 Point3(finalX, finalY, toon.getZ(render)),
                                 fluid=True,
                                 bakeInStart=False)),
             LerpHprInterval(toon, 1.0, hpr=hpr)),
         Func(toon.loop, 'neutral'))
     return toonTrack
示例#3
0
 def throwObject(self, projectile = True):
     if not self.weapon:
         return
     self.acceptOnce('enter' + self.wsnp.node().getName(), self.handleWeaponCollision)
     self.playWeaponSound()
     if self.weapon:
         self.weapon.wrtReparentTo(render)
         self.weapon.setHpr(Vec3(0, 0, 0))
     if self.attack not in ('glowerpower',):
         parent = self.suit.find('**/joint_Rhold')
     else:
         parent = self.suit.find('**/joint_head')
     startNP = parent.attachNewNode('startNp')
     startNP.lookAt(render, self.targetX, self.targetY, self.targetZ)
     pathNP = NodePath('throwPath')
     pathNP.reparentTo(startNP)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 50, 0)
     if self.attack in ('clipontie', 'powertie', 'halfwindsor'):
         self.weapon.setHpr(pathNP.getHpr(render))
     if projectile == True:
         self.throwTrajectory = ProjectileInterval(self.weapon, startPos=self.suit.find('**/joint_Rhold').getPos(render), endPos=pathNP.getPos(render), gravityMult=0.7, duration=1.0)
     else:
         self.weapon.setH(pathNP.getH(render))
         self.throwTrajectory = LerpPosInterval(self.weapon, duration=0.5, pos=pathNP.getPos(render), startPos=startNP.getPos(render) + (0, 3, 0))
     self.throwTrajectory.start()
     self.weapon_state = 'released'
     startNP.removeNode()
     del startNP
     pathNP.removeNode()
     del pathNP
示例#4
0
class CamManager(DirectObject.DirectObject):
    """1st or 3d person camera, or disable
    """
    def __init__(self, game):
        self.game = game
        self.char = self.game.char
        self.win = self.game.gui.win
        self.hotkeys = self.game.gui.hotkeys
        self.node = NodePath('char')
        self.Ccentr = NodePath('Ccentr')
        self.Ccentr.reparentTo(self.node)
        self.Ccentr.setZ(1)
        self.third_dist = -6
        self.sleep = 0.001
        self.camera = self.game.gui.camera
        self.char.reparentTo(self.node)
        taskMgr.setupTaskChain('cam_move', numThreads = 1,
                       frameSync = False, threadPriority = TPUrgent, timeslicePriority = False)


    def set_enable(self, value, third = False):
        self.enable = value
        self.third = third

        self.node.reparentTo(self.game.world.root_node)
        self.node.setPos(self.game.world.avatar.getPos())
        if self.enable:
            self.camera.reparentTo(self.Ccentr)
            if self.third:
                self.camera.setPos(0, self.third_dist, 0)
                #self.char.show()
            else:
                self.camera.setPos(0, 0, 0)
                #self.char.hide()
            self.camera.lookAt(self.Ccentr)
            taskMgr.add(self.mouse_update, 'mouse-task')
        else:
            self.camera.reparentTo(self.game.world.root_node)
            self.camera.setPos(self.game.world.root_node, self.game.world.avatar.getPos(self.game.world.root_node))
            self.node.detachNode()

    #@profile_decorator
    def mouse_update(self, task):
        """ this task updates the mouse """
        if not self.enable:
            return task.done

        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if self.win.movePointer(0, self.win.getXSize()/2, self.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - self.win.getXSize()/2)*0.1)
            self.Ccentr.setP(self.Ccentr.getP() - (y - self.win.getYSize()/2)*0.1)

        time.sleep(self.sleep)
        return task.cont

    def point_dist(self, p1, p2):
        return math.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2+(p1[2]-p2[2])**2)
示例#5
0
class SkyBox(DynamicElement):
    """
    SkyBox is only related to render
    """
    ROTATION_MAX = 5000

    def __init__(self, pure_background: bool = False):
        super(SkyBox, self).__init__()
        self._accumulate = 0
        self.f = 1
        if not self.render or pure_background:
            self.node_path = NodePath("pure_background")
            return
        skybox = self.loader.loadModel(AssetLoader.file_path("models", "skybox.bam"))

        skybox.hide(CamMask.MiniMap | CamMask.RgbCam | CamMask.Shadow | CamMask.ScreenshotCam)
        skybox.set_scale(20000)

        skybox_texture = self.loader.loadTexture(AssetLoader.file_path("textures", "skybox.jpg"))
        skybox_texture.set_minfilter(SamplerState.FT_linear)
        skybox_texture.set_magfilter(SamplerState.FT_linear)
        skybox_texture.set_wrap_u(SamplerState.WM_repeat)
        skybox_texture.set_wrap_v(SamplerState.WM_mirror)
        skybox_texture.set_anisotropic_degree(16)
        skybox.set_texture(skybox_texture)

        gles = ConfigVariableString("load-display").getValue()
        if gles == "pandagles2":
            skybox_shader = Shader.load(
                Shader.SL_GLSL, AssetLoader.file_path("shaders", "skybox_gles.vert.glsl"),
                AssetLoader.file_path("shaders", "skybox_gles.frag.glsl")
            )
        else:
            if is_mac():
                vert_file = "skybox_mac.vert.glsl"
                frag_file = "skybox_mac.frag.glsl"
            else:
                vert_file = "skybox.vert.glsl"
                frag_file = "skybox.frag.glsl"
            skybox_shader = Shader.load(
                Shader.SL_GLSL, AssetLoader.file_path("shaders", vert_file),
                AssetLoader.file_path("shaders", frag_file)
            )
        skybox.set_shader(skybox_shader)
        self.node_path = skybox
        skybox.setZ(-4400)
        skybox.setH(30)

    def step(self):
        if not self.render:
            return
        if self._accumulate >= self.ROTATION_MAX:
            self.f *= -1
            self._accumulate = 0
        self._accumulate += 1
        factor = self.f * (1 - abs(self._accumulate - self.ROTATION_MAX / 2) * 2 / self.ROTATION_MAX)
        self.node_path.setH(self.node_path.getH() + factor * 0.0035)
示例#6
0
 def buildRotateAnim(self, unit_model, start_pos, end_pos, start_h, heading=None):
     if heading == None:
         dummy_start = NodePath("dummy_start")
         dummy_end = NodePath("dummy_end")
         dummy_start.setPos(start_pos)
         dummy_end.setPos(end_pos)
         dummy_start.lookAt(dummy_end)
         end_h = dummy_start.getH(render)
     else:
         end_h = utils.getHeadingAngle(heading)
     interval = unit_model.model.quatInterval(0.2, hpr = Point3(end_h, 0, 0), startHpr = Point3(start_h, 0, 0))
     duration = 0.2
     return interval, duration, start_pos, end_h          
示例#7
0
 def _runToonThroughSlot(self, toon, slot, goInside=True):
     helperNode = NodePath('helper')
     helperNode.reparentTo(toon.getParent())
     helperNode.lookAt(self)
     lookAtH = helperNode.getH(self._model)
     toonH = toon.getH(self._model)
     hDiff = abs(lookAtH - toonH)
     distanceFromElev = toon.getDistance(self._model)
     moveSpeed = 9.778
     anim = 'run'
     if toon.animFSM.getCurrentState() == 'Sad':
         moveSpeed *= 0.5
         anim = 'sad-walk'
     runInsideDistance = 20
     track = Sequence(Func(toon.stopSmooth),
                      Func(toon.loop, anim, 1.0),
                      Parallel(
                          toon.hprInterval(hDiff / 360.0,
                                           Point3(lookAtH, 0, 0),
                                           other=self._model,
                                           blendType='easeIn'),
                          toon.posInterval(distanceFromElev / moveSpeed,
                                           Point3(
                                               self._elevatorPoints[slot],
                                               0, 0),
                                           other=self._model,
                                           blendType='easeIn')),
                      name=toon.uniqueName('runThroughExit'),
                      autoPause=1)
     if goInside:
         track.append(
             Parallel(
                 toon.hprInterval(lookAtH / 360.0,
                                  Point3(0, 0, 0),
                                  other=self._model,
                                  blendType='easeOut'),
                 toon.posInterval(runInsideDistance / moveSpeed,
                                  Point3(self._elevatorPoints[slot],
                                         runInsideDistance, 0),
                                  other=self._model,
                                  blendType='easeOut')))
     track.append(Func(self._clearToonTrack, toon))
     track.append(Func(toon.setAnimState, 'Happy', 1.0))
     self._storeToonTrack(toon, track)
     track.start()
示例#8
0
 def buildMoveAnim(self, unit_model, start_pos, end_pos, start_h):
     dummy_start = NodePath("dummy_start")
     dummy_end = NodePath("dummy_end")
     duration = 0.0
     p = None   
     dummy_start.setPos(start_pos)
     dummy_end.setPos(end_pos)
     dummy_start.lookAt(dummy_end) 
     end_h = dummy_start.getH(render)               
     # Model heading is different than movement heading, first create animation that turns model to his destination
     i_h = None
     if end_h != start_h:
         i_h = unit_model.model.quatInterval(0.2, hpr = Point3(end_h, 0, 0), startHpr = Point3(start_h, 0, 0))
     i = unit_model.node.posInterval(0.5, end_pos, start_pos)
     duration += 0.5
     if i_h:
         p = Parallel(i, i_h)
     else:
         p = i
     return p, duration, end_pos, end_h  
示例#9
0
class Vehicle(ActorNode):
    def __init__(self, parent=None):
        '''
        Create a new Vehicle node. Physics should be initialized before any
        instances of Vehicle are created.

        arguments:
          parent -- A PandaNode for the vehicle to attach to. Default is None,
                    in which case the Vehicle should be added to the scene
                    graph via NodePath.attachNewNode().

        '''
        ActorNode.__init__(self, 'VehiclePhysics')
        base.physicsMgr.attachPhysicalNode(self)

        self.getPhysicsObject().setMass(MASS)
        if parent:
            self.myPath = parent.attachNewNode(self)
        else:
            self.myPath = NodePath(self)

        # Load vehicle model and place in the transparent bin.
        vehicleModel = loader.loadModel(MODEL_PATH)
        hull = vehicleModel.find('**/Hull')
        hull.setBin('transparent', 30)
        pwnsEnclosure = vehicleModel.find('**/Pwns_Enclosure')
        pwnsEnclosure.setBin('transparent', 30)
        self.myPath.setPos(0, 0, -0.0)
        selectable = self.myPath.attachNewNode(SelectableNode('vehicle sel'))
        vehicleModel.reparentTo(selectable)

        # ==== Initialize Physics ==== #
        thrusterForceNode = ForceNode('ThrusterForce')
        self.myPath.attachNewNode(thrusterForceNode)

        self.linearForce = LinearVectorForce(0, 0, 0)
        self.linearForce.setMassDependent(1)
        self.angularForce = AngularVectorForce(0, 0, 0)

        thrusterForceNode.addForce(self.linearForce)
        thrusterForceNode.addForce(self.angularForce)

        self.getPhysical(0).addLinearForce(self.linearForce)
        self.getPhysical(0).addAngularForce(self.angularForce)

        self.previousXY = (self.myPath.getX(), self.myPath.getY())

        self.tm = ThrusterManager()

        # Add self.updatePhysics to the task manager and run this task as
        # frequently as possible.
        self.updatePhysicsTask = taskMgr.add(self.updatePhysics,
                                             'UpdatePhysics')

        # ==== Initialize Cameras ==== #
        lens = PerspectiveLens()
        lens.setNearFar(0.05, 100.0)
        #Use either FocalLength or Fov. Fov ~40 is about what actual forward cameras are
        #lens.setFocalLength(0.8)
        lens.setFov(70, 70)
        camera = Camera("Forward_left", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Forward_Camera'))
        camera.setX(camera.getX() - 0.1)  # Forward cameras 20cm apart
        camera.setY(
            camera.getY() +
            0.05)  # Move in front of torpedo tubes to avoid abstruction
        camera.setHpr(0, 0, 0)

        camera = Camera("Forward_right", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Forward_Camera'))
        camera.setX(camera.getX() + 0.1)  # Forward cameras 20cm apart
        camera.setY(
            camera.getY() +
            0.05)  # Move in front of torpedo tubes to avoid abstruction
        camera.setHpr(0, 0, 0)

        lens = PerspectiveLens()
        lens.setNearFar(0.05, 100.0)
        lens.setFocalLength(0.8)
        camera = Camera("Downward", lens).getPath()
        camera.reparentTo(vehicleModel.find('**/Downward_Camera'))
        camera.setHpr(0, -90, 0)

        #Layout link (to access hydrophone information)
        self.layout = None

        #Hydrophone variables
        self.start_time = time()
        self.last_hydro_update = time()

    def setLayout(self, layout):
        #Add a link to the layout to allow for referencing other objects
        #This is necessary for the hydrophone addition
        self.layout = layout

    def getDepth(self):
        ''' Returns the depth of the vehicle, in meters. '''
        return -0.15 - self.myPath.getZ()

    def getHeading(self):
        ''' Returns the heading of the vehicle, in clockwise degrees. '''
        # Panda uses counter-clockwise degrees, with the range (-180, 180].
        heading = self.myPath.getH()
        if heading < 0:
            return -heading
        elif heading > 0:
            return 360 - heading
        else:
            return 0

    def updatePhysics(self, task):
        '''
        Use the motor PWM values calculated by the controller to apply forces
        to the simulated vehicle.

        This runs at every frame, so it needs to complete quickly.

        '''
        outputs = shm.kalman.get()
        self.tm.update(outputs)
        passive_wrench = vehicle.passive_forces(outputs, self.tm)
        passive_forces, passive_torques = passive_wrench[:3], \
                                          passive_wrench[3:]

        # Get motor thrusts
        thrusts = np.array(self.tm.get_thrusts())

        # Add passive forces and torques to that produced by thrusters,
        # converting them to sub space first.
        force = self.tm.total_thrust(thrusts) + \
                self.tm.orientation.conjugate() * passive_forces
        torque = self.tm.total_torque(thrusts) + \
                self.tm.orientation.conjugate() * passive_torques

        # Finally apply forces and torques to the model
        # we also need to account for panda3d's strange coordinate system
        # (x and y are flipped and z points up (instead of down))
        self.linearForce.setVector(force_subspace[1], \
                                   force_subspace[0], \
                                  -force_subspace[2])

        # We're supposed to use axis angle here, but I'm being sneaky
        # and using the torque vector directly, i.e. non normalized axis angle
        # with the hopes that this LRotationf constructor will figure it out
        self.angularForce.setQuat(\
            LRotationf(LVector3f(torque_subspace[1], \
                                 torque_subspace[0], \
                                -torque_subspace[2]), 1))

        # Update shared variables for controller
        outputs.heading = self.getHeading()
        outputs.pitch = self.myPath.getP()
        outputs.roll = self.myPath.getR()

        # This velocity is in world space
        # We need to put it into THRUST CONVENTION SPACE
        # which we assume kalman outputs in...
        velocity = self.getPhysicsObject().getVelocity()

        # Bring the velocity into THRUST CONVENTION SPACE
        # Don't forget to account for panda's coordinate system
        velocity = self.tm.heading_quat.conjugate() * \
                  np.array((velocity.getY(), velocity.getX(), -velocity.getZ()))

        outputs.velx = velocity[0]
        outputs.vely = velocity[1]
        outputs.depth_rate = velocity[2]

        outputs.depth = self.getDepth()
        outputs.north = self.myPath.getY()
        outputs.east = self.myPath.getX()

        dX = self.myPath.getX() - self.previousXY[0]
        dY = self.myPath.getY() - self.previousXY[1]

        # Forward and sway are in THRUST CONVENTION SPACE
        # don't forget to account for panda's coordinate system
        dF, dS, dD = self.tm.heading_quat.conjugate() * np.array((dY, dX, 0.0))

        outputs.forward += dF
        outputs.sway += dS

        # Output some quaternions, accounting for Panda's coordinate system
        outputs.q0, outputs.q2, outputs.q1, outputs.q3 = self.myPath.getQuat()
        outputs.q3 *= -1.0

        shm.kalman.set(outputs)

        svHeadingInt.set(self.getHeading())
        svDepth.set(self.getDepth())
        #XXX: Approximate altitude assuming that the pool is 12 feet deep
        svAltitude.set(3.6 - self.getDepth())
        svDvlDmgNorth.set(self.myPath.getY())
        svDvlDmgEast.set(self.myPath.getX())

        self.previousXY = (self.myPath.getX(), self.myPath.getY())  #update

        self.output_hydro_data()

        return Task.cont

    def output_hydro_data(self):
        #Update simulated hydrophone values
        pingers = []  #Get all pingers from the layout
        for element in self.layout.elements:
            if element.getTypeName() == "Pinger":
                pingers.append(element)

        HYDRO_TICK_PERIOD = 1

        if time() - self.last_hydro_update > HYDRO_TICK_PERIOD:
            dt = time() - self.last_hydro_update
            self.last_hydro_update = time()

            if shm.hydrophones_settings.dsp_mode.get() == 1:  #Search mode
                #Incr search count
                shm.hydrophones_results.search_count.set(
                    shm.hydrophones_results.search_count.get() + 1)

                #Generate proper "hydrophone bins" marks
                sb = 0
                for p in pingers:
                    f = p.pinger_frequency
                    dc = (f - (shm.hydrophones_settings.searchCenter.get() -
                               shm.hydrophones_settings.searchDelta.get())
                          ) / shm.hydrophones_settings.searchStep.get() + 0.5
                    sb |= 1 << int(dc)
                shm.hydrophones_results.search_bins.set(sb)

            else:  #Track Mode
                #Incr ping count
                shm.hydrophones_results.ping_count.set(
                    shm.hydrophones_results.ping_count.get() + 1)

                #Determine which pinger we are actively tracking (within 0.7khz of target)
                targetp = None
                for p in pingers:
                    if abs(shm.hydrophones_settings.trackFrequency.get() -
                           p.pinger_frequency) < 700:
                        targetp = p

                if targetp is not None:
                    shm.hydrophones_results.intensity.set(
                        int(shm.hydrophones_settings.trackMagThresh.get() +
                            1e4 * random()))
                    shm.hydrophones_results.ping_time.set(int(dt * 1000))

                    pp = targetp.path.getPos()

                    vv = vector.Vector(self.myPath.getY(), self.myPath.getX())
                    pv = vector.Vector(pp.getY(), pp.getX())

                    #heading
                    dv = pv - vv
                    ang = vector.GetAuvAngle(dv)
                    hdiff = helpers.heading_diff(self.getHeading(), ang)

                    shm.hydrophones_results.heading.set(hdiff)

                    #elevation
                    dh = self.myPath.getZ() - pp.getZ()
                    dist = vector.Length(dv)
                    elev = math.degrees(math.atan2(dist, dh))
                    elev = min(elev, 90)

                    shm.hydrophones_results.elevation.set(elev)

                    #phase calculations
                    dy = self.myPath.getY() - pp.getY()
                    dx = self.myPath.getX() - pp.getX()
                    yang = math.degrees(math.atan2(dist, dy))
                    xang = math.degrees(math.atan2(dist, dx))

                    shm.hydrophones_results.phaseX.set((90.0 - xang) / 90.0)
                    shm.hydrophones_results.phaseY.set((90.0 - yang) / 90.0)
                    shm.hydrophones_results.phaseZ.set((90.0 - elev) / 90.0)

                else:
                    shm.hydrophones_results.heading.set(0)
                    shm.hydrophones_results.elevation.set(0)
                    shm.hydrophones_results.intensity.set(0)
                    shm.hydrophones_results.ping_time.set(0)

            shm.hydrophones_results.uptime.set(int(time() - self.start_time))

    def __del__(self):
        ''' Remove update tasks from the panda task manager. '''
        taskMgr.remove(self.updatePhysicsTask)
        ActorNode.__del__(self)
示例#10
0
class CogdoFlyingCameraManager:
    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

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

    def _initCollisions(self):
        self._camCollRay = CollisionRay()
        camCollNode = CollisionNode('CameraToonRay')
        camCollNode.addSolid(self._camCollRay)
        camCollNode.setFromCollideMask(OTPGlobals.WallBitmask
                                       | OTPGlobals.CameraBitmask
                                       | ToontownGlobals.FloorEventBitmask
                                       | ToontownGlobals.CeilingBitmask)
        camCollNode.setIntoCollideMask(0)
        self._camCollNP = self._camera.attachNewNode(camCollNode)
        self._camCollNP.show()
        self._collOffset = Vec3(0, 0, 0.5)
        self._collHandler = CollisionHandlerQueue()
        self._collTrav = CollisionTraverser()
        self._collTrav.addCollider(self._camCollNP, self._collHandler)
        self._betweenCamAndToon = {}
        self._transNP = NodePath('trans')
        self._transNP.reparentTo(render)
        self._transNP.setTransparency(True)
        self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
        self._transNP.setBin('fixed', 10000)

    def _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

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

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

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

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

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

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

        self._betweenCamAndToon = nodesInBetween
示例#11
0
class Golem(FSM, DirectObject):
    def __init__(self):
        FSM.__init__(self, "FSM-Golem")
        random.seed()
        self.golem = loader.loadModel("Golem")
        self.golem = Actor(
            "Golem", {
                "Idle": "Golem-Idle",
                "Walk": "Golem-Walk",
                "Attack": "Golem-Attack",
                "Destroyed": "Golem-Destroyed"
            })
        self.golem.setBlend(frameBlend=True)
        golemViewSphere = CollisionSphere(0, 0, 0.5, 6)
        golemViewSphere.setTangible(False)
        golemViewColNP = self.golem.attachNewNode(
            CollisionNode('golemViewField'))
        golemViewColNP.node().addSolid(golemViewSphere)
        golemHitSphere = CollisionSphere(0, 0, 0.5, 1)
        golemHitColNP = self.golem.attachNewNode(
            CollisionNode('golemHitField'))
        golemHitColNP.node().addSolid(golemHitSphere)

        # a collision segment to check attacks
        self.attackCheckSegment = CollisionSegment(0, 0, 1, 0, -1.3, 1)
        self.golemAttackRay = self.golem.attachNewNode(
            CollisionNode("golemAttackCollision"))
        self.golemAttackRay.node().addSolid(self.attackCheckSegment)
        self.golemAttackRay.node().setIntoCollideMask(0)
        self.attackqueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.golemAttackRay, self.attackqueue)

        attackAnim = self.golem.actorInterval("Attack", playRate=2)
        self.AttackSeq = Parallel(attackAnim,
                                  Sequence(Wait(0.5), Func(self.ceckAttack)))

        self.lookatFloater = NodePath(PandaNode("golemTracker"))
        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.hide()
        self.lookatFloater.reparentTo(render)
        self.trackerObject = loader.loadModel("misc/Pointlight")
        self.trackerObject.setColor(0, 1, 0)
        self.trackerObject.setScale(0.25)
        self.trackerObject.reparentTo(self.lookatFloater)

    def start(self, startPos):
        self.golem.setPos(startPos.getPos())
        self.golem.setHpr(startPos.getHpr())
        self.golem.reparentTo(render)
        self.trackedEnemy = None
        self.health = 5
        self.accept(
            "playerCollision-in-golemViewField", lambda extraArgs: base.
            messenger.send("golemSeesPlayer", [self.golem]))

    def stop(self):
        self.trackedEnemy = None
        taskMgr.remove("GolemAI_task")
        self.golem.hide()
        self.ignoreAll()

    def cleanup(self):
        self.stop()
        self.lookatFloater.removeNode()
        self.golem.cleanup()
        self.golem.removeNode()

    def activate(self, trackedEnemy):
        self.trackedEnemy = trackedEnemy
        taskMgr.add(self.aiTask, "GolemAI_task")
        self.lookatFloater.show()

    def aiTask(self, task):
        dt = globalClock.getDt()
        if self.AttackSeq.isPlaying(): return task.cont

        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.lookAt(self.trackedEnemy)
        self.lookatFloater.setH(self.lookatFloater.getH() + 180)
        self.lookatFloater.setP(0)
        self.lookatFloater.setR(0)

        self.golem.lookAt(self.trackedEnemy)
        self.golem.setH(self.golem.getH() + 180)

        distanceVec = self.golem.getPos() - self.trackedEnemy.getPos()
        enemyDist = distanceVec.length()

        if enemyDist < 2.0:
            # close enough for combat
            action = random.choice(["Attack", "Idle"])
            if action == "Attack":
                self.request("Attack")
            else:
                if self.state != "Idle":
                    self.request("Idle")
        else:
            self.golem.setY(self.golem, -0.5 * dt)
            if self.state != "Walk":
                self.request("Walk")

        return task.cont

    def hit(self):
        hitInterval = Sequence(Func(self.golem.setColorScale, 1, 0, 0, 0.75),
                               Wait(0.15), Func(self.golem.clearColorScale),
                               Wait(0.15),
                               Func(self.golem.setColorScale, 1, 0, 0, 0.75),
                               Wait(0.15), Func(self.golem.clearColorScale),
                               Wait(0.15),
                               Func(self.golem.setColorScale, 1, 0, 0, 0.75),
                               Wait(0.15), Func(self.golem.clearColorScale),
                               Wait(0.15),
                               Func(self.golem.setColorScale, 1, 0, 0, 0.75),
                               Wait(0.15), Func(self.golem.clearColorScale),
                               Wait(0.15))
        self.health -= 1
        if self.health == 4:
            self.trackerObject.setColor(0, 1, 0)
            hitInterval.start()
        elif self.health == 3:
            self.trackerObject.setColor(0.25, 0.75, 0)
            hitInterval.start()
        elif self.health == 2:
            self.trackerObject.setColor(0.5, .5, 0)
            hitInterval.start()
        elif self.health == 1:
            self.trackerObject.setColor(0.75, 0.25, 0)
            hitInterval.start()
        elif self.health == 0:
            self.trackerObject.setColor(0, 0, 0)
            self.request("Destroyed")

    def ceckAttack(self):
        for i in range(self.attackqueue.getNumEntries()):
            entry = self.attackqueue.getEntry(i)
            into = entry.getIntoNode()
            if "playerCollision" in into.getName():
                if random.random() > .5:
                    base.messenger.send("HitPlayer")

    def enterIdle(self):
        self.golem.loop("Idle")

    def enterWalk(self):
        self.golem.setPlayRate(2, "Walk")
        self.golem.loop("Walk")

    def enterAttack(self):
        self.AttackSeq.start()

    def enterDestroyed(self):
        self.ignoreAll()
        taskMgr.remove("GolemAI_task")
        self.AttackSeq.finish()
        self.golem.play("Destroyed")
        self.lookatFloater.hide()
        base.messenger.send("GolemDestroyed")
示例#12
0
class Maleficium(ShowBase):
    def __init__(self):
        compressedTextures = ConfigVariableString('compressed-textures','1') # Compresses Textures on load (increases loadtime / framerate)
        ShowBase.__init__(self)
        
        ## Debug Values (True/False)
        self.fpsMeter = True
        
        debug.checkDebugSettings(self)

        self.KeyBindings()

        ## Load World
        world.load('prisonCrater')

        ## Add Player to World
        self.playerBox = NodePath('player')
        self.player = Actor("data/models/hm.bam",
                            {"run":"data/models/hm-run.bam",
                             "idle":"data/models/hm.bam"})
        self.player.reparentTo(self.playerBox)
        self.player.setScale(.01)
        self.playerBox.reparentTo(render)
        self.isMoving = False

        ## Create Camera
        base.disableMouse()
        self.cameratarget = self.render.attachNewNode('Camera Target')
        base.camera.setPos(self.playerBox.getX(),self.playerBox.getY()+20,self.playerBox.getZ()+5)
        self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6)
        self.radius = 10
        self.XYAngle = .028
        self.ZAngle = .01

        ## Set Up Ground Collisions
        ## Player Collision
        base.cTrav = CollisionTraverser()
        self.ColHandler = CollisionHandlerFloor()       
        self.colGroundRay = CollisionNode('colGroundRay')
        self.colGroundRay.addSolid(CollisionRay(0,0,2,0,0,-1))
        self.playerCol = self.playerBox.attachNewNode(self.colGroundRay)
        base.cTrav.addCollider(self.playerCol,self.ColHandler)
        self.ColHandler.addCollider(self.playerCol,self.playerBox)
                                       
        ## Add main Game Loop to taskmanager
        taskMgr.add(self.gameLoop,'mainLoop')


    ### Input Structure; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers)
    def KeyBindings(self):
        ## Setup Map
        self.startRightClick = True
        
        self.keyMap = {
            "forward":0,
            "backward":0,
            "turn_left":0,
            "turn_right":0,
            "strafe_left":0,
            "strafe_right":0,
            "cam_up":0,
            "cam_down":0,
            "cam_right":0,
            "cam_left":0,
            "zoom_in":0,
            "zoom_out":0,
            "right_click":0,
            "wheel_zoom_in":0,
            "wheel_zoom_out":0,
            }

        ## Accept Keys
        self.accept('escape',sys.exit)
        self.accept('w', self.setKey, ['forward',1])
        self.accept('w-up', self.setKey, ['forward',0])
        self.accept('s', self.setKey, ['backward',1])
        self.accept('s-up', self.setKey, ['backward',0])
        self.accept('a', self.setKey, ['turn_left',1])
        self.accept('a-up', self.setKey, ['turn_left',0])
        self.accept('d', self.setKey, ['turn_right',1])
        self.accept('d-up', self.setKey, ['turn_right',0])
        self.accept('q', self.setKey, ['strafe_left',1])
        self.accept('q-up', self.setKey, ['strafe_left',0])
        self.accept('e', self.setKey, ['strafe_right',1])
        self.accept('e-up', self.setKey, ['strafe_right',0])
        self.accept('arrow_up', self.setKey, ['cam_down',1])
        self.accept('arrow_up-up', self.setKey, ['cam_down',0])
        self.accept('arrow_down', self.setKey, ['cam_up',1])
        self.accept('arrow_down-up', self.setKey, ['cam_up',0])
        self.accept('arrow_right', self.setKey, ['cam_right',1])
        self.accept('arrow_right-up', self.setKey, ['cam_right',0])
        self.accept('arrow_left', self.setKey, ['cam_left',1])
        self.accept('arrow_left-up', self.setKey, ['cam_left',0])
        self.accept('[', self.setKey, ['zoom_in',1])
        self.accept('[-up', self.setKey, ['zoom_in',0])
        self.accept(']', self.setKey, ['zoom_out',1])
        self.accept(']-up', self.setKey, ['zoom_out',0])

        ## Accept Mouse
        self.accept('mouse3',self.setKey, ['right_click',1])
        self.accept('mouse3-up',self.setKey, ['right_click',0])
        self.accept('wheel_up',self.setKey, ['wheel_zoom_in',1])
        self.accept('wheel_down',self.setKey, ['wheel_zoom_out',1])

    ### Set Key Presses; Coded by Darren Kent (Modeled after Roaming-Ralph by Ryan Myers)
    def setKey(self,key,value):
        self.keyMap[key] = value        
            


    ### Main Game Loop; Coded by Darren Kent
    def gameLoop(self,task):

        ## Keyboard Camera Controls
        if (self.keyMap["cam_left"]!=0):
            self.XYAngle += .002
        if (self.keyMap["cam_right"]!=0):
            self.XYAngle -= .002
        if (self.keyMap["cam_up"] != 0):
            if self.ZAngle <= .045:
                self.ZAngle += .001
        if (self.keyMap["cam_down"] != 0):
            if self.ZAngle >= .002:
                self.ZAngle -= .001
        if (self.keyMap["zoom_in"] != 0):
            if self.radius >= 4:
                self.radius -= 1
                self.setRadius = self.radius
        if (self.keyMap["zoom_out"] != 0):
            if self.radius <= 40:
                self.radius += 1
                self.setRadius = self.radius
                
        ## Mouse Camera Controls
        if (self.keyMap["right_click"]!=0):
            if self.startRightClick == True:
                self.startRightClick = False
                self.tempMouseX = base.mouseWatcherNode.getMouseX()
                self.tempMouseY = base.mouseWatcherNode.getMouseY()
                self.tempXAngle = self.XYAngle
                self.tempZAngle = self.ZAngle
                self.tempPlayerH = self.playerBox.getH()
            elif self.startRightClick == False:
                Ztemp = self.tempZAngle + (base.mouseWatcherNode.getMouseY() - self.tempMouseY) / 20
                self.XYAngle = self.tempXAngle - (base.mouseWatcherNode.getMouseX() - self.tempMouseX) / 20
                if Ztemp >= .045:
                    Ztemp = .045
                if Ztemp <= 0.002:
                    Ztemp = 0.002
                self.ZAngle = Ztemp
        else:
            self.startRightClick = True
       
        if (self.keyMap["wheel_zoom_in"] != 0):
            if self.radius >= 7:
                self.radius -= 3
                self.setRadius = self.radius
        if (self.keyMap["wheel_zoom_out"] != 0):
            if self.radius <= 38:
                self.radius += 2
                self.setRadius = self.radius
        self.setKey("wheel_zoom_out",0)
        self.setKey("wheel_zoom_in", 0)

        ## Reposition Camera
        x = self.cameratarget.getX() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.cos(math.degrees(self.XYAngle))
        y = self.cameratarget.getY() + self.radius * math.sin(math.degrees(self.ZAngle)) * math.sin(math.degrees(self.XYAngle))
        z = self.cameratarget.getZ() + self.radius * math.cos(math.degrees(self.ZAngle))
        base.camera.setPos(x,y,z)
        base.camera.lookAt(self.cameratarget)
        self.cameratarget.setPos(self.playerBox.getX(),self.playerBox.getY(),self.playerBox.getZ()+6)


        ## Keyboard Movement Controls
        if (self.keyMap["turn_left"]!=0):
            self.playerBox.setH(self.playerBox.getH() + 200 * globalClock.getDt())
        if (self.keyMap["turn_right"]!=0):
            self.playerBox.setH(self.playerBox.getH() - 200 * globalClock.getDt())
        if (self.keyMap["strafe_left"]!=0):
            self.playerBox.setX(self.playerBox, +20 * globalClock.getDt())
        if (self.keyMap["strafe_right"]!=0):
            self.playerBox.setX(self.playerBox, -20 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.playerBox.setY(self.playerBox, -25 * globalClock.getDt())
        if (self.keyMap["backward"] != 0):
            self.playerBox.setY(self.playerBox, +15 * globalClock.getDt())

        if (self.keyMap["forward"]!=0):
            if self.isMoving == False:
                self.player.setPlayRate(2.5,'run')
                self.player.loop('run')
                self.isMoving = True
        else:
            if self.isMoving:
                self.player.setPlayRate(1,'idle')
                self.player.loop('idle')
                self.isMoving = False

        ## Check Collisions
            

        return task.cont
示例#13
0
class PartyCog(FSM):
    notify = directNotify.newCategory('PartyCog')
    HpTextGenerator = TextNode('HpTextGenerator')
    hpText = None
    height = 7

    def __init__(self,
                 parentNode,
                 id,
                 bounceSpeed=3,
                 bounceHeight=1,
                 rotateSpeed=1,
                 heightShift=1,
                 xMoveSpeed=0,
                 xMoveDistance=0,
                 bounceOffset=0):
        self.id = id
        FSM.__init__(self, 'PartyCogFSM-%d' % self.id)
        self.showFacingStatus = False
        self.xMoveSpeed = xMoveSpeed
        self.xMoveDistance = xMoveDistance
        self.heightShift = heightShift
        self.bounceSpeed = bounceSpeed
        self.bounceHeight = bounceHeight
        self.rotateSpeed = rotateSpeed
        self.parentNode = parentNode
        self.bounceOffset = bounceOffset
        self.hitInterval = None
        self.kaboomTrack = None
        self.resetRollIval = None
        self.netTimeSentToStartByHit = 0
        self.load()
        self.request('Down')
        return

    def load(self):
        self.root = NodePath('PartyCog-%d' % self.id)
        self.root.reparentTo(self.parentNode)
        path = 'phase_13/models/parties/cogPinata_'
        self.actor = Actor(
            path + 'actor', {
                'idle': path + 'idle_anim',
                'down': path + 'down_anim',
                'up': path + 'up_anim',
                'bodyHitBack': path + 'bodyHitBack_anim',
                'bodyHitFront': path + 'bodyHitFront_anim',
                'headHitBack': path + 'headHitBack_anim',
                'headHitFront': path + 'headHitFront_anim'
            })
        self.actor.reparentTo(self.root)
        self.temp_transform = Mat4()
        self.head_locator = self.actor.attachNewNode('temphead')
        self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75)
        self.bodyColl.setTangible(1)
        self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' %
                                          self.id)
        self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.bodyCollNode.addSolid(self.bodyColl)
        self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode)
        self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5)
        self.headColl.setTangible(1)
        self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' %
                                          self.id)
        self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.headCollNode.addSolid(self.headColl)
        self.headCollNodePath = self.root.attachNewNode(self.headCollNode)
        self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0)
        self.arm1Coll.setTangible(1)
        self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' %
                                          self.id)
        self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm1CollNode.addSolid(self.arm1Coll)
        self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode)
        self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0)
        self.arm2Coll.setTangible(1)
        self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' %
                                          self.id)
        self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm2CollNode.addSolid(self.arm2Coll)
        self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode)
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)
        self.pieHitSound = globalBattleSoundCache.getSound(
            'AA_wholepie_only.ogg')
        self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg')
        self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole')
        self.hole.setTransparency(True)
        self.hole.setP(-90.0)
        self.hole.setScale(3)
        self.hole.setBin('ground', 3)
        self.hole.reparentTo(self.parentNode)

    def unload(self):
        self.request('Off')
        self.clearHitInterval()
        if self.hole is not None:
            self.hole.removeNode()
            self.hole = None
        if self.actor is not None:
            self.actor.cleanup()
            self.actor.removeNode()
            self.actor = None
        if self.root is not None:
            self.root.removeNode()
            self.root = None
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.kaboomTrack = None
        if self.resetRollIval is not None and self.resetRollIval.isPlaying():
            self.resetRollIval.finish()
        self.resetRollIval = None
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.finish()
        self.hitInterval = None
        del self.upSound
        del self.pieHitSound
        return

    def enterStatic(self):
        pass

    def exitStatic(self):
        pass

    def enterActive(self, startTime):
        self.root.setR(0.0)
        updateTask = Task.Task(self.updateTask)
        updateTask.startTime = startTime
        taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id)

    def exitActive(self):
        taskMgr.remove('PartyCog.update-%d' % self.id)
        taskMgr.remove('PartyCog.bounceTask-%d' % self.id)
        self.clearHitInterval()
        self.resetRollIval = self.root.hprInterval(0.5,
                                                   Point3(
                                                       self.root.getH(), 0.0,
                                                       0.0),
                                                   blendType='easeInOut')
        self.resetRollIval.start()
        self.actor.stop()

    def enterDown(self):
        if self.oldState == 'Off':
            downAnimControl = self.actor.getAnimControl('down')
            self.actor.pose('down', downAnimControl.getNumFrames() - 1)
            return
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpFunc(self.setAlongSpline,
                     duration=1.0,
                     fromData=self.currentT,
                     toData=0.0),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'down', loop=0)),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def exitDown(self):
        self.root.setR(0.0)
        self.root.setH(0.0)
        self.targetDistance = 0.0
        self.targetFacing = 0.0
        self.currentT = 0.0
        self.setAlongSpline(0.0)
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'up', loop=0)),
            Func(self.actor.loop, 'idle'),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def filterDown(self, request, args):
        if request == 'Down':
            return None
        else:
            return self.defaultFilter(request, args)
        return None

    def setEndPoints(self, start, end, amplitude=1.7):
        self.sinAmplitude = amplitude
        self.sinPeriod = (end.getX() - start.getX()) / 2
        self.sinDisplacement = start.getY()
        self.startPoint = start
        self.endPoint = end
        self.currentT = 0.0
        self.targetDistance = 0.0
        self.currentFacing = 0.0
        self.targetFacing = 0.0
        self.setAlongSpline(self.currentT)
        self.hole.setPos(self.root.getPos())
        self.hole.setZ(0.02)

    def rockBackAndForth(self, task):
        t = task.startTime + task.time
        angle = math.sin(t) * 20.0
        self.root.setR(angle)
        return task.cont

    def updateDistance(self, distance):
        self.targetDistance = clamp(distance, -1.0, 1.0)

    def updateTask(self, task):
        self.rockBackAndForth(task)
        if self.targetDistance > self.currentT:
            self.currentT += min(0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        elif self.targetDistance < self.currentT:
            self.currentT += max(-0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        if self.currentT < 0.0:
            self.targetFacing = -90.0
        elif self.currentT > 0.0:
            self.targetFacing = 90.0
        else:
            self.targetFacing = 0.0
        if self.targetFacing > self.currentFacing:
            self.currentFacing += min(10,
                                      self.targetFacing - self.currentFacing)
        elif self.targetFacing < self.currentFacing:
            self.currentFacing += max(-10,
                                      self.targetFacing - self.currentFacing)
        self.root.setH(self.currentFacing)
        return task.cont

    def setAlongSpline(self, t):
        t = t + 1.0
        dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0
        x = self.startPoint.getX() + t * dist
        y = self.startPoint.getY() - math.sin(
            t * 2 * math.pi) * self.sinAmplitude
        self.root.setPos(x, y, 0)

    def startBounce(self):
        taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id)

    def bounce(self, task):
        self.root.setZ(
            math.sin((self.bounceOffset + task.time) * self.bounceSpeed) *
            self.bounceHeight + self.heightShift)
        return task.cont

    def setPos(self, position):
        self.root.setPos(position)

    def respondToPieHit(self, timestamp, position, hot=False, direction=1.0):
        if self.netTimeSentToStartByHit < timestamp:
            self.__showSplat(position, direction, hot)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
        else:
            self.notify.debug(
                'respondToPieHit self.netTimeSentToStartByHit = %s' %
                self.netTimeSentToStartByHit)

    def clearHitInterval(self):
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.clearToInitial()
        return

    def __showSplat(self, position, direction, hot=False):
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.clearHitInterval()
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splat.reparentTo(render)
        self.splat.setPos(self.root, position)
        self.splat.setAlphaScale(1.0)
        if not direction == 1.0:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0])
            if self.currentFacing > 0.0:
                facing = 'HitFront'
            else:
                facing = 'HitBack'
        else:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1])
            if self.currentFacing > 0.0:
                facing = 'HitBack'
            else:
                facing = 'HitFront'
        if hot:
            targetscale = 0.75
            part = 'head'
        else:
            targetscale = 0.5
            part = 'body'

        def setSplatAlpha(amount):
            self.splat.setAlphaScale(amount)

        self.hitInterval = Sequence(
            ActorInterval(self.actor, part + facing, loop=0),
            Func(self.actor.loop, 'idle'))
        self.hitInterval.start()
        self.kaboomTrack = Parallel(
            SoundInterval(self.pieHitSound,
                          volume=1.0,
                          node=self.actor,
                          cutOff=PartyGlobals.PARTY_COG_CUTOFF),
            Sequence(
                Func(self.splat.showThrough),
                Parallel(
                    Sequence(
                        LerpScaleInterval(self.splat,
                                          duration=0.175,
                                          scale=targetscale,
                                          startScale=Point3(0.1, 0.1, 0.1),
                                          blendType='easeOut'), Wait(0.175)),
                    Sequence(
                        Wait(0.1),
                        LerpFunc(setSplatAlpha,
                                 duration=1.0,
                                 fromData=1.0,
                                 toData=0.0,
                                 blendType='easeOut'))),
                Func(self.splat.cleanup), Func(self.splat.removeNode)))
        self.kaboomTrack.start()
        return

    def showHitScore(self, number, scale=1):
        if number <= 0:
            return
        if self.hpText:
            self.hideHitScore()
        self.HpTextGenerator.setFont(ToontownGlobals.getSignFont())
        if number < 0:
            self.HpTextGenerator.setText(str(number))
        else:
            self.HpTextGenerator.setText('+' + str(number))
        self.HpTextGenerator.clearShadow()
        self.HpTextGenerator.setAlign(TextNode.ACenter)
        r = 1
        g = 1
        b = 0
        a = 1
        self.HpTextGenerator.setTextColor(r, g, b, a)
        self.hpTextNode = self.HpTextGenerator.generate()
        self.hpText = render.attachNewNode(self.hpTextNode)
        self.hpText.setScale(scale)
        self.hpText.setBillboardPointEye()
        self.hpText.setBin('fixed', 100)
        self.hpText.setPos(self.root, 0, 0, self.height / 2)
        seq = Sequence(
            self.hpText.posInterval(
                0.25,
                Point3(self.root.getX(render), self.root.getY(render),
                       self.root.getZ(render) + self.height + 1.0),
                blendType='easeOut'), Wait(0.25),
            self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)),
            Func(self.hideHitScore))
        seq.start()

    def hideHitScore(self):
        if self.hpText:
            taskMgr.remove('PartyCogHpText' + str(self.id))
            self.hpText.removeNode()
            self.hpText = None
        return

    def getHeadLocation(self):
        self.actor.getJoints(jointName='head')[0].getNetTransform(
            self.temp_transform)
        self.head_locator.setMat(self.temp_transform)
        return self.head_locator.getZ(self.root)
示例#14
0
class CameraControl(DirectObject, HasKeybinds):
    """ adds controls to a given camera, usually base.camera"""
    def __init__(self, camera=None):
        #camera setup
        self.camera = camera
        if self.camera == None:
            self.camera = base.camera

        #XXX note, when moving cam target we need to make sure the camera doesnt move too...
        cameraBase = GeomNode('cameraBase')  #utility node for pan
        targetGeom = makeCameraTarget()
        cameraBase.addGeom(targetGeom)
        self.cameraBase = render.attachNewNode(cameraBase)
        #self.cameraBase.setTwoSided(True) #backface culling issue with my tristrip fail

        self.cameraTarget = NodePath(
            'cameraTarget')  #utility node for rot, zoom, reattach
        self.cameraTarget.reparentTo(self.cameraBase)
        #self.cameraTarget.reparentTo(render)
        self.camera.reparentTo(self.cameraTarget)

        self.track = self.camera.attachNewNode(
            'track')  #hack for pointing vector
        self.track.setPos(LVecBase3f(0, 50, 0))
        #nn = GeomNode('helper')
        #ng = makeCameraTarget()
        #nn.addGeom(targetGeom)
        #self.track.attachNewNode(nn)

        #keybind setup
        self.__ends__ = defaultdict(list)

        #self.accept("escape", sys.exit)  #no, exit_cleanup will handle this...

        for function_name, key in keybinds['view'].items():
            #self.accept(key,taskMgr.add,(getattr(self,function),function+'Task'))
            self.accept(
                key, self.makeTask,
                [function_name
                 ])  # TODO split out functions that don't require tasks
            keytest = key.split('-')[-1]
            #print(keytest)
            if keytest in {'mouse1', 'mouse2', 'mouse3'}:
                self.addEndTask(keytest, function_name)
                self.accept(keytest + '-up', self.endTask,
                            [keytest, function_name])

        #gains #TODO tweak me!
        self.XGAIN = .01
        self.YGAIN = .01

        #window setup
        self.getWindowSize()
        self.accept('window-event', self.getWindowSize)

        #self.accept('mouse1') #mouse 1 by itself does selection?
        #self.accpet('mouse3') #pan
        #self.accpet('mouse2')

        #--camera moves relatvie to arbitrary origin--
        #pan in plane
        #zoom #this needs to be on a log scale, linear is balls
        #rotate
        #--camera in place--
        #roll camera in place
        #yaw
        #pitch
        #look at selection/origin/center of mass of
        #--camera lense changes--
        #fov (for perspective)
        #perspective/orthographic
        #--worldcraft--
        #z mode wasd + mouse to orient for zooming

        #--selection functions we need to leave space for--
        #drop origin if we don't have something selected
        #click select
        #drag select, logial intersec
        #right click for menu

        self.__ch__ = None
        self.__cp__ = None
        self.__cr__ = None
        self.__cth__ = None
        self.__ctp__ = None

        pass

    def getWindowSize(self, wat=None):
        self.__winx__ = base.win.getXSize()
        self.__winy__ = base.win.getYSize()
        #print(self.__winx__,self.__winy__)

    def makeTask(self, function_name):
        """ ye old task spawner """
        if hasattr(self, function_name):
            if base.mouseWatcherNode.hasMouse():
                x, y = base.mouseWatcherNode.getMouse()
                setattr(self, '__%sTask_s__' % function_name,
                        (x, y))  #this should be faster
                taskMgr.add(getattr(self, function_name),
                            function_name + 'Task')
        else:
            raise KeyError(
                'Check your keybinds, there is no function by that name here!')

    def addEndTask(self, key, function_name):
        self.__ends__[key].append(function_name)

    def endTask(self, key, function):
        for func in self.__ends__[key]:
            taskMgr.remove(func + 'Task')
            setattr(self, '__%sTask_s__' % func, None)  #this should be faster
        self.__ch__ = None  #FIXME this seems hackish
        self.__cp__ = None
        self.__cr__ = None
        self.__cth__ = None
        self.__ctp__ = None

    def getMouseDdDt(self, name):  #XXX deprecated
        """ use gain to adjust pixels per degree
            this should probably be normalized to screen size actually?
            or no... but to what?
        """
        if base.mouseWatcherNode.hasMouse():
            x, z = base.mouseWatcherNode.getMouse()
            sx, sz = getattr(self, '__%s_start__' % name)
            print(x, sx)
            print(z, sz)
            if z != sz or x != sx:  #watch out for aliasing here...
                norm = (((x - sx) * self.XGAIN)**2 +
                        ((z - sz) * self.YGAIN)**2)**.5
                #norm =  ((x - sx) * self.X_GAIN), ((z - sz) * self.Y_GAIN)
                setattr(self, '__%s_start__' % name, (x, z))
                return norm
            else:  #mouse has not moved
                return 0

    def getMouseDdDf(self, name):
        if base.mouseWatcherNode.hasMouse():
            x, y = base.mouseWatcherNode.getMouse()
            sx, sy = getattr(self, '__%s_s__' % (name))
            dx = (x - sx) * self.XGAIN * self.__winx__
            dy = (y - sy) * self.YGAIN * self.__winy__
            return dx, dy

    def getMouseCross(
            self, name
    ):  #FIXME may need to do this incrementally as we started with...
        if base.mouseWatcherNode.hasMouse():
            x, y = base.mouseWatcherNode.getMouse()
            sx, sy = getattr(self, '__%s_s__' % (name))

            dx = (x - sx) * self.XGAIN * self.__winx__
            dy = (y - sy) * self.YGAIN * self.__winy__
            norm = (dx**2 + dy**2)**.5
            cross = x * sy - y * sx

            return cross * norm

    @event_callback
    def home(self, task):
        self.camera.lookAt(self.cameraBase)
        taskMgr.remove(task.getName())
        return task.cont

    @event_callback
    def pan(self, task):
        """ I don't like it, it's weird! """
        invert = -1
        magic_number = 15
        magic_number = 20
        if base.mouseWatcherNode.hasMouse():
            x, y = base.mouseWatcherNode.getMouse()
            sx, sy = getattr(self, '__%s_s__' % (task.getName()))
            dx = (x - sx) * self.XGAIN * self.__winx__ * magic_number * invert
            dy = (y - sy) * self.YGAIN * self.__winy__ * magic_number * invert
            #cx,cy,cz = self.camera.getPos()
            self.camera.setPos(self.camera, dx, 0, dy)
            setattr(
                self, '__%s_s__' % task.getName(), (x, y)
            )  #reset each frame to compensate for moving from own position
            #nx,ny,nz = self.camera.getPos()
            #dx2, dy2, dz2 = nx-cx, ny-cy, nz-cz
            #self.camera.setPos(cx,cz,cy)
            #self.cameraBase.setPos(self.cameraBase,dx2,dy2,dz2) #a hack to move cameraBase as if it were the camera
            #self.cameraTarget.setPos(self.cameraBase,dx2,dy2,dz2) #a hack to move cameraBase as if it were the camera
        return task.cont

    @event_callback
    def zoom_in_slow(self, task, speed=10):
        return self.zoom_in(
            task,
            speed)  #hehe this will work because it just passes the task :)

    @event_callback
    def zoom_out_slow(self, task, speed=10):
        return self.zoom_out(task, speed)

    @event_callback
    def zoom_in_fast(self, task, speed=1000):
        return self.zoom_in(
            task,
            speed)  #hehe this will work because it just passes the task :)

    @event_callback
    def zoom_out_fast(self, task, speed=1000):
        return self.zoom_out(task, speed)

    @event_callback
    def zoom_in(
        self,
        task,
        speed=100
    ):  #FIXME zoom_in and zoom_out still get custom xys even thought they don't use them!
        self.camera.setPos(self.camera, 0, speed, 0)
        taskMgr.remove(task.getName())
        return task.cont

    @event_callback
    def zoom_out(self, task, speed=100):
        self.camera.setPos(self.camera, 0, -speed, 0)
        taskMgr.remove(
            task.getName()
        )  #we do it this way instead of addOnce because we want to add all the tasks in one go
        return task.cont

    @event_callback
    def rotate(self, task
               ):  #FIXME disregard orientation acqurie proper mouse movements!
        dx, dy = self.getMouseDdDf(task.getName())
        if self.__cth__ == None:
            self.__cth__ = self.cameraTarget.getH()
        if self.__ctp__ == None:
            self.__ctp__ = self.cameraTarget.getP()
        self.cameraTarget.setH(self.__cth__ - dx * 10)
        self.cameraTarget.setP(self.__ctp__ + dy * 10)
        return task.cont

    #if we are in camera mode
    @event_callback
    def pitch(self, task):
        dx, dy = self.getMouseDdDf(task.getName())
        print('got pitch', dy)
        return task.cont

    @event_callback
    def look(self, task):  #AKA heading in hpr
        dx, dy = self.getMouseDdDf(task.getName())
        if self.__ch__ == None:
            self.__ch__ = self.camera.getH()
        if self.__cp__ == None:
            self.__cp__ = self.camera.getP()
        self.camera.setH(self.__ch__ - dx)
        self.camera.setP(
            self.__cp__ +
            dy)  #FIXME when we're clicking this might should be inverted?
        return task.cont

    @event_callback
    def roll(self, task):
        """ ALWAYS roll with respect to axis of rotation"""
        if self.__cr__ == None:
            self.__cr__ = self.cameraTarget.getR()
        #cross product idiot
        cross = self.getMouseCross(task.getName())

        self.cameraTarget.setR(self.__cr__ - cross * 10)
        return task.cont
示例#15
0
class Player(DirectObject):
    def __init__(self, _main):
        self.main = _main

        # Stats
        self.moveSpeed = 8
        self.inventory = []
        self.maxCarryWeight = 20.0 #kg ?
        self.currentInventoryWeight = 0.0

        # Inventory GUI
        self.inventoryGui = Inventory()
        self.inventoryGui.hide()
        self.inventoryActive = False
        self.craftInventory = CraftInventory()
        self.craftInventory.hide()

        # enable movements through the level
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
        self.player = NodePath("Player")#loader.loadModel("smiley")
        self.player.setPos(149.032, 329.324, 11.3384)
        self.player.setH(180)
        self.player.reparentTo(render)

        self.accept("w", self.setKey, ["forward",1])
        self.accept("w-up", self.setKey, ["forward",0])
        self.accept("a", self.setKey, ["left",1])
        self.accept("a-up", self.setKey, ["left",0])
        self.accept("s", self.setKey, ["backward",1])
        self.accept("s-up", self.setKey, ["backward",0])
        self.accept("d", self.setKey, ["right",1])
        self.accept("d-up", self.setKey, ["right",0])
        self.accept("mouse1", self.handleLeftMouse)
        self.accept("i", self.toggleInventory)
        self.accept("c", self.toggleCraftInventory)


        # screen sizes
        self.winXhalf = base.win.getXSize() / 2
        self.winYhalf = base.win.getYSize() / 2

        self.mouseSpeedX = 0.1
        self.mouseSpeedY = 0.1

        camera.setH(180)
        camera.reparentTo(self.player)
        camera.setZ(self.player, 2)
        base.camLens.setFov(75)
        base.camLens.setNear(0.8)

        # Mouse controls
        self.mouseNode = CollisionNode('mouseRay')
        self.mouseNodeNP = camera.attachNewNode(self.mouseNode)
        self.mouseNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.mouseRay = CollisionRay()
        self.mouseNode.addSolid(self.mouseRay)
        self.mouseRayHandler = CollisionHandlerQueue()

        # Collision Traverser
        self.traverser = CollisionTraverser("Player Traverser")
        base.cTrav = self.traverser
        self.traverser.addCollider(self.mouseNodeNP, self.mouseRayHandler)

    def run(self):
        taskMgr.add(self.move, "moveTask", priority=-4)

    def pause(self):
        taskMgr.remove("moveTask")

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

    def move(self, task):
        if not base.mouseWatcherNode.hasMouse(): return task.cont

        pointer = base.win.getPointer(0)
        mouseX = pointer.getX()
        mouseY = pointer.getY()

        if base.win.movePointer(0, self.winXhalf, self.winYhalf):
            # calculate the looking up/down of the camera.
            # NOTE: for first person shooter, the camera here can be replaced
            # with a controlable joint of the player model
            p = camera.getP() - (mouseY - self.winYhalf) * self.mouseSpeedY
            if p <-80:
                p = -80
            elif p > 90:
                p = 90
            camera.setP(p)

            # rotate the player's heading according to the mouse x-axis movement
            h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX
            if h <-360:
                h = 360
            elif h > 360:
                h = -360
            self.player.setH(h)

        # basic movement of the player
        if self.keyMap["left"] != 0:
            self.player.setX(self.player, self.moveSpeed * globalClock.getDt())
        if self.keyMap["right"] != 0:
            self.player.setX(self.player, -self.moveSpeed * globalClock.getDt())
        if self.keyMap["forward"] != 0:
            self.player.setY(self.player, -self.moveSpeed * globalClock.getDt())
        if self.keyMap["backward"] != 0:
            self.player.setY(self.player, self.moveSpeed * globalClock.getDt())


        # keep the player on the ground
        elevation = self.main.t.terrain.getElevation(self.player.getX(), self.player.getY())
        self.player.setZ(elevation*self.main.t.zScale)

        return task.cont

    def toggleInventory(self):
        if self.inventoryActive:
            self.inventoryGui.hide()
            self.inventoryActive = False
            self.run()
        else:
            self.inventoryGui.show()
            self.inventoryActive = True
            self.pause()

    def toggleCraftInventory(self):
        if self.inventoryActive:
            self.craftInventory.hide()
            self.inventoryActive = False
            self.run()
        else:
            self.craftInventory.updateList(self.inventory)
            self.craftInventory.show()
            self.inventoryActive = True
            self.pause()

    def handleLeftMouse(self):
        # Do the mining
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.mouseRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            self.traverser.traverse(render)
            # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
            if self.mouseRayHandler.getNumEntries() > 0:
            # This is so we get the closest object.
                self.mouseRayHandler.sortEntries()
                pickedObj = self.mouseRayHandler.getEntry(0).getIntoNodePath()

                # Range check
                if (self.player.getPos() - pickedObj.getPos(render)).length() <= 3.0:
                    self.mine(pickedObj)
                else:
                    print "You are to far, move closer!"


    def mine(self, _nodeNP):
        self.nodeNP = _nodeNP

        # get the object class
        for node in self.main.nodeGen.currentNodes:
            if self.main.nodeGen.currentNodes[node] in self.inventory:
                print "new Loot:", self.main.nodeGen.currentNodes[node].giveLoot()
                self.inventory.append(self.main.nodeGen.currentNodes[node])
                if self.main.nodeGen.currentNodes[node].lootLeft == 0:
                    self.main.nodeGen.currentNodes[node].removeModel()
                    break
                break


            # if mining node
            else:

                if self.main.nodeGen.currentNodes[node].model and self.main.nodeGen.currentNodes[node].model.getPos() == self.nodeNP.getPos(render):
                    #self.main.nodeGen.currentNodes[node].removeModel()
                    self.inventory.append(self.main.nodeGen.currentNodes[node])
                    self.currentInventoryWeight += self.main.nodeGen.currentNodes[node].weight
                    self.inventoryGui.updateList(self.inventory)
                    print "You received:", self.main.nodeGen.currentNodes[node].giveLoot(), self.main.nodeGen.currentNodes[node].giveType(), "Ores"
                    print "Inventory:", self.inventory
                    print "Current Weight:", self.currentInventoryWeight
                    break

        print self.player.getPos()
示例#16
0
class Player(object):
    """
        Player is the main actor in the fps game
    """
    FORWARD = Vec3(0,2,0)
    BACK = Vec3(0,-1,0)
    LEFT = Vec3(-1,0,0)
    RIGHT = Vec3(1,0,0)
    FLYUP = Vec3(0,0,1)
    FLYDN = Vec3(0,0,-1)
    STOP = Vec3(0)
    PORTAL_CYCLE = {
        'blue' : 'orange',
        'orange' : 'blue',
        }

    def __init__(self, base, fps, osd):
        self.base = base
        self.fps = fps
        self.osd = osd
        self.speed = RUN_SPEED
        self.walk = self.STOP
        self.readyToJump = False
        self.intoPortal = None
        self.mass = Mass()
        self.origin = self.fps.level.settings.origin
        self.bporigin = (999,999,999)
        self.oporigin = (999,999,999)
        self.current_target = None
        self.canPortal = []
        self.canSetTarget = True
        self.selectedCubes = []
        self.editorTextureStage = TextureStage('editor')
        self.editorSelectedTexture = loader.loadTexture('models/tex/selected.png')
        self.selectingForMulti = False
        # Init functions
        self.loadModel()
        self.makePortals()
        self.setUpCamera()
        if self.fps.editor_mode:
            self.createMouseCollisions()
            self.speed = self.speed * 5
            self.attachEditorControls()
            self.attachEditorTasks()
        else:
            self.createCollisions()
            self.attachStandardControls()
            self.attachStandardTasks()

    def loadModel(self):
        """ make the nodepath for player """
        self.node = NodePath('player')
        self.node.reparentTo(render)
        self.node.setPos(*self.origin)
        self.node.setScale(0.05)
        self.mass.pos = VBase3(self.node.getX(), self.node.getY(), self.node.getZ())

    def makePortals(self):
        # The BLUE CUBE
        bpor = loader.loadModel("cube_nocol")
        bpor.setTag('noportals', '1')
        bpor.reparentTo(render)
        bpor.setPos(*self.bporigin)
        bpor.setScale(0.3,0.02,0.5)
        # The BLUE CUBE's camera
        bbuffer = self.base.win.makeTextureBuffer("B Buffer", 512, 512)
        bbuffer.setSort(-100)
        bcamera = self.base.makeCamera(bbuffer)
        bcamera.node().getLens().setAspectRatio(0.3/0.5)
        bcamera.node().getLens().setFov(15)
        bcamera.reparentTo(bpor)
        bcamera.node().setScene(render)

        # The ORANGE CUBE
        opor = loader.loadModel("cube_nocol")
        opor.setTag('noportals', '1')
        opor.reparentTo(render)
        opor.setPos(*self.oporigin)
        opor.setScale(0.3,0.02,0.5)
        # The ORANGE CUBE's camera
        obuffer = self.base.win.makeTextureBuffer("O Buffer", 512, 512)
        obuffer.setSort(-100)
        ocamera = self.base.makeCamera(obuffer)
        ocamera.node().getLens().setAspectRatio(0.3/0.5)
        ocamera.node().getLens().setFov(15)
        ocamera.reparentTo(opor)
        ocamera.node().setScene(render)

        # Assign the textures
        bpor.setTexture(obuffer.getTexture())
        opor.setTexture(bbuffer.getTexture())
        # Store the portals and theirs cameras
        self.bluePortal = bpor
        self.bluePortal.setHpr(0,90,0)
        self.orangePortal = opor
        self.orangePortal.setHpr(0,-90,0)
        self.bcamera = bcamera
        self.ocamera = ocamera

    def setUpCamera(self):
        """ puts camera at the players node """
        pl =  self.base.cam.node().getLens()
        pl.setFov(70)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.node)
        self.base.camLens.setFov(100)
        if self.fps.editor_mode:
            self.node.lookAt(self.fps.level.cubes_hash.keys()[0])

    def createCollisions(self):
        self.createPlayerCollisions()
        self.createMouseCollisions()
        self.createPortalCollisions()

    def createPlayerCollisions(self):
        """ create a collision solid and ray for the player """
        cn = CollisionNode('player')
        cn.setFromCollideMask(COLLISIONMASKS['geometry'])
        cn.setIntoCollideMask(COLLISIONMASKS['portals'] | COLLISIONMASKS['exit'] | COLLISIONMASKS['lava'])
        cn.addSolid(CollisionSphere(0,0,0,3))
        solid = self.node.attachNewNode(cn)
        # TODO : find a way to remove that, it's the cause of the little
        # "push me left" effect we see sometime when exiting a portal
        self.base.cTrav.addCollider(solid,self.base.pusher)
        self.base.pusher.addCollider(solid,self.node, self.base.drive.node())
        # init players floor collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,-.2)
        ray.setDirection(0,0,-1)
        cn = CollisionNode('playerRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.nodeGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.nodeGroundHandler)
        # init players ceil collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,.2)
        ray.setDirection(0,0,1)
        cn = CollisionNode('playerUpRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.ceilGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.ceilGroundHandler)

    def createMouseCollisions(self):
        # Fire the portals
        firingNode = CollisionNode('mouseRay')
        firingNP = self.base.camera.attachNewNode(firingNode)
        firingNode.setFromCollideMask(COLLISIONMASKS['geometry'])
        firingNode.setIntoCollideMask(BitMask32.allOff())
        firingRay = CollisionRay()
        firingRay.setOrigin(0,0,0)
        firingRay.setDirection(0,1,0)
        firingNode.addSolid(firingRay)
        self.firingHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(firingNP, self.firingHandler)

    def createPortalCollisions(self):
        # Enter the portals
        cn = CollisionNode('bluePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.bluePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)
        cn = CollisionNode('orangePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.orangePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)

    def attachCommonControls(self):
        self.base.accept( "z" if AZERTY else "w" , self.addWalk,[self.FORWARD])
        self.base.accept( "z-up" if AZERTY else "w-up" , self.addWalk,[-self.FORWARD] )
        self.base.accept( "s" , self.addWalk,[self.BACK] )
        self.base.accept( "s-up" , self.addWalk,[-self.BACK] )
        self.base.accept( "q" if AZERTY else "a" , self.addWalk,[self.LEFT])
        self.base.accept( "q-up" if AZERTY else "a-up" , self.addWalk,[-self.LEFT] )
        self.base.accept( "d" , self.addWalk,[self.RIGHT] )
        self.base.accept( "d-up" , self.addWalk,[-self.RIGHT] )
        self.base.accept( "r-up" , self.resetPosition )
        self.base.accept( "p-up" , self.showPosition )
        self.base.accept( "b-up" , self.deBug )

    def attachStandardControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__,["readyToJump",True])
        self.base.accept( "space-up" , self.__setattr__,["readyToJump",False])
        self.base.accept( "c-up" , self.__setattr__,["intoPortal",None] )
        self.base.accept( "e-up" , self.erasePortals )
        self.base.accept( "mouse1" , self.fireBlue )
        self.base.accept( "mouse3" , self.fireOrange )
        # Events
        self.base.accept( "bluePortal-into-player" , self.enterPortal, ["blue"] )
        self.base.accept( "orangePortal-into-player" , self.enterPortal, ["orange"] )
        self.base.accept( "bluePortal-outof-player" , self.exitPortal, ["blue"] )
        self.base.accept( "orangePortal-outof-player" , self.exitPortal, ["orange"] )
        self.base.accept( "levelExit-into-player" , self.levelExit)
        self.base.accept( "lava-into-player" , self.fallIntoLava)

    def attachStandardTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveUpdate, 'move-task')
        taskMgr.add(self.jumpUpdate, 'jump-task')

    def attachEditorControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__, ['selectingForMulti', 1])
        self.base.accept( "space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "shift-space" , self.__setattr__, ['selectingForMulti', 2])
        self.base.accept( "shift-space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "c-up" , self.clearMultiSelectedCubes)
        self.base.accept( "mouse1" , self.selectCubeForCopy, [1])
        self.base.accept( "wheel_up" , self.selectCubeForChange, [1] )
        self.base.accept( "wheel_down" , self.selectCubeForChange, [-1] )
        self.base.accept( "mouse3" , self.selectCubeForDelete )
        self.base.accept("f11", self.saveLevel)
        self.base.accept("x", self.selectCubeForRectangle)
        self.base.accept("shift-x", self.selectCubeForRectangle, [True])
        self.base.accept("l", self.addLightHere)
        self.base.accept("u", self.fps.level.undo, [1])
        for i in range(1,10):
            self.base.accept( "%i-up" % (i,), self.selectCubeForCopy, [i])
        for key, vec in [("a" if AZERTY else "q", self.FLYUP),("w" if AZERTY else "z", self.FLYDN)]:
            self.base.accept(key, self.addWalk, [vec])
            self.base.accept(key + "-up", self.addWalk, [-vec])

    def attachEditorTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveInEditor, 'move-task')

    def deBug(self):
        import pdb
        pdb.set_trace()
    def showPosition(self):
        print self.node.getPos()
        print self.mass
    def fallIntoLava(self, *args, **kwargs):
        # TODO : sound and message + little delay
        self.erasePortals()
        self.resetPosition()
    def resetPosition(self, *args, **kwargs):
        self.node.setHpr(VBase3(0,0,0))
        self.mass.pos = VBase3(*self.origin)
        self.mass.vel = VBase3(0,0,0)
        self.mass.force = VBase3(0,0,0)
        self.node.setPos(self.mass.pos)
    def erasePortals(self):
        self.bluePortal.setPos(*self.bporigin)
        self.orangePortal.setPos(*self.oporigin)
        self.bluePortal.detachNode()
        self.orangePortal.detachNode()
        self.intoPortal = None
        self.canPortal = []
    #@oldpostracker
    def mouseUpdate(self,task):
        """ this task updates the mouse """
        md = self.base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if self.base.win.movePointer(0, self.base.win.getXSize()/2, self.base.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - self.base.win.getXSize()/2)*0.1)
            if self.fps.editor_mode:
                self.node.setP(self.node.getP() - (y - self.base.win.getYSize()/2)*0.1)
            else:
                self.base.camera.setP(self.base.camera.getP() - (y - self.base.win.getYSize()/2)*0.1)
            self.canSetTarget = True
            self.bcamera.lookAt(self.bluePortal, self.node.getPos(self.orangePortal))
            self.ocamera.lookAt(self.orangePortal, self.node.getPos(self.bluePortal))
            #self.canPortal = ['blue','orange']
            if self.fps.editor_mode:
                cube, point, normal = self.selectCube()
                self.osd.updateTargetPosition(cube)
        if self.selectingForMulti:
            self.selectCubeForMulti()
        return task.cont

    def addWalk(self, vec):
        self.walk += vec

    def moveUpdate(self,task):
        """ this task makes the player move """
        # move where the keys set it
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        return task.cont

    #@oldpostracker
    def jumpUpdate(self,task):
        """ this task simulates gravity and makes the player jump """
        # get the highest Z from the down casting ray
        highestZ = -100
        lowestZ = 100
        for i in range(self.nodeGroundHandler.getNumEntries()):
            entry = self.nodeGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z > highestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                highestZ = z
        for i in range(self.ceilGroundHandler.getNumEntries()):
            entry = self.ceilGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z < lowestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                lowestZ = z
        # gravity effects and jumps
        self.mass.simulate(globalClock.getDt())
        self.node.setZ(self.mass.pos.getZ())
        if highestZ > self.node.getZ()-PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
        if lowestZ < self.node.getZ()+PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
        if self.readyToJump and self.node.getZ() < highestZ + PLAYER_TO_FLOOR_TOLERANCE_FOR_REJUMP:
            self.mass.jump(JUMP_FORCE)
        return task.cont

    def firePortal(self, name, node):
        def hasTagValue(node, tag, value):
            if node.getTag(tag) == value:
                return True
            for pnum in range(node.getNumParents()):
                return hasTagValue(node.getParent(pnum), tag, value)
            return False
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            if hasTagValue(closest.getIntoNode(), 'noportals', '1'):
                return
            point = closest.getSurfacePoint(render)
            normal = closest.getSurfaceNormal(render)
            node.setPos(point)
            node.lookAt(point + normal)
            node.reparentTo(render)
            dest = self.PORTAL_CYCLE[name]
            if dest not in self.canPortal:
                self.canPortal.append(dest)

    def fireBlue(self, *arg, **kwargs):
        self.firePortal("blue", self.bluePortal)

    def fireOrange(self, *arg, **kwargs):
        self.firePortal("orange", self.orangePortal)

    #@oldpostracker
    def enterPortal(self, color, collision):
        if self.intoPortal is None and color in self.canPortal:
            self.intoPortal = color
            portal = {"orange": self.bluePortal, "blue": self.orangePortal}.get(color)
            otherportal = {"orange": self.orangePortal, "blue": self.bluePortal}.get(color)
            # Handle horizontal portals :
            if portal.getH() == 0:
                self.node.setP(0)
                self.node.setR(0)
            elif otherportal.getH() == 0:
                self.node.setH(portal.getH())
                self.node.setP(0)
                self.node.setR(0)
            else:
                # New HPR is relative to 'new' portal but it the 'same' value
                # as the old HPR seen from the 'other' portal
                oldh_fromportal = self.node.getH(otherportal)
                self.node.setHpr(Vec3(0,0,0))
                self.node.setH(portal, 180-oldh_fromportal)
                newh_fromportal = self.node.getH(portal)
            self.node.setPos(portal, self.walk * 10.)
            self.mass.pos = self.node.getPos()
            # Make half a turn (only if we straffing without walking)
            if self.walk.getY() == 0 and self.walk.getX() != 0:
                self.node.setH(self.node, 180)
                self.node.setPos(self.node, self.walk * 10)
    #@oldpostracker
    def exitPortal(self, color, collision):
        # When you entered the blue portal, you have to exit the orange one
        if self.intoPortal != color:
            self.intoPortal = None

    def levelExit(self, event):
        if self.fps.level.settings.next_level:
            self.fps.level.loadlevel(self.fps.level.settings.next_level)
            self.origin = self.fps.level.settings.origin
            self.resetPosition()
            self.erasePortals()
            self.walk = self.STOP
        else:
            print "You won !"
            sys.exit(0)

    # EDITOR MODE
    def selectCube(self):
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            return closest.getIntoNodePath().getParent().getParent(), closest.getSurfacePoint(render), closest.getSurfaceNormal(render) # render/cube.egg/-PandaNode/-GeomNode
        else:
            return None, None, None

    def clearMultiSelectedCubes(self):
        for c in self.selectedCubes:
            c.clearTexture(self.editorTextureStage)
        self.selectedCubes = []

    def selectCubeForMulti(self):
        cube, point, normal = self.selectCube()
        if cube:
            if self.selectingForMulti == 1:
                cube.setTexture(self.editorTextureStage, self.editorSelectedTexture)
                if cube not in self.selectedCubes:
                    self.selectedCubes.append(cube)
            elif cube in self.selectedCubes:
                cube.clearTexture(self.editorTextureStage)
                self.selectedCubes.remove(cube)

    def selectCubeForCopy(self, qty = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.copyCube(c, normal, qty)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.copyCube(cube, normal, qty)

    def selectCubeForDelete(self):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.deleteCube(c)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.deleteCube(cube)

    def selectCubeForChange(self, step = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.changeCube(c, step)
        else:
            self.fps.level.changeCube(cube, step)

    def selectCubeForRectangle(self, makeRoom = False):
        cube, point, normal = self.selectCube()
        if makeRoom:
            self.fps.level.createRoom(cube, self.node) # creates a room from the selected cube to the player(camera) position
        else:
            self.fps.level.createRectangle(cube, self.node) # creates a rectangle from the selected cube to the player(camera) position

    def saveLevel(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        levelname = self.fps.levelname
        self.fps.level.savelevel(levelname, camerapos)

    def addLightHere(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        self.fps.level.addLightHere(camerapos)

    def moveInEditor(self,task):
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        self.osd.updatePosition(self.node)
        return task.cont
示例#17
0
class Moving(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

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

        # 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("EggMod/SandPlan.egg")
        self.environ.reparentTo(render)
        self.environ.setScale(20)

        StartPos = LVector3(0, 0, 0)
        self.movint = loader.loadModel("EggMod/HailPar.egg")
        self.movint.reparentTo(render)
        self.movint.setScale(2)
        self.movint.setPos(StartPos + (0, 0, 0.5))

        # 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("f", self.setKey, ["up", 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("f-up", self.setKey, ["up", False])

        self.mopan = Pmango()

        self.alin = LinearEulerIntegrator()
        self.mopan.attachLinearIntegrator(self.alin)
        self.arin = AngularEulerIntegrator()
        self.mopan.attachAngularIntegrator(self.arin)

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

        self.cTrav = CollisionTraverser()
        #base.cTrav.setRespectPrevTransform(True)

        self.actMove = NodePath("ActMove")
        self.actMove.reparentTo(render)
        self.actMove.setPos(0, 0, 190)
        self.an = ActorNode("BMova")
        self.anp = self.actMove.attachNewNode(self.an)

        self.mopan.attachPhysicalNode(self.an)
        self.movint.reparentTo(self.actMove)

        self.anp.node().getPhysicsObject().setMass(1)
        #self.an.getPhysicsObject().setTerminalVelocity(1.0)

        self.dvi = 0
        self.grava = ForceNode('GravAll')
        self.grar = render.attachNewNode(self.grava)
        self.grdi = LinearVectorForce(0.0, -0.0, -8.0)
        #self.grdi.setMassDependent(1)
        self.grava.addForce(
            self.grdi)  #Forces have to be added to force nodes and to
        # a physics manager

        self.mopan.addLinearForce(self.grdi)

        self.BMoveBalance = CollisionSphere(0, 0, -7.0, 1)
        self.BMoveBalanceNode = CollisionNode('BMove')
        self.BMoveBalanceNode.addSolid(self.BMoveBalance)

        #self.BMABalance = CollisionSphere(0, 0, -7.0, 1)
        #self.BMABalanceNode = CollisionNode('BMAove')
        #self.BMABalanceNode.addSolid(self.BMABalance)

        self.BMoveBalancePath = self.actMove.attachNewNode(
            self.BMoveBalanceNode)

        #self.BMAoveBalancePath=self.anp.attachNewNode(self.BMABalanceNode)
        #self.BMAoveBalancePath.setPos(0,0,-8)

        self.BMAoveBalancePath = self.BMoveBalancePath.copyTo(self.anp)
        self.BMAoveBalancePath.setPos(0, 0, -5)

        self.BMoveBalancePath.setPos(
            self.actMove.getRelativePoint(self.BMoveBalancePath,
                                          self.BMoveBalancePath.getPos()))
        self.DinGro = PhysicsCollisionHandler()
        self.DinGro.setStaticFrictionCoef(1)
        self.DinGro.setDynamicFrictionCoef(2)
        self.DinGro.setAlmostStationarySpeed(0.1)

        self.DinGro.addCollider(
            self.BMAoveBalancePath,
            self.anp)  #Colliders use nodepaths for collisions instead of nodes
        self.cTrav.addCollider(self.BMAoveBalancePath, self.DinGro)

        self.DinGro.addCollider(self.BMoveBalancePath, self.anp)
        self.cTrav.addCollider(self.BMoveBalancePath, self.DinGro)

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

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

        # Create some lighting
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection((-5, -5, -5))
        render.setLight(render.attachNewNode(directionalLight))

        self.calrun = 0
        self.upcal = None
        self.anp.setPos(0, 0, 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()
        self.dvi += dt
        self.anr = self.an.getPhysicsObject()
        self.cTrav.setRespectPrevTransform(True)

        print(self.anr.getVelocity())

        #self.anr.setVelocity(0,0,0)
        self.mopan.doPhysics(dt)
        if dt <= .2:

            self.actMove.setPos(self.actMove, self.anp.getPos())
            self.anp.setPos(0, 0, 0.0)

            #self.anr.setVelocity(0,0,-1)

        #self.anp.setPos(0,0,0.0)
        if self.keyMap["left"]:
            self.actMove.setH(self.actMove.getH() + 200 * dt)
        if self.keyMap["right"]:
            self.actMove.setH(self.actMove.getH() - 200 * dt)
        if self.keyMap["forward"]:
            self.actMove.setFluidY(self.actMove, -25 * dt)
        if self.keyMap["back"]:
            self.actMove.setFluidY(self.actMove, 25 * dt)
        if self.keyMap["up"]:
            self.actMove.setFluidZ(self.actMove, 25 * dt)

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

        return task.cont
示例#18
0
class PlayWorld(object):
    def __init__(self, config=None):
        if config is None:
            self.config = {}
            execfile('play_config.py', self.config)
        else:
            self.config = config
        self.reward = None
        print self.config['pydaq']
        if pydaq and self.config.setdefault('pydaq', True) is not None:
            self.reward = pydaq.GiveReward()
        self.reward_count = 0
        # adjustment to speed so corresponds to gobananas task
        # 7 seconds to cross original environment
        # speed needs to be adjusted to both speed in original
        # environment and c_range of colors
        # self.speed = 0.05 * (self.c_range[1] - self.c_range[0])
        # speed is own variable, so can be changed during training.
        self.speed = self.config['speed']

        # need a multiplier to the joystick output to tolerable speed
        self.vel_base = 4
        self.max_vel = [500, 500, 0]

        self.base = ShowBase()
        self.base.disableMouse()
        # self.base.setFrameRateMeter(True)
        # assume we are showing windows unless proven otherwise
        if self.config.get('win', True):
            # only need inputs if we have a window
            self.inputs = Inputs(self.base)
            props = WindowProperties()
            props.setCursorHidden(True)
            props.setForeground(True)
            print self.config.get('resolution')
            if self.config.get('resolution'):
                # main window
                props.set_size(int(self.config['resolution'][0]), int(self.config['resolution'][1]))
                # props.set_origin(1920, 0)
                props.set_origin(500, 0)
            else:
                props.set_size(600, 600)
                props.set_origin(400, 50)
            self.base.win.requestProperties(props)
        # print 'background color', self.base.getBackgroundColor()
        # field = self.base.loader.loadModel("../goBananas/models/play_space/field.bam")
        field = self.base.loader.loadModel("../goBananas/models/play_space/round_courtyard.bam")
        field.setPos(0, 0, 0)
        field.reparent_to(self.base.render)
        field_node_path = field.find('**/+CollisionNode')
        field_node_path.node().setIntoCollideMask(0)
        sky = self.base.loader.loadModel("../goBananas/models/sky/sky_kahana2.bam")
        sky.setPos(0, 0, 0)
        sky.setScale(1.6)
        sky.reparentTo(self.base.render)
        windmill = self.base.loader.loadModel("../goBananas/models/windmill/windmill.bam")
        windmill.setPos(-10, 30, -1)
        windmill.setScale(0.03)
        windmill.reparentTo(self.base.render)
        # mountain = self.base.loader.loadModel("../goBananas/models/mountain/mountain.bam")
        # mountain.setScale(0.0005)
        # mountain.setPos(10, 30, -0.5)

        # create the avatar
        self.avatar = NodePath(ActorNode("avatar"))
        self.avatar.reparentTo(self.base.render)
        self.avatar.setPos(0, 0, 1)
        self.avatar.setScale(0.5)
        pl = self.base.cam.node().getLens()
        pl.setFov(60)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.avatar)

        # initialize task variables
        self.frame_task = None
        self.started_game = None
        self.showed_match = None
        self.gave_reward = None

        # initialize and start the game
        self.set_next_trial()

        # print 'end init'

    def start_loop(self):
        # need to get new match
        self.start_play()

    def start_play(self):
        print 'start play'
        # log this
        # print self.base.render.ls()
        self.frame_task = self.base.taskMgr.add(self.game_loop, "game_loop")
        self.frame_task.last = 0  # initiate task time of the last frame

    def game_loop(self, task):
        dt = task.time - task.last
        task.last = task.time
        velocity = self.inputs.poll_inputs(LVector3(0))
        self.move_avatar(dt, velocity)
        return task.cont

    def reward_loop(self, task):
        self.reward_count += 1
        if self.reward_count <= self.config['num_beeps']:
            if self.reward:
                # log this
                print 'give a bloody reward already'
                self.reward.pumpOut()
            print 'give reward'
            return task.again
        else:
            self.end_loop()
            return task.done

    def move_avatar(self, dt, velocity):
        # print 'velocity', self.velocity
        self.avatar.setH(self.avatar.getH() - velocity[0] * 1.1)
        move = LVector3(0, velocity[1], 0)
        self.avatar.setPos(self.avatar, move * dt * self.vel_base)

    def give_reward(self):
        # clear the background
        self.base.setBackgroundColor(0.41, 0.41, 0.41)
        print 'give first reward'
        self.reward_count = 1
        if self.reward:
            # log this
            self.reward.pumpOut()
        self.gave_reward = self.base.taskMgr.doMethodLater(self.config['pump_delay'], self.reward_loop, 'reward_loop')

    def end_loop(self):
        print 'end loop'
        # clear avatar map
        # if there is a match set, return to center of color gradient,
        # set new match, if applicable
        self.set_next_trial()

    def set_next_trial(self):
        print 'set next trial'
        # move avatar back to beginning position, only matters for
        # showing card for next color match
        # self.avatar.set_pos(-10, -10, 2)
        # start the game
        self.start_loop()

    def check_key_map(self):
        if self.config['colors'][0]:
            if self.inputs.key_map['r']:
                self.config['match_direction'] = ['right']
            elif self.inputs.key_map['r'] is not None:
                self.config['match_direction'] = ['left']
        elif self.config['colors'][1]:
            if self.inputs.key_map['f']:
                self.config['match_direction'] = ['front']
            elif self.inputs.key_map['f'] is not None:
                self.config['match_direction'] = ['back']

    def setup_display2(self, display_node):
        print 'setup display2'
        props = WindowProperties()
        props.set_cursor_hidden(True)
        props.set_foreground(False)
        if self.config.get('resolution'):
            props.setSize(700, 700)
            props.setOrigin(-int(self.config['resolution'][0] - 5), 5)
        else:
            props.setSize(300, 300)
            props.setOrigin(10, 10)
        window2 = self.base.openWindow(props=props, aspectRatio=1)
        lens = OrthographicLens()
        lens.set_film_size(2, 2)
        lens.setNearFar(-100, 100)
        self.render2d = NodePath('render2d')
        self.render2d.attach_new_node(display_node)
        camera2d = self.base.makeCamera(window2)
        camera2d.setPos(0, -10, 0)
        camera2d.node().setLens(lens)
        camera2d.reparentTo(self.render2d)
示例#19
0
class Golem(FSM, DirectObject):
    def __init__(self):
        FSM.__init__(self, "FSM-Golem")
        random.seed()
        self.golem = loader.loadModel("Golem")
        self.golem = Actor("Golem", {
            "Idle":"Golem-Idle",
            "Walk":"Golem-Walk",
            "Attack":"Golem-Attack",
            "Destroyed":"Golem-Destroyed"})
        self.golem.setBlend(frameBlend = True)
        golemViewSphere = CollisionSphere(0, 0, 0.5, 6)
        golemViewSphere.setTangible(False)
        golemViewColNP = self.golem.attachNewNode(CollisionNode('golemViewField'))
        golemViewColNP.node().addSolid(golemViewSphere)
        golemHitSphere = CollisionSphere(0, 0, 0.5, 1)
        golemHitColNP = self.golem.attachNewNode(CollisionNode('golemHitField'))
        golemHitColNP.node().addSolid(golemHitSphere)

        # a collision segment to check attacks
        self.attackCheckSegment = CollisionSegment(0, 0, 1, 0, -1.3, 1)
        self.golemAttackRay = self.golem.attachNewNode(CollisionNode("golemAttackCollision"))
        self.golemAttackRay.node().addSolid(self.attackCheckSegment)
        self.golemAttackRay.node().setIntoCollideMask(0)
        self.attackqueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.golemAttackRay, self.attackqueue)

        attackAnim = self.golem.actorInterval("Attack", playRate = 2)
        self.AttackSeq = Parallel(
            attackAnim,
            Sequence(
                Wait(0.5),
                Func(self.ceckAttack)
            ))

        self.lookatFloater = NodePath(PandaNode("golemTracker"))
        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.hide()
        self.lookatFloater.reparentTo(render)
        self.trackerObject = loader.loadModel("misc/Pointlight")
        self.trackerObject.setColor(0, 1, 0)
        self.trackerObject.setScale(0.25)
        self.trackerObject.reparentTo(self.lookatFloater)

    def start(self, startPos):
        self.golem.setPos(startPos.getPos())
        self.golem.setHpr(startPos.getHpr())
        self.golem.reparentTo(render)
        self.trackedEnemy = None
        self.health = 5
        self.accept("playerCollision-in-golemViewField",
                    lambda extraArgs: base.messenger.send("golemSeesPlayer", [self.golem]))

    def stop(self):
        self.trackedEnemy = None
        taskMgr.remove("GolemAI_task")
        self.golem.hide()
        self.ignoreAll()

    def cleanup(self):
        self.stop()
        self.lookatFloater.removeNode()
        self.golem.cleanup()
        self.golem.removeNode()

    def activate(self, trackedEnemy):
        self.trackedEnemy = trackedEnemy
        taskMgr.add(self.aiTask, "GolemAI_task")
        self.lookatFloater.show()

    def aiTask(self, task):
        dt = globalClock.getDt()
        if self.AttackSeq.isPlaying(): return task.cont

        self.lookatFloater.setPos(self.golem, 0, 0, 3.4)
        self.lookatFloater.lookAt(self.trackedEnemy)
        self.lookatFloater.setH(self.lookatFloater.getH() + 180)
        self.lookatFloater.setP(0)
        self.lookatFloater.setR(0)

        self.golem.lookAt(self.trackedEnemy)
        self.golem.setH(self.golem.getH() + 180)

        distanceVec = self.golem.getPos() - self.trackedEnemy.getPos()
        enemyDist = distanceVec.length()

        if enemyDist < 2.0:
            # close enough for combat
            action = random.choice(["Attack", "Idle"])
            if action == "Attack":
                self.request("Attack")
            else:
                if self.state != "Idle":
                    self.request("Idle")
        else:
            self.golem.setY(self.golem, -0.5 * dt)
            if self.state != "Walk":
                self.request("Walk")

        return task.cont

    def hit(self):
        hitInterval = Sequence(
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15),
            Func(self.golem.setColorScale, 1, 0, 0, 0.75),
            Wait(0.15),
            Func(self.golem.clearColorScale),
            Wait(0.15))
        self.health -= 1
        if self.health == 4:
            self.trackerObject.setColor(0, 1, 0)
            hitInterval.start()
        elif self.health == 3:
            self.trackerObject.setColor(0.25, 0.75, 0)
            hitInterval.start()
        elif self.health == 2:
            self.trackerObject.setColor(0.5, .5, 0)
            hitInterval.start()
        elif self.health == 1:
            self.trackerObject.setColor(0.75, 0.25, 0)
            hitInterval.start()
        elif self.health == 0:
            self.trackerObject.setColor(0, 0, 0)
            self.request("Destroyed")

    def ceckAttack(self):
        for i in range(self.attackqueue.getNumEntries()):
            entry = self.attackqueue.getEntry(i)
            into = entry.getIntoNode()
            if "playerCollision" in into.getName():
                if random.random() > .5:
                    base.messenger.send("HitPlayer")

    def enterIdle(self):
        self.golem.loop("Idle")

    def enterWalk(self):
        self.golem.setPlayRate(2, "Walk")
        self.golem.loop("Walk")

    def enterAttack(self):
        self.AttackSeq.start()

    def enterDestroyed(self):
        self.ignoreAll()
        taskMgr.remove("GolemAI_task")
        self.AttackSeq.finish()
        self.golem.play("Destroyed")
        self.lookatFloater.hide()
        base.messenger.send("GolemDestroyed")
示例#20
0
class Menu(object):
    '''
    '''
    def __init__(self, parent):
        
        self._notify = DirectNotify().newCategory("Menu")
        self._notify.info("New Menu-Object created: %s" %(self))
        
        #Font
        self.font = DynamicTextFont(FONT)
        self.font.setRenderMode(TextFont.RMSolid)
        
        self.KEY_DELAY = 0.15
        self.player_buttonpressed = []
        
        self._parent = parent
        self._players = parent.players
        self._devices = parent.devices
        
        taskMgr.add(self.fetchAnyKey, "fetchAnyKey")
        
    def showStartScreen(self):
        '''
        the first screen with "press any Key"
        the device with the first key press will be the first player
        '''
        self._notify.info("Initializing StartScreen")
        
        self.wii = []
        
        #StartScreen Node
        self.startNode = NodePath("StartNode")
        self.startNode.reparentTo(render)
        self.startNode.setPos(-5,15,3)

        #Headline model
        headline = loader.loadModel("data/models/logo.egg")
        headline.setX(4.7)
        headline.setY(-4)
        headline.setZ(-2)
        headline.setP(90)
        headline.reparentTo(self.startNode)
        
        #Press any key text
        presskey = TextNode("PressAnyKey")
        presskey.setFont(self.font)
        presskey.setText(_("Press any key!!"))
        textNodePath = NodePath("PressAnyNode")
        textNodePath.attachNewNode(presskey)
        textNodePath.setPos(0,10,-9.5)
        textNodePath.reparentTo(self.startNode)
        
        #Show the start screen 
        self.startNode.show()
        
        #LICHT
        plight = PointLight('plight')
        plight.setColor(VBase4(10, 10, 10, 1))
        plnp = self.startNode.attachNewNode(plight)
        plnp.setPos(20, -800, 30)
        self.startNode.setLight(plnp)
        
        #Camera
        self.camera = base.makeCamera(base.win)
        
        self._notify.info("StarScreen initialized")
        
    # -----------------------------------------------------------------
    
    def fetchAnyKey(self, task):
        '''
        Return the first device with the first key stroke
        '''
        for i in xrange(len(self._devices.devices)):
            if self._devices.devices[i].boost:
                #Kill Camera
                self.camera.node().setActive(False)
                #Kill Node
                self.startNode.removeNode()
                
                #Start the menu
                self.menu = MainMenu(self._parent, self.newGame, self._devices.devices[i], self._devices)
                self.menu.menuMain()
                return task.done
        return task.cont



        # -----------------------------------------------------------------

    def newGame(self):
        '''
        The select vehicle screen
        '''
        base.enableParticles()
        self.countdown = COUNTDOWN_START #the countdown, when its over the game can be started
        self._notify.info("Initializing new game")
        #GlobPattern if we need a Panda Class
        self.vehicle_list = glob.glob("data/models/vehicles/*.egg")
        for index in range(len(self.vehicle_list)):
            self.vehicle_list[index] = Filename.fromOsSpecific(self.vehicle_list[index]).getFullpath()
        self._notify.debug("Vehicle list: %s" %(self.vehicle_list))
        self.platform = loader.loadModel("data/models/platform.egg")
        
        #Loading-Text that gets displayed when loading a model
        text = TextNode("Loading")
        text.setFont(self.font)
        text.setText(_("Loading..."))
        text.setAlign(TextProperties.ACenter)
        self.loading = NodePath("LoadingNode")
        self.loading.attachNewNode(text)
        self.loading.setPos(0,0,2)
        
        #The countdown, its possible to start the game when its 0
        text = TextNode("Countdown")
        text.setFont(self.font)
        text.setAlign(TextProperties.ACenter)
        text.setText(_(str(COUNTDOWN_START)))
        self.countdown_node = NodePath("Countdown")
        self.countdown_node.attachNewNode(text)
        self.countdown_node.setPos(0,0,4)
        
        #PreLoad the description that gets displayed when loading a model
        text = TextNode("name")
        text.setFont(self.font)
        text.setText(_("Loading..."))
        text.setAlign(TextProperties.ACenter)
        self.attributes = NodePath("AttributeNode")
        self.attributes.attachNewNode(text)
        
        self.unusedDevices = self._devices.devices[:]
        taskMgr.add(self.collectPlayer, "collectPlayer")
        #taskMgr.add(self.collectWii, "collectWii")
        self.screens = []
        taskMgr.add(self.selectVehicle, "selectVehicle")
        
        self.color_red = Vec4(1,0,0,0)
        self.color_green = Vec4(0,1,0,0)
        
        self._notify.info("New game initialized")
        
    # -----------------------------------------------------------------
        
    def selectVehicle(self, task):
        '''
        The vehicle select and rotate task
        '''
        #Set the countdown and hide, if > 3
        self.countdown -= globalClock.getDt()
        if self.countdown <=0:
            self.countdown_node.getChild(0).node().setText(_("Go"))
            self.countdown_node.setColor(self.color_green)
        elif self.countdown <=3: 
            self.countdown_node.getChild(0).node().setText(str(int(round((self.countdown+0.5)))))
            self.countdown_node.setColor(self.color_red)           
            self.countdown_node.show()
        else: self.countdown_node.hide()
        
        heading = self.loading.getH() -(30 * globalClock.getDt())
        self.loading.setH(heading)
        for player in self._players:
            if player.vehicle.model != None:
                player.vehicle.model.setH(heading)
                
            if self.player_buttonpressed[self._players.index(player)] < task.time and not player.vehicle.model_loading:
                if player.device.directions[0] < -0.8:
                    self._parent.menuselect.play()
                    self.countdown = COUNTDOWN_START
                    self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY
                    index = self.vehicle_list.index("data/models/vehicles/%s" %(player.vehicle.model.getName()))-1
                    self._notify.debug("Previous vehicle selected: %s" %(index))
                    player.vehicle.model_loading = True
                    player.vehicle.model.hide()
                    player.camera.camera.getParent().find("AttributeNode").hide()#Hide the attributes
                    self.loading.instanceTo(player.camera.camera.getParent())
                    loader.loadModel(self.vehicle_list[index], callback = player.setVehicle)
                elif player.device.directions[0] > 0.8:
                    self._parent.menuselect.play()
                    self.countdown = COUNTDOWN_START
                    self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY
                    index = self.vehicle_list.index("data/models/vehicles/%s" %(player.vehicle.model.getName()))+1
                    self._notify.debug("Next vehicle selected: %s" %(index))
                    if index >= len(self.vehicle_list): index = 0
                    player.vehicle.model_loading = True
                    player.vehicle.model.hide()
                    player.camera.camera.getParent().find("AttributeNode").hide()#Hide the attributes
                    self.loading.instanceTo(player.camera.camera.getParent())
                    loader.loadModel(self.vehicle_list[index], callback = player.setVehicle)
                    
                if player.device.directions[1] > 0.8:
                    self.countdown = COUNTDOWN_START
                    self._parent.menuselect.play()
                    self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY
                 
                    self._notify.debug("Next color selected")
                    a = player.vehicle.model.findAllTextures()
                    tex = a.findTexture(player.vehicle.model.getName()[:-4])
                    self.rotateHue(tex, 0.1)
                    
                elif player.device.directions[1] < -0.8:
                    self._parent.menuselect.play()
                    self.countdown = COUNTDOWN_START
                    self.player_buttonpressed[self._players.index(player)] = task.time + self.KEY_DELAY
                 
                    self._notify.debug("Next color selected")
                    a = player.vehicle.model.findAllTextures()
                    tex = a.findTexture(player.vehicle.model.getName()[:-4])
                    self.rotateHue(tex, -0.1)
        return task.cont
    
    # -----------------------------------------------------------------

    def rotateHue(self, tex, value=0.1):
        '''
        '''
        img = PNMImage()
        tex.store(img)
        for y in xrange(img.getReadYSize()):
            for x in xrange(img.getReadXSize()):
                r, g, b = img.getXel(x,y)
                h, s, v = colorsys.rgb_to_hsv(r, g, b)
                h += value
                if h < 0:
                    h += 360
                r, g, b = colorsys.hsv_to_rgb(h, s, v)
                img.setXel(x,y,r,g,b)
        tex.load(img)
    
    # -----------------------------------------------------------------

    def collectWii(self, task):
        '''
        Collect wiimotes task
        '''
        try:
            print 'Put Wiimote in discoverable mode now (press 1+2)...'
            wiimote = cwiid.Wiimote()
            self.wiimoteX.append(wiimote)
            print len(self.wiimoteX)
        except:
            pass
        return task.cont
        
    # -----------------------------------------------------------------
     
    def collectPlayer(self, task):
        '''
        Wait until all players are ready
        '''
        if len(self._players) > 0 and self.player_buttonpressed[0] < task.time:
            if self._players[0].device.boost and self.countdown <= 0:
                loading = False
                for player in self._players: 
                    if player.vehicle.model_loading: 
                        loading = True
                        break
                self._notify.debug("Loading vehicle: %s" %(loading))
                if not loading:
                    taskMgr.remove("selectVehicle")
                    self.track =  trackgen3d.Track3d(1000, 1800, 1600, 1200, 5)#len(self._players))
                    self.streetPath = render.attachNewNode(self.track.createRoadMesh())
                    #self.borderleftPath = render.attachNewNode(self.track.createBorderLeftMesh())
                    self.borderleftPath = render.attachNewNode(self.track.createBorderLeftMesh())
                    self.borderrightPath = render.attachNewNode(self.track.createBorderRightMesh())
                    self.borderleftcollisionPath = NodePath(self.track.createBorderLeftCollisionMesh())
                    self.borderrightcollisionPath = NodePath(self.track.createBorderRightCollisionMesh())
                    ##self.borderPath = render.attachNewNode(self.track.createBorderMesh())
                    
                    textures = ["tube", "tube2", "street"]
                    tex = textures[random.randint(0, len(textures)-1)]
                    roadtex = loader.loadTexture('data/textures/'+tex+'.png')
                    bordertex = loader.loadTexture('data/textures/border.png')
                    self.streetPath.setTexture(roadtex)
                    self.borderleftPath.setTexture(bordertex)
                    self.borderrightPath.setTexture(bordertex)

                    #self.streetPath = loader.loadModel('data/models/Street.egg')
                    ##self.streetPath = loader.loadModel('data/models/Street.egg')
                    #tex = loader.loadTexture('data/models/StreetTex.png')
                    #self.nodePath.setTexture(tex)
                    
                    self._parent.startGame(self.streetPath,self.borderleftPath,self.borderrightPath, self.track.trackpoints, self.borderleftcollisionPath, self.borderrightcollisionPath)
                    return task.done

        for device in self.unusedDevices:
                if device.boost:
                    self.countdown = COUNTDOWN_START
                    self.player_buttonpressed.append(0)
                    self._parent.addPlayer(device)
                    
                    #Set the PlayerCam to the Vehicle select menu Node        
                    vehicleSelectNode = NodePath("VehicleSelectNode")
                    self._players[-1].camera.camera.reparentTo(vehicleSelectNode)
                    
                    #Light, that casts shadows
                    plight = Spotlight('plight')
                    plight.setColor(VBase4(10.0, 10.0, 10.0, 1))
                    if (base.win.getGsg().getSupportsBasicShaders() != 0):
                        pass
                        ##plight.setShadowCaster(True, 2048, 2048)#enable shadows for this light ##TODO wegen Linux
                        
                    #Light
                    plight.getLens().setFov(80)
                    plnp = vehicleSelectNode.attachNewNode(plight)
                    plnp.setPos(2, -10, 10)
                    plnp.lookAt(0,0,0)
                    vehicleSelectNode.setLight(plnp)
##                    vehicleSelectNode.setShaderAuto()#enable autoshader so we can use shadows
                    
                    #Light
                    ambilight = AmbientLight('ambilight')
                    ambilight.setColor(VBase4(0.2, 0.2, 0.2, 1))
                    vehicleSelectNode.setLight(vehicleSelectNode.attachNewNode(ambilight))
                    self.platform.instanceTo(vehicleSelectNode) #Load the platform
                    
                    #instance shown text
                    self.countdown_node.instanceTo(vehicleSelectNode) #Instance the Countdown
                    self.loading.instanceTo(vehicleSelectNode) #Show the Loading-Text
                    self.attributes.copyTo(vehicleSelectNode).hide()
                    self._players[-1].vehicle.model_loading = True
                    
                    #start loading the model
                    loader.loadModel(self.vehicle_list[0], callback = self._players[-1].setVehicle)
                    self._notify.debug("Loading initial vehicle: %s" %(self.vehicle_list[0]))
                    self.unusedDevices.remove(device) 
                    self.player_buttonpressed[-1] = task.time + self.KEY_DELAY
                    
                    #Add the Skybox
                    skybox = loader.loadModel("data/models/skybox.egg")
                    t = Texture()
                    t.load(PNMImage("data/textures/skybox_hangar.png"))
                    skybox.setTexture(t)
                    skybox.setBin("background", 1)
                    skybox.setDepthWrite(0)
                    skybox.setDepthTest(0)
                    skybox.setLightOff()
                    skybox.setScale(10000)
                    skybox.reparentTo(vehicleSelectNode)

        for player in self._players:
            if self.player_buttonpressed[self._players.index(player)] < task.time:
                if player.device.use_item:
                    self.countdown = COUNTDOWN_START
                    self._notify.debug("Removing player: %s" %(player))
                    self.unusedDevices.append(player.device)
                    self.player_buttonpressed.pop(self._players.index(player))
                    self._parent.removePlayer(player) 
        return task.cont
示例#21
0
class PlayWorld(object):
    def __init__(self, config=None):
        if config is None:
            self.config = {}
            execfile('play_config.py', self.config)
        else:
            self.config = config
        self.reward = None
        print self.config['pydaq']
        if pydaq and self.config.setdefault('pydaq', True) is not None:
            self.reward = pydaq.GiveReward()
        self.reward_count = 0
        # adjustment to speed so corresponds to gobananas task
        # 7 seconds to cross original environment
        # speed needs to be adjusted to both speed in original
        # environment and c_range of colors
        # self.speed = 0.05 * (self.c_range[1] - self.c_range[0])
        # speed is own variable, so can be changed during training.
        self.speed = self.config['speed']

        # need a multiplier to the joystick output to tolerable speed
        self.vel_base = 4
        self.max_vel = [500, 500, 0]

        self.base = ShowBase()
        self.base.disableMouse()
        # self.base.setFrameRateMeter(True)
        # assume we are showing windows unless proven otherwise
        if self.config.get('win', True):
            # only need inputs if we have a window
            self.inputs = Inputs(self.base)
            props = WindowProperties()
            props.setCursorHidden(True)
            props.setForeground(True)
            print self.config.get('resolution')
            if self.config.get('resolution'):
                # main window
                props.set_size(int(self.config['resolution'][0]),
                               int(self.config['resolution'][1]))
                # props.set_origin(1920, 0)
                props.set_origin(500, 0)
            else:
                props.set_size(600, 600)
                props.set_origin(400, 50)
            self.base.win.requestProperties(props)
        # print 'background color', self.base.getBackgroundColor()
        # field = self.base.loader.loadModel("../goBananas/models/play_space/field.bam")
        field = self.base.loader.loadModel(
            "../goBananas/models/play_space/round_courtyard.bam")
        field.setPos(0, 0, 0)
        field.reparent_to(self.base.render)
        field_node_path = field.find('**/+CollisionNode')
        field_node_path.node().setIntoCollideMask(0)
        sky = self.base.loader.loadModel(
            "../goBananas/models/sky/sky_kahana2.bam")
        sky.setPos(0, 0, 0)
        sky.setScale(1.6)
        sky.reparentTo(self.base.render)
        windmill = self.base.loader.loadModel(
            "../goBananas/models/windmill/windmill.bam")
        windmill.setPos(-10, 30, -1)
        windmill.setScale(0.03)
        windmill.reparentTo(self.base.render)
        # mountain = self.base.loader.loadModel("../goBananas/models/mountain/mountain.bam")
        # mountain.setScale(0.0005)
        # mountain.setPos(10, 30, -0.5)

        # create the avatar
        self.avatar = NodePath(ActorNode("avatar"))
        self.avatar.reparentTo(self.base.render)
        self.avatar.setPos(0, 0, 1)
        self.avatar.setScale(0.5)
        pl = self.base.cam.node().getLens()
        pl.setFov(60)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.avatar)

        # initialize task variables
        self.frame_task = None
        self.started_game = None
        self.showed_match = None
        self.gave_reward = None

        # initialize and start the game
        self.set_next_trial()

        # print 'end init'

    def start_loop(self):
        # need to get new match
        self.start_play()

    def start_play(self):
        print 'start play'
        # log this
        # print self.base.render.ls()
        self.frame_task = self.base.taskMgr.add(self.game_loop, "game_loop")
        self.frame_task.last = 0  # initiate task time of the last frame

    def game_loop(self, task):
        dt = task.time - task.last
        task.last = task.time
        velocity = self.inputs.poll_inputs(LVector3(0))
        self.move_avatar(dt, velocity)
        return task.cont

    def reward_loop(self, task):
        self.reward_count += 1
        if self.reward_count <= self.config['num_beeps']:
            if self.reward:
                # log this
                print 'give a bloody reward already'
                self.reward.pumpOut()
            print 'give reward'
            return task.again
        else:
            self.end_loop()
            return task.done

    def move_avatar(self, dt, velocity):
        # print 'velocity', self.velocity
        self.avatar.setH(self.avatar.getH() - velocity[0] * 1.1)
        move = LVector3(0, velocity[1], 0)
        self.avatar.setPos(self.avatar, move * dt * self.vel_base)

    def give_reward(self):
        # clear the background
        self.base.setBackgroundColor(0.41, 0.41, 0.41)
        print 'give first reward'
        self.reward_count = 1
        if self.reward:
            # log this
            self.reward.pumpOut()
        self.gave_reward = self.base.taskMgr.doMethodLater(
            self.config['pump_delay'], self.reward_loop, 'reward_loop')

    def end_loop(self):
        print 'end loop'
        # clear avatar map
        # if there is a match set, return to center of color gradient,
        # set new match, if applicable
        self.set_next_trial()

    def set_next_trial(self):
        print 'set next trial'
        # move avatar back to beginning position, only matters for
        # showing card for next color match
        # self.avatar.set_pos(-10, -10, 2)
        # start the game
        self.start_loop()

    def check_key_map(self):
        if self.config['colors'][0]:
            if self.inputs.key_map['r']:
                self.config['match_direction'] = ['right']
            elif self.inputs.key_map['r'] is not None:
                self.config['match_direction'] = ['left']
        elif self.config['colors'][1]:
            if self.inputs.key_map['f']:
                self.config['match_direction'] = ['front']
            elif self.inputs.key_map['f'] is not None:
                self.config['match_direction'] = ['back']

    def setup_display2(self, display_node):
        print 'setup display2'
        props = WindowProperties()
        props.set_cursor_hidden(True)
        props.set_foreground(False)
        if self.config.get('resolution'):
            props.setSize(700, 700)
            props.setOrigin(-int(self.config['resolution'][0] - 5), 5)
        else:
            props.setSize(300, 300)
            props.setOrigin(10, 10)
        window2 = self.base.openWindow(props=props, aspectRatio=1)
        lens = OrthographicLens()
        lens.set_film_size(2, 2)
        lens.setNearFar(-100, 100)
        self.render2d = NodePath('render2d')
        self.render2d.attach_new_node(display_node)
        camera2d = self.base.makeCamera(window2)
        camera2d.setPos(0, -10, 0)
        camera2d.node().setLens(lens)
        camera2d.reparentTo(self.render2d)
示例#22
0
文件: ui.py 项目: tgbugs/desc
class CameraControl(DirectObject, HasKeybinds):
    """ adds controls to a given camera, usually base.camera"""
    def __init__(self,camera=None):
        #camera setup
        self.camera = camera
        if self.camera == None:
            self.camera = base.camera


        #XXX note, when moving cam target we need to make sure the camera doesnt move too...
        cameraBase = GeomNode('cameraBase') #utility node for pan
        targetGeom = makeCameraTarget()
        cameraBase.addGeom(targetGeom)
        self.cameraBase = render.attachNewNode(cameraBase)
        #self.cameraBase.setTwoSided(True) #backface culling issue with my tristrip fail

        self.cameraTarget = NodePath('cameraTarget') #utility node for rot, zoom, reattach
        self.cameraTarget.reparentTo(self.cameraBase)
        #self.cameraTarget.reparentTo(render)
        self.camera.reparentTo(self.cameraTarget)


        self.track = self.camera.attachNewNode('track')  #hack for pointing vector
        self.track.setPos(LVecBase3f(0,50,0))
        #nn = GeomNode('helper')
        #ng = makeCameraTarget()
        #nn.addGeom(targetGeom)
        #self.track.attachNewNode(nn)

        #keybind setup
        self.__ends__=defaultdict(list)

        #self.accept("escape", sys.exit)  #no, exit_cleanup will handle this...

        for function_name, key in keybinds['view'].items():
            #self.accept(key,taskMgr.add,(getattr(self,function),function+'Task'))
            self.accept(key, self.makeTask, [function_name])  # TODO split out functions that don't require tasks
            keytest=key.split('-')[-1]
            #print(keytest)
            if keytest in {'mouse1','mouse2','mouse3'}:
                self.addEndTask(keytest,function_name)
                self.accept(keytest+'-up', self.endTask, [keytest,function_name])

        #gains #TODO tweak me!
        self.XGAIN = .01
        self.YGAIN = .01

        #window setup
        self.getWindowSize()
        self.accept('window-event', self.getWindowSize)
        


        #self.accept('mouse1') #mouse 1 by itself does selection?
        #self.accpet('mouse3') #pan
        #self.accpet('mouse2')

        #--camera moves relatvie to arbitrary origin--
        #pan in plane
        #zoom #this needs to be on a log scale, linear is balls
        #rotate
        #--camera in place--
        #roll camera in place
        #yaw
        #pitch
        #look at selection/origin/center of mass of
        #--camera lense changes--
        #fov (for perspective)
        #perspective/orthographic
        #--worldcraft--
        #z mode wasd + mouse to orient for zooming

        #--selection functions we need to leave space for--
        #drop origin if we don't have something selected
        #click select
        #drag select, logial intersec
        #right click for menu

        self.__ch__=None
        self.__cp__=None
        self.__cr__=None
        self.__cth__=None
        self.__ctp__=None

        pass

    def getWindowSize(self,wat=None):
        self.__winx__ = base.win.getXSize()
        self.__winy__ = base.win.getYSize()
        #print(self.__winx__,self.__winy__)

    def makeTask(self, function_name):
        """ ye old task spawner """
        if hasattr(self, function_name):
            if base.mouseWatcherNode.hasMouse():
                x,y = base.mouseWatcherNode.getMouse()
                setattr(self, '__%sTask_s__'%function_name, (x,y)) #this should be faster
                taskMgr.add(getattr(self,function_name), function_name+'Task')
        else:
            raise KeyError('Check your keybinds, there is no function by that name here!')

    def addEndTask(self,key,function_name):
        self.__ends__[key].append(function_name)

    def endTask(self, key, function):
        for func in self.__ends__[key]:
            taskMgr.remove(func+'Task')
            setattr(self, '__%sTask_s__'%func, None) #this should be faster
        self.__ch__=None #FIXME this seems hackish
        self.__cp__=None
        self.__cr__=None
        self.__cth__=None
        self.__ctp__=None

    def getMouseDdDt(self, name): #XXX deprecated
        """ use gain to adjust pixels per degree
            this should probably be normalized to screen size actually?
            or no... but to what?
        """
        if base.mouseWatcherNode.hasMouse():
            x,z = base.mouseWatcherNode.getMouse()
            sx,sz = getattr(self,'__%s_start__'%name)
            print(x,sx)
            print(z,sz)
            if z != sz or x != sx: #watch out for aliasing here...
                norm = (((x - sx) * self.XGAIN)**2 + ((z - sz) * self.YGAIN)**2)**.5
                #norm =  ((x - sx) * self.X_GAIN), ((z - sz) * self.Y_GAIN)
                setattr(self, '__%s_start__'%name, (x,z))
                return norm
            else: #mouse has not moved
                return 0

    def getMouseDdDf(self,name):
        if base.mouseWatcherNode.hasMouse():
            x,y = base.mouseWatcherNode.getMouse()
            sx,sy = getattr(self,'__%s_s__'%(name))
            dx = (x - sx) * self.XGAIN * self.__winx__
            dy = (y - sy) * self.YGAIN * self.__winy__
            return dx, dy

    def getMouseCross(self,name): #FIXME may need to do this incrementally as we started with...
        if base.mouseWatcherNode.hasMouse():
            x,y = base.mouseWatcherNode.getMouse()
            sx,sy = getattr(self,'__%s_s__'%(name))

            dx = (x - sx) * self.XGAIN * self.__winx__
            dy = (y - sy) * self.YGAIN * self.__winy__
            norm = (dx**2 + dy**2)**.5
            cross = x * sy - y * sx

            return cross * norm

    @event_callback
    def home(self, task):
        self.camera.lookAt(self.cameraBase)
        taskMgr.remove(task.getName())
        return task.cont

    @event_callback
    def pan(self, task):
        """ I don't like it, it's weird! """
        invert = -1
        magic_number = 15
        magic_number = 20
        if base.mouseWatcherNode.hasMouse():
            x,y = base.mouseWatcherNode.getMouse()
            sx,sy = getattr(self,'__%s_s__'%(task.getName()))
            dx = (x - sx) * self.XGAIN * self.__winx__ * magic_number * invert
            dy = (y - sy) * self.YGAIN * self.__winy__ * magic_number * invert
            #cx,cy,cz = self.camera.getPos()
            self.camera.setPos(self.camera,dx,0,dy)
            setattr(self, '__%s_s__'%task.getName(), (x,y)) #reset each frame to compensate for moving from own position
            #nx,ny,nz = self.camera.getPos()
            #dx2, dy2, dz2 = nx-cx, ny-cy, nz-cz
            #self.camera.setPos(cx,cz,cy)
            #self.cameraBase.setPos(self.cameraBase,dx2,dy2,dz2) #a hack to move cameraBase as if it were the camera
            #self.cameraTarget.setPos(self.cameraBase,dx2,dy2,dz2) #a hack to move cameraBase as if it were the camera
        return task.cont

    @event_callback
    def zoom_in_slow(self, task, speed = 10):
        return self.zoom_in(task, speed) #hehe this will work because it just passes the task :)

    @event_callback
    def zoom_out_slow(self, task, speed = 10):
        return self.zoom_out(task, speed)

    @event_callback
    def zoom_in_fast(self, task, speed = 1000):
        return self.zoom_in(task, speed) #hehe this will work because it just passes the task :)

    @event_callback
    def zoom_out_fast(self, task, speed = 1000):
        return self.zoom_out(task, speed)


    @event_callback
    def zoom_in(self, task, speed = 100): #FIXME zoom_in and zoom_out still get custom xys even thought they don't use them!
        self.camera.setPos(self.camera,0,speed,0)
        taskMgr.remove(task.getName())
        return task.cont

    @event_callback
    def zoom_out(self, task, speed = 100):
        self.camera.setPos(self.camera,0,-speed,0)
        taskMgr.remove(task.getName()) #we do it this way instead of addOnce because we want to add all the tasks in one go
        return task.cont

    @event_callback
    def rotate(self, task): #FIXME disregard orientation acqurie proper mouse movements!
        dx,dy = self.getMouseDdDf(task.getName())
        if self.__cth__ == None:
            self.__cth__ = self.cameraTarget.getH()
        if self.__ctp__ == None:
            self.__ctp__ = self.cameraTarget.getP()
        self.cameraTarget.setH(self.__cth__ - dx * 10)
        self.cameraTarget.setP(self.__ctp__ + dy * 10)
        return task.cont

    #if we are in camera mode
    @event_callback
    def pitch(self, task):
        dx,dy = self.getMouseDdDf(task.getName())
        print('got pitch',dy)
        return task.cont

    @event_callback
    def look(self, task): #AKA heading in hpr
        dx,dy = self.getMouseDdDf(task.getName())
        if self.__ch__ == None:
            self.__ch__ = self.camera.getH()
        if self.__cp__ == None:
            self.__cp__ = self.camera.getP()
        self.camera.setH(self.__ch__ - dx)
        self.camera.setP(self.__cp__ + dy) #FIXME when we're clicking this might should be inverted?
        return task.cont

    @event_callback
    def roll(self, task):
        """ ALWAYS roll with respect to axis of rotation"""
        if self.__cr__ == None:
            self.__cr__ = self.cameraTarget.getR()
        #cross product idiot
        cross = self.getMouseCross(task.getName())

        self.cameraTarget.setR(self.__cr__ - cross * 10 )
        return task.cont
示例#23
0
class CogdoFlyingCameraManager:

    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

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

    def _initCollisions(self):
        self._camCollRay = CollisionRay()
        camCollNode = CollisionNode('CameraToonRay')
        camCollNode.addSolid(self._camCollRay)
        camCollNode.setFromCollideMask(OTPGlobals.WallBitmask | OTPGlobals.CameraBitmask | ToontownGlobals.FloorEventBitmask | ToontownGlobals.CeilingBitmask)
        camCollNode.setIntoCollideMask(0)
        self._camCollNP = self._camera.attachNewNode(camCollNode)
        self._camCollNP.show()
        self._collOffset = Vec3(0, 0, 0.5)
        self._collHandler = CollisionHandlerQueue()
        self._collTrav = CollisionTraverser()
        self._collTrav.addCollider(self._camCollNP, self._collHandler)
        self._betweenCamAndToon = {}
        self._transNP = NodePath('trans')
        self._transNP.reparentTo(render)
        self._transNP.setTransparency(True)
        self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
        self._transNP.setBin('fixed', 10000)

    def _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

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

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

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

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

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

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

        self._betweenCamAndToon = nodesInBetween