示例#1
0
 def _calcSpeeds(self):
     # get the button states:
     forward = inputState.isSet("forward")
     reverse = inputState.isSet("reverse")
     turnLeft = inputState.isSet("turnLeft")
     turnRight = inputState.isSet("turnRight")
     slide = inputState.isSet(self.slideName) or 0
     #jump = inputState.isSet("jump")
     
     # Check for Auto-Run
     if base.localAvatar.getAutoRun():
         forward = 1
         reverse = 0
             
     # Determine what the speeds are based on the buttons:
     self.speed=(forward and self.avatarControlForwardSpeed or
                 reverse and -self.avatarControlReverseSpeed)
     # Should fSlide be renamed slideButton?
     self.slideSpeed=slide and ((reverse and turnLeft and -self.avatarControlReverseSpeed*(0.75)) or
                                (reverse and turnRight and self.avatarControlReverseSpeed*(0.75)) or
                                (turnLeft and -self.avatarControlForwardSpeed*(0.75)) or
                                (turnRight and self.avatarControlForwardSpeed*(0.75)))
     self.rotationSpeed=not slide and (
             (turnLeft and self.avatarControlRotateSpeed) or
             (turnRight and -self.avatarControlRotateSpeed))
示例#2
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft")
        turnRight = inputState.isSet("turnRight")
        slideLeft = inputState.isSet("slideLeft")
        slideRight = inputState.isSet("slideRight")
        levitateUp = inputState.isSet("levitateUp")
        levitateDown = inputState.isSet("levitateDown")
        run = inputState.isSet("run") and self.runMultiplier or 1.0

        # Check for Auto-Run
        if base.localAvatar.getAutoRun():
            forward = 1
            reverse = 0

        # Determine what the speeds are based on the buttons:
        self.speed = ((forward and self.avatarControlForwardSpeed
                       or reverse and -self.avatarControlReverseSpeed))
        self.liftSpeed = ((levitateUp and self.avatarControlForwardSpeed or
                           levitateDown and -self.avatarControlReverseSpeed))
        self.slideSpeed = ((slideLeft and -self.avatarControlForwardSpeed)
                           or (slideRight and self.avatarControlForwardSpeed))
        self.rotationSpeed = ((turnLeft and self.avatarControlRotateSpeed) or
                              (turnRight and -self.avatarControlRotateSpeed))

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        # Check to see if we're moving at all:
        if self.speed or self.liftSpeed or self.slideSpeed or self.rotationSpeed:
            # How far did we move based on the amount of time elapsed?
            dt = ClockObject.getGlobalClock().getDt()
            distance = dt * self.speed * run
            lift = dt * self.liftSpeed * run
            slideDistance = dt * self.slideSpeed * run
            rotation = dt * self.rotationSpeed

            # Take a step in the direction of our previous heading.
            self.vel = Vec3(Vec3.forward() * distance + Vec3.up() * lift +
                            Vec3.right() * slideDistance)
            if self.vel != Vec3.zero():
                # rotMat is the rotation matrix corresponding to
                # our previous heading.
                rotMat = Mat3.rotateMatNormaxis(self.avatarNodePath.getH(),
                                                Vec3.up())
                step = rotMat.xform(self.vel)
                self.avatarNodePath.setFluidPos(
                    Point3(self.avatarNodePath.getPos() + step))
            self.avatarNodePath.setH(self.avatarNodePath.getH() + rotation)
            messenger.send("avatarMoving")
        else:
            self.vel.set(0.0, 0.0, 0.0)
        return Task.cont
示例#3
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        if not self.lifter.hasContact():
            # hack fix for falling through the floor:
            messenger.send("walkerIsOutOfWorld", [self.avatarNodePath])

        self._calcSpeeds()

        if __debug__:
            debugRunning = inputState.isSet("debugRunning")
            if debugRunning:
                self.speed*=4.0
                self.slideSpeed*=4.0
                self.rotationSpeed*=1.25

        if self.wantDebugIndicator:
            self.displayDebugInfo()
        # How far did we move based on the amount of time elapsed?
        dt=ClockObject.getGlobalClock().getDt()
        # Check to see if we're moving at all:
        if self.speed or self.slideSpeed or self.rotationSpeed:
            if self.stopThisFrame:
                distance = 0.0
                slideDistance = 0.0
                rotation = 0.0
                self.stopThisFrame = 0
            else:
                distance = dt * self.speed
                slideDistance = dt * self.slideSpeed
                rotation = dt * self.rotationSpeed

            # Take a step in the direction of our previous heading.
            self.vel=Vec3(Vec3.forward() * distance +
                          Vec3.right() * slideDistance)
            if self.vel != Vec3.zero():
                # rotMat is the rotation matrix corresponding to
                # our previous heading.
                rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                step=rotMat.xform(self.vel)
                self.avatarNodePath.setFluidPos(Point3(self.avatarNodePath.getPos()+step))
            self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
            messenger.send("avatarMoving")
        else:
            self.vel.set(0.0, 0.0, 0.0)

        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        self.__oldDt = dt

        try:
            self.worldVelocity = self.__oldPosDelta*(1/self.__oldDt)
        except:
            # divide by zero
            self.worldVelocity = 0

        return Task.cont
示例#4
0
    def setWASDTurn(self, turn):
        self.__WASDTurn = turn

        if not self.isEnabled:
            return
        
        turnLeftWASDSet = inputState.isSet("turnLeft", inputSource=inputState.WASD)
        turnRightWASDSet = inputState.isSet("turnRight", inputSource=inputState.WASD)
        slideLeftWASDSet = inputState.isSet("slideLeft", inputSource=inputState.WASD)
        slideRightWASDSet = inputState.isSet("slideRight", inputSource=inputState.WASD)

        for token in self.WASDTurnTokens:
            token.release()

        if turn:
            self.WASDTurnTokens = (
                inputState.watchWithModifiers("turnLeft", "a", inputSource=inputState.WASD),
                inputState.watchWithModifiers("turnRight", "d", inputSource=inputState.WASD),
                )

            inputState.set("turnLeft", slideLeftWASDSet, inputSource=inputState.WASD)
            inputState.set("turnRight", slideRightWASDSet, inputSource=inputState.WASD)

            inputState.set("slideLeft", False, inputSource=inputState.WASD)
            inputState.set("slideRight", False, inputSource=inputState.WASD)

        else:
            self.WASDTurnTokens = (
                inputState.watchWithModifiers("slideLeft", "a", inputSource=inputState.WASD),
                inputState.watchWithModifiers("slideRight", "d", inputSource=inputState.WASD),
                )

            inputState.set("slideLeft", turnLeftWASDSet, inputSource=inputState.WASD)
            inputState.set("slideRight", turnRightWASDSet, inputSource=inputState.WASD)
                
            inputState.set("turnLeft", False, inputSource=inputState.WASD)
            inputState.set("turnRight", False, inputSource=inputState.WASD)
                
示例#5
0
    def setWASDTurn(self, turn):
        self.__WASDTurn = turn

        if not self.isEnabled:
            return
        
        turnLeftWASDSet = inputState.isSet("turnLeft", inputSource=inputState.WASD)
        turnRightWASDSet = inputState.isSet("turnRight", inputSource=inputState.WASD)
        slideLeftWASDSet = inputState.isSet("slideLeft", inputSource=inputState.WASD)
        slideRightWASDSet = inputState.isSet("slideRight", inputSource=inputState.WASD)

        for token in self.WASDTurnTokens:
            token.release()

        if turn:
            self.WASDTurnTokens = (
                inputState.watchWithModifiers("turnLeft", "a", inputSource=inputState.WASD),
                inputState.watchWithModifiers("turnRight", "d", inputSource=inputState.WASD),
                )

            inputState.set("turnLeft", slideLeftWASDSet, inputSource=inputState.WASD)
            inputState.set("turnRight", slideRightWASDSet, inputSource=inputState.WASD)

            inputState.set("slideLeft", False, inputSource=inputState.WASD)
            inputState.set("slideRight", False, inputSource=inputState.WASD)

        else:
            self.WASDTurnTokens = (
                inputState.watchWithModifiers("slideLeft", "a", inputSource=inputState.WASD),
                inputState.watchWithModifiers("slideRight", "d", inputSource=inputState.WASD),
                )

            inputState.set("slideLeft", turnLeftWASDSet, inputSource=inputState.WASD)
            inputState.set("slideRight", turnRightWASDSet, inputSource=inputState.WASD)
                
            inputState.set("turnLeft", False, inputSource=inputState.WASD)
            inputState.set("turnRight", False, inputSource=inputState.WASD)
示例#6
0
 def monitor(self, foo):
     #assert self.debugPrint("monitor()")
     #if 1:
     #    airborneHeight=self.avatar.getAirborneHeight()
     #    onScreenDebug.add("airborneHeight", "% 10.4f"%(airborneHeight,))
     if 0:
         onScreenDebug.add("InputState forward", "%d"%(inputState.isSet("forward")))
         onScreenDebug.add("InputState reverse", "%d"%(inputState.isSet("reverse")))
         onScreenDebug.add("InputState turnLeft", "%d"%(inputState.isSet("turnLeft")))
         onScreenDebug.add("InputState turnRight", "%d"%(inputState.isSet("turnRight")))
         onScreenDebug.add("InputState slideLeft", "%d"%(inputState.isSet("slideLeft")))
         onScreenDebug.add("InputState slideRight", "%d"%(inputState.isSet("slideRight")))
     return Task.cont
示例#7
0
    def _calcSpeeds(self):
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft") or inputState.isSet("slideLeft")
        turnRight = inputState.isSet("turnRight") or inputState.isSet("slideRight")

        # Check for Auto-Run
        if base.localAvatar.getAutoRun():
            forward = 1
            reverse = 0
        
        # Determine what the speeds are based on the buttons:
        self.speed=(forward and self.avatarControlForwardSpeed or
                    reverse and -self.avatarControlReverseSpeed)
        self.slideSpeed=0.
        self.rotationSpeed=(
            (turnLeft and self.avatarControlRotateSpeed) or
            (turnRight and -self.avatarControlRotateSpeed))
示例#8
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.append("localAvatar pos = %s\n"%(base.localAvatar.getPos().pPrintValues(),))
                onScreenDebug.append("localAvatar h = % 10.4f\n"%(base.localAvatar.getH(),))
                onScreenDebug.append("localAvatar anim = %s\n"%(base.localAvatar.animFSM.getCurrentState().getName(),))
        #assert self.debugPrint("handleAvatarControls(task=%s)"%(task,))
        physObject=self.actorNode.getPhysicsObject()
        #rotAvatarToPhys=Mat3.rotateMatNormaxis(-self.avatarNodePath.getH(), Vec3.up())
        #rotPhysToAvatar=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
        contact=self.actorNode.getContactVector()

        # hack fix for falling through the floor:
        if contact==Vec3.zero() and self.avatarNodePath.getZ()<-50.0:
            # DCR: don't reset X and Y; allow player to move
            self.reset()
            self.avatarNodePath.setZ(50.0)
            messenger.send("walkerIsOutOfWorld", [self.avatarNodePath])

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft")
        turnRight = inputState.isSet("turnRight")
        slide = 0#inputState.isSet("slide")
        slideLeft = 0#inputState.isSet("slideLeft")
        slideRight = 0#inputState.isSet("slideRight")
        jump = inputState.isSet("jump")
        
        # Check for Auto-Run
        if base.localAvatar.getAutoRun():
            forward = 1
            reverse = 0
                
        # Determine what the speeds are based on the buttons:
        self.__speed=(forward and self.avatarControlForwardSpeed or
                reverse and -self.avatarControlReverseSpeed)
        avatarSlideSpeed=self.avatarControlForwardSpeed*0.5
        #self.__slideSpeed=slide and (
        #        (turnLeft and -avatarSlideSpeed) or
        #        (turnRight and avatarSlideSpeed))
        self.__slideSpeed=(
                (slideLeft and -avatarSlideSpeed) or
                (slideRight and avatarSlideSpeed))
        self.__rotationSpeed=not slide and (
                (turnLeft and self.avatarControlRotateSpeed) or
                (turnRight and -self.avatarControlRotateSpeed))

        # How far did we move based on the amount of time elapsed?
        dt=ClockObject.getGlobalClock().getDt()

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0
        #self.__oldPosDelta = render.getRelativeVector(
        #    self.avatarNodePath,
        #    self.avatarNodePath.getPosDelta(render))
        #self.__oldPosDelta = self.avatarNodePath.getRelativeVector(
        #    render,
        #    self.avatarNodePath.getPosDelta(render))
        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        self.__oldDt = dt
        #posDelta = self.avatarNodePath.getPosDelta(render)
        #if posDelta==Vec3.zero():
        #    self.priorParent.setVector(self.__oldPosDelta)
        #else:
        #    self.priorParent.setVector(Vec3.zero())
        #    # We must copy the vector to preserve it:
        #    self.__oldPosDelta=Vec3(posDelta)
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.add("posDelta1",
                    self.avatarNodePath.getPosDelta(render).pPrintValues())

                if 0:
                    onScreenDebug.add("posDelta3",
                        render.getRelativeVector(
                            self.avatarNodePath,
                            self.avatarNodePath.getPosDelta(render)).pPrintValues())

                if 0:
                    onScreenDebug.add("gravity",
                        self.gravity.getLocalVector().pPrintValues())
                    onScreenDebug.add("priorParent",
                        self.priorParent.getLocalVector().pPrintValues())
                    onScreenDebug.add("avatarViscosity",
                        "% 10.4f"%(self.avatarViscosity.getCoef(),))

                    onScreenDebug.add("physObject pos",
                        physObject.getPosition().pPrintValues())
                    onScreenDebug.add("physObject hpr",
                        physObject.getOrientation().getHpr().pPrintValues())
                    onScreenDebug.add("physObject orien",
                        physObject.getOrientation().pPrintValues())

                if 1:
                    onScreenDebug.add("physObject vel",
                        physObject.getVelocity().pPrintValues())
                    onScreenDebug.add("physObject len",
                        "% 10.4f"%physObject.getVelocity().length())

                if 0:
                    onScreenDebug.add("posDelta4",
                        self.priorParentNp.getRelativeVector(
                            render,
                            self.avatarNodePath.getPosDelta(render)).pPrintValues())

                if 1:
                    onScreenDebug.add("priorParent",
                        self.priorParent.getLocalVector().pPrintValues())

                if 0:
                    onScreenDebug.add("priorParent po",
                        self.priorParent.getVector(physObject).pPrintValues())

                if 0:
                    onScreenDebug.add("__posDelta",
                        self.__oldPosDelta.pPrintValues())

                if 1:
                    onScreenDebug.add("contact",
                        contact.pPrintValues())
                    #onScreenDebug.add("airborneHeight", "% 10.4f"%(
                    #    self.getAirborneHeight(),))

                if 0:
                    onScreenDebug.add("__oldContact",
                        contact.pPrintValues())
                    onScreenDebug.add("__oldAirborneHeight", "% 10.4f"%(
                        self.getAirborneHeight(),))
        airborneHeight=self.getAirborneHeight()
        if airborneHeight > self.highMark:
            self.highMark = airborneHeight
            if __debug__:
                onScreenDebug.add("highMark", "% 10.4f"%(self.highMark,))
        #if airborneHeight < 0.1: #contact!=Vec3.zero():
        if 1:
            if (airborneHeight > self.avatarRadius*0.5
                    or physObject.getVelocity().getZ() > 0.0
                    ): # Check stair angles before changing this.
                # ...the avatar is airborne (maybe a lot or a tiny amount).
                self.isAirborne = 1
            else:
                # ...the avatar is very close to the ground (close enough to be
                # considered on the ground).
                if self.isAirborne and physObject.getVelocity().getZ() <= 0.0:
                    # ...the avatar has landed.
                    contactLength = contact.length()
                    if contactLength>self.__hardLandingForce:
                        #print "jumpHardLand"
                        messenger.send("jumpHardLand")
                    else:
                        #print "jumpLand"
                        messenger.send("jumpLand")
                    self.priorParent.setVector(Vec3.zero())
                    self.isAirborne = 0
                elif jump:
                    #print "jump"
                    #self.__jumpButton=0
                    messenger.send("jumpStart")
                    if 0:
                        # ...jump away from walls and with with the slope normal.
                        jumpVec=Vec3(contact+Vec3.up())
                        #jumpVec=Vec3(rotAvatarToPhys.xform(jumpVec))
                        jumpVec.normalize()
                    else:
                        # ...jump straight up, even if next to a wall.
                        jumpVec=Vec3.up()
                    jumpVec*=self.avatarControlJumpForce
                    physObject.addImpulse(Vec3(jumpVec))
                    self.isAirborne = 1 # Avoid double impulse before fully airborne.
                else:
                    self.isAirborne = 0
            if __debug__:
                onScreenDebug.add("isAirborne", "%d"%(self.isAirborne,))
        else:
            if contact!=Vec3.zero():
                # ...the avatar has touched something (but might not be on the ground).
                contactLength = contact.length()
                contact.normalize()
                angle=contact.dot(Vec3.up())
                if angle>self.__standableGround:
                    # ...avatar is on standable ground.
                    if self.__oldContact==Vec3.zero():
                    #if self.__oldAirborneHeight > 0.1: #self.__oldContact==Vec3.zero():
                        # ...avatar was airborne.
                        self.jumpCount-=1
                        if contactLength>self.__hardLandingForce:
                            messenger.send("jumpHardLand")
                        else:
                            messenger.send("jumpLand")
                    elif jump:
                        self.jumpCount+=1
                        #self.__jumpButton=0
                        messenger.send("jumpStart")
                        jump=Vec3(contact+Vec3.up())
                        #jump=Vec3(rotAvatarToPhys.xform(jump))
                        jump.normalize()
                        jump*=self.avatarControlJumpForce
                        physObject.addImpulse(Vec3(jump))

        if contact!=self.__oldContact:
            # We must copy the vector to preserve it:
            self.__oldContact=Vec3(contact)
        self.__oldAirborneHeight=airborneHeight

        moveToGround = Vec3.zero()
        if not self.useHeightRay or self.isAirborne:
            # ...the airborne check is a hack to stop sliding.
            self.phys.doPhysics(dt)
            if __debug__:
                onScreenDebug.add("phys", "on")
        else:
            physObject.setVelocity(Vec3.zero())
            #if airborneHeight>0.001 and contact==Vec3.zero():
            #    moveToGround = Vec3(0.0, 0.0, -airborneHeight)
            #moveToGround = Vec3(0.0, 0.0, -airborneHeight)
            moveToGround = Vec3(0.0, 0.0, -self.determineHeight())
            if __debug__:
                onScreenDebug.add("phys", "off")
        # Check to see if we're moving at all:
        if self.__speed or self.__slideSpeed or self.__rotationSpeed or moveToGround!=Vec3.zero():
            distance = dt * self.__speed
            slideDistance = dt * self.__slideSpeed
            rotation = dt * self.__rotationSpeed

            #debugTempH=self.avatarNodePath.getH()
            assert self.avatarNodePath.getQuat().isSameDirection(physObject.getOrientation())
            assert self.avatarNodePath.getPos().almostEqual(physObject.getPosition(), 0.0001)

            # update pos:
            # Take a step in the direction of our previous heading.
            self.__vel=Vec3(
                Vec3.forward() * distance +
                Vec3.right() * slideDistance)

            # rotMat is the rotation matrix corresponding to
            # our previous heading.
            rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
            step=rotMat.xform(self.__vel)
            physObject.setPosition(Point3(
                physObject.getPosition()+step+moveToGround))

            # update hpr:
            o=physObject.getOrientation()
            r=LRotationf()
            r.setHpr(Vec3(rotation, 0.0, 0.0))
            physObject.setOrientation(o*r)

            # sync the change:
            self.actorNode.updateTransform()

            assert self.avatarNodePath.getQuat().isSameDirection(physObject.getOrientation())
            assert self.avatarNodePath.getPos().almostEqual(physObject.getPosition(), 0.0001)
            #assert self.avatarNodePath.getH()==debugTempH-rotation
            messenger.send("avatarMoving")
        else:
            self.__vel.set(0.0, 0.0, 0.0)
        # Clear the contact vector so we can tell if we contact something next frame:
        self.actorNode.setContactVector(Vec3.zero())
        return Task.cont
示例#9
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft")
        turnRight = inputState.isSet("turnRight")
        slideLeft = inputState.isSet("slideLeft")
        slideRight = inputState.isSet("slideRight")
        levitateUp = inputState.isSet("levitateUp")
        levitateDown = inputState.isSet("levitateDown")
        run = inputState.isSet("run") and self.runMultiplier or 1.0

        # Check for Auto-Run
        if base.localAvatar.getAutoRun():
            forward = 1
            reverse = 0
        
        # Determine what the speeds are based on the buttons:
        self.speed=(
                (forward and self.avatarControlForwardSpeed or
                reverse and -self.avatarControlReverseSpeed))
        self.liftSpeed=(
                (levitateUp and self.avatarControlForwardSpeed or
                levitateDown and -self.avatarControlReverseSpeed))
        self.slideSpeed=(
                (slideLeft and -self.avatarControlForwardSpeed) or
                (slideRight and self.avatarControlForwardSpeed))
        self.rotationSpeed=(
                (turnLeft and self.avatarControlRotateSpeed) or
                (turnRight and -self.avatarControlRotateSpeed))

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        # Check to see if we're moving at all:
        if self.speed or self.liftSpeed or self.slideSpeed or self.rotationSpeed:
            # How far did we move based on the amount of time elapsed?
            dt=ClockObject.getGlobalClock().getDt()
            distance = dt * self.speed * run
            lift = dt * self.liftSpeed * run
            slideDistance = dt * self.slideSpeed * run
            rotation = dt * self.rotationSpeed

            # Take a step in the direction of our previous heading.
            self.vel=Vec3(Vec3.forward() * distance +
                          Vec3.up() * lift +
                          Vec3.right() * slideDistance)
            if self.vel != Vec3.zero():
                # rotMat is the rotation matrix corresponding to
                # our previous heading.
                rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                step=rotMat.xform(self.vel)
                self.avatarNodePath.setFluidPos(Point3(self.avatarNodePath.getPos()+step))
            self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
            messenger.send("avatarMoving")
        else:
            self.vel.set(0.0, 0.0, 0.0)
        return Task.cont
示例#10
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        # get the button states:
        run = inputState.isSet("run")
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft")
        turnRight = inputState.isSet("turnRight")
        slideLeft = inputState.isSet("slideLeft")
        slideRight = inputState.isSet("slideRight")
        jump = inputState.isSet("jump")

        # Check for Auto-Run
        if 'localAvatar' in __builtins__:
            if base.localAvatar and base.localAvatar.getAutoRun():
                forward = 1
                reverse = 0

        # Determine what the speeds are based on the buttons:
        self.speed = (forward and self.avatarControlForwardSpeed
                      or reverse and -self.avatarControlReverseSpeed)
        # Slide speed is a scaled down version of forward speed
        # Note: you can multiply a factor in here if you want slide to
        # be slower than normal walk/run. Let's try full speed.
        #self.slideSpeed=(slideLeft and -self.avatarControlForwardSpeed*0.75 or
        #                 slideRight and self.avatarControlForwardSpeed*0.75)
        self.slideSpeed = (
            reverse and slideLeft and -self.avatarControlReverseSpeed * 0.75
            or reverse and slideRight and self.avatarControlReverseSpeed * 0.75
            or slideLeft and -self.avatarControlForwardSpeed * 0.75
            or slideRight and self.avatarControlForwardSpeed * 0.75)
        self.rotationSpeed = not (slideLeft or slideRight) and (
            (turnLeft and self.avatarControlRotateSpeed) or
            (turnRight and -self.avatarControlRotateSpeed))

        if self.speed and self.slideSpeed:
            self.speed *= GravityWalker.DiagonalFactor
            self.slideSpeed *= GravityWalker.DiagonalFactor

        debugRunning = inputState.isSet("debugRunning")
        if (debugRunning):
            self.speed *= base.debugRunningMultiplier
            self.slideSpeed *= base.debugRunningMultiplier
            self.rotationSpeed *= 1.25

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0
        if self.wantDebugIndicator:
            self.displayDebugInfo()
        if self.lifter.isOnGround():
            if self.isAirborne:
                self.isAirborne = 0
                assert self.debugPrint("isAirborne 0 due to isOnGround() true")
                impact = self.lifter.getImpactVelocity()
                if impact < -30.0:
                    messenger.send("jumpHardLand")
                    self.startJumpDelay(0.3)
                else:
                    messenger.send("jumpLand")
                    if impact < -5.0:
                        self.startJumpDelay(0.2)
                    # else, ignore the little potholes.
            assert self.isAirborne == 0
            self.priorParent = Vec3.zero()
            if jump and self.mayJump:
                # The jump button is down and we're close
                # enough to the ground to jump.
                self.lifter.addVelocity(self.avatarControlJumpForce)
                messenger.send("jumpStart")
                self.isAirborne = 1
                assert self.debugPrint("isAirborne 1 due to jump")
        else:
            if self.isAirborne == 0:
                assert self.debugPrint(
                    "isAirborne 1 due to isOnGround() false")
            self.isAirborne = 1

        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        # How far did we move based on the amount of time elapsed?
        self.__oldDt = ClockObject.getGlobalClock().getDt()
        dt = self.__oldDt

        # Check to see if we're moving at all:
        self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (
            self.priorParent != Vec3.zero())
        if self.moving:
            distance = dt * self.speed
            slideDistance = dt * self.slideSpeed
            rotation = dt * self.rotationSpeed

            # Take a step in the direction of our previous heading.
            if distance or slideDistance or self.priorParent != Vec3.zero():
                # rotMat is the rotation matrix corresponding to
                # our previous heading.
                rotMat = Mat3.rotateMatNormaxis(self.avatarNodePath.getH(),
                                                Vec3.up())
                if self.isAirborne:
                    forward = Vec3.forward()
                else:
                    contact = self.lifter.getContactNormal()
                    forward = contact.cross(Vec3.right())
                    # Consider commenting out this normalize.  If you do so
                    # then going up and down slops is a touch slower and
                    # steeper terrain can cut the movement in half.  Without
                    # the normalize the movement is slowed by the cosine of
                    # the slope (i.e. it is multiplied by the sign as a
                    # side effect of the cross product above).
                    forward.normalize()
                self.vel = Vec3(forward * distance)
                if slideDistance:
                    if self.isAirborne:
                        right = Vec3.right()
                    else:
                        right = forward.cross(contact)
                        # See note above for forward.normalize()
                        right.normalize()
                    self.vel = Vec3(self.vel + (right * slideDistance))
                self.vel = Vec3(rotMat.xform(self.vel))
                step = self.vel + (self.priorParent * dt)
                self.avatarNodePath.setFluidPos(
                    Point3(self.avatarNodePath.getPos() + step))
            self.avatarNodePath.setH(self.avatarNodePath.getH() + rotation)
        else:
            self.vel.set(0.0, 0.0, 0.0)
        if self.moving or jump:
            messenger.send("avatarMoving")
        return Task.cont
示例#11
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the "avatar" (ship).
        """
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.append("localAvatar pos = %s\n"%(
                    base.localAvatar.getPos().pPrintValues(),))
                onScreenDebug.append("localAvatar hpr = %s\n"%(
                    base.localAvatar.getHpr().pPrintValues(),))
        assert self.debugPrint("handleAvatarControls(task=%s)"%(task,))
        physObject = self.actorNode.getPhysicsObject()
        contact = self.actorNode.getContactVector()
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("slideLeft") or inputState.isSet("turnLeft")
        turnRight = inputState.isSet("slideRight") or inputState.isSet("turnRight")
        slide = inputState.isSet("slide")
        slideLeft = 0
        slideRight = 0
        jump = inputState.isSet("jump")
        # Determine what the speeds are based on the buttons:

        # Check for Auto-Sailing
        if self.ship.getIsAutoSailing():
            forward = 1
            reverse = 0
        else:
            forward = 0
            
        # How far did we move based on the amount of time elapsed?
        dt = ClockObject.getGlobalClock().getDt()
        
        if reverse or turnLeft or turnRight or not forward:
            # Reset Straight Sailing Bonus
            self.straightHeading = 0
        else:
            # Add in the Straight Sailing Time
            self.straightHeading += dt
            
        # Straight Sailing Acceleration Bonus
        straightSailBonus = 0.0
        #if self.straightHeading > self.STRAIGHT_SAIL_BONUS_TIME * 0.333:
        #    straightSailBonus = (self.straightHeading - (self.STRAIGHT_SAIL_BONUS_TIME * 0.333)) / self.STRAIGHT_SAIL_BONUS_TIME * 0.666
        if self.straightHeading > (self.STRAIGHT_SAIL_BONUS_TIME * 0.5):
            straightSailBonus = (self.straightHeading - (self.STRAIGHT_SAIL_BONUS_TIME * 0.5)) / self.STRAIGHT_SAIL_BONUS_TIME * 0.5
        straightSailBonus = min(self.MAX_STRAIGHT_SAIL_BONUS, straightSailBonus * self.MAX_STRAIGHT_SAIL_BONUS)
        straightSailBonus += 1.0
        
        self.__speed=(forward and self.ship.acceleration * straightSailBonus) or \
                      (reverse and -self.ship.reverseAcceleration)
            
        avatarSlideSpeed=self.ship.acceleration *0.5 * straightSailBonus
        #self.__slideSpeed=slide and (
        #        (turnLeft and -avatarSlideSpeed) or
        #        (turnRight and avatarSlideSpeed))
        self.__slideSpeed=(forward or reverse) and (
                (slideLeft and -avatarSlideSpeed) or
                (slideRight and avatarSlideSpeed))
        self.__rotationSpeed=not slide and (
                (turnLeft and self.ship.turnRate) or
                (turnRight and -self.ship.turnRate))
        
        # Add in Straight Sailing Multiplier
        self.__speed *= straightSailBonus
        self.__slideSpeed *= straightSailBonus
        maxSpeed = self.ship.maxSpeed * straightSailBonus
        
        # Enable debug turbo modec
        debugRunning = inputState.isSet("debugRunning")
        if(debugRunning):
            self.__speed*=base.debugRunningMultiplier
            self.__slideSpeed*=base.debugRunningMultiplier
            self.__rotationSpeed*=1.25
            maxSpeed = self.ship.maxSpeed * base.debugRunningMultiplier

        #*#
        self.currentTurning += self.__rotationSpeed
        if self.currentTurning > self.ship.maxTurn:
            self.currentTurning = self.ship.maxTurn
        elif self.currentTurning < -self.ship.maxTurn:
            self.currentTurning = -self.ship.maxTurn
        if turnLeft or turnRight:
            mult = .9
        elif forward or reverse:
            mult = .82
        else:
            mult = .8
        self.currentTurning *= mult
        if self.currentTurning < 0.001 and self.currentTurning > -0.001:
            self.currentTurning = 0.0
        self.__rotationSpeed = self.currentTurning

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0

        #------------------------------
        #debugTempH=self.shipNodePath.getH()
        if __debug__:
            q1=self.shipNodePath.getQuat()
            q2=physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr())
        assert self.shipNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)
        #------------------------------

        # Check to see if we're moving at all:
        physVel = physObject.getVelocity()
        physVelLen = physVel.length()
        if (not physVel.almostEqual(Vec3(0),0.1)
            or self.__speed
            or self.__slideSpeed
            or self.__rotationSpeed):
            # don't factor in dt, the physics system will do that
            distance = self.__speed #dt * self.__speed
            goForward = True
            if (distance < 0):
                goForward = False
            slideDistance = self.__slideSpeed
            rotation = self.__rotationSpeed
            if debugRunning:
                rotation *= 4

            # update pos:
            # Take a step in the direction of our previous heading.
            self.__vel=Vec3(
                Vec3.forward() * distance +
                Vec3.right() * slideDistance)

            # rotMat is the rotation matrix corresponding to
            # our previous heading.
            rotMat=Mat3.rotateMatNormaxis(
                self.shipNodePath.getH(), Vec3.up())
            step=rotMat.xform(self.__vel)

            #newVector = self.acForce.getLocalVector()+Vec3(step)
            newVector = Vec3(step)
            #newVector=Vec3(rotMat.xform(newVector))
            #maxLen = maxSpeed
            if (goForward):
                maxLen = self.ship.acceleration * straightSailBonus
            else:
                maxLen = self.ship.reverseAcceleration

            if newVector.length() > maxLen and \
               not (debugRunning or base.localAvatar.getTurbo()):
                newVector.normalize()
                newVector *= maxLen
                
            if __debug__:
                onScreenDebug.add(
                    "newVector", newVector)
                onScreenDebug.add(
                    "newVector length", newVector.length())

            base.controlForce.setVector(newVector)

            assert base.controlForce.getLocalVector() == newVector,'1'
            assert base.controlForce.getPhysicsObject(),'2'
            assert base.controlForce.getPhysicsObject() == physObject,'3'

            #momentum = self.momentumForce.getLocalVector()
            #momentum *= 0.9
            #self.momentumForce.setVector(momentum)

            # update hpr:
            o=physObject.getOrientation()
            r=LRotationf()
            # factor in dt since we're directly setting the rotation here
            r.setHpr(Vec3(rotation * dt, 0.0, 0.0))
            physObject.setOrientation(o*r)

            # sync the change:
            self.actorNode.updateTransform()
            #assert self.shipNodePath.getH()==debugTempH-rotation
            messenger.send("avatarMoving")
        else:
            # even if there are no active inputs, we still might be moving
            assert physObject.getVelocity().almostEqual(Vec3(0),0.1)
            #base.controlForce.setVector(Vec3.zero())
            goForward = True


        #*#
        speed = physVel
        if (goForward):
            if physVelLen > maxSpeed:
                speed.normalize()
                speed *= maxSpeed
        else:
            if physVelLen > self.ship.maxReverseSpeed:
                speed.normalize()
                speed *= self.ship.maxReverseSpeed

        #speed *= 1.0 - dt * 0.05

        # modify based on sail damage
        speed *= self.ship.Sp
        speed /= self.ship.maxSp

        if __debug__:
            q1=self.shipNodePath.getQuat()
            q2=physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr()
        assert self.shipNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)

        # Clear the contact vector so we can
        # tell if we contact something next frame
        self.actorNode.setContactVector(Vec3.zero())

        oldPosDelta = self.shipNodePath.getPosDelta(render)
        oldDt = dt
        assert hasattr(self.ship, 'worldVelocity')
        if oldDt:
            self.ship.worldVelocity = oldPosDelta*(1/oldDt)
        if self.wantDebugIndicator:
            onScreenDebug.add("w __oldPosDelta vec",
                oldPosDelta.pPrintValues())
            onScreenDebug.add("w __oldPosDelta len",
                "% 10.4f"%oldPosDelta.length())
            onScreenDebug.add("w __oldDt",
                "% 10.4f"%oldDt)
            onScreenDebug.add("w worldVelocity vec",
                self.ship.worldVelocity.pPrintValues())
            onScreenDebug.add("w worldVelocity len",
                "% 10.4f"%self.ship.worldVelocity.length())

        # if hasattr(self.ship, 'sailBillow'):
        #     self.ship.sailBillow = self.sailsDeployed

        if hasattr(self.ship, 'currentTurning'):
            self.ship.currentTurning = self.currentTurning

        return Task.cont
示例#12
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.append("localAvatar pos = %s\n"%(
                    base.localAvatar.getPos().pPrintValues(),))
                onScreenDebug.append("localAvatar hpr = %s\n"%(
                    base.localAvatar.getHpr().pPrintValues(),))
        #assert self.debugPrint("handleAvatarControls(task=%s)"%(task,))
        physObject=self.actorNode.getPhysicsObject()
        contact=self.actorNode.getContactVector()
        
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("slideLeft") or inputState.isSet("turnLeft")
        turnRight = inputState.isSet("slideRight") or inputState.isSet("turnRight")
        slide = inputState.isSet("slide")
        slideLeft = 0
        slideRight = 0
        jump = inputState.isSet("jump")
        # Determine what the speeds are based on the buttons:
        
        # Check for Auto-Sailing
        if self.ship.getIsAutoSailing():
            forward = 1
            reverse = 0
            
        # How far did we move based on the amount of time elapsed?
        dt=ClockObject.getGlobalClock().getDt()
        
        if reverse or turnLeft or turnRight:
            # Reset Straight Sailing Bonus
            self.straightHeading = 0
            
        # Straight Sailing Acceleration Bonus
        straightSailDt += dt
        straightSailBonus = 0.0
        if straightSailDt > self.STRAIGHT_SAIL_BONUS_TIME / 2.0:
            straightSailBonus = (straightSailDt - (self.STRAIGHT_SAIL_BONUS_TIME / 2.0)) / self.STRAIGHT_SAIL_BONUS_TIME / 2.0
        straightSailBonus *= self.MAX_STRAIGHT_SAIL_BONUS
        straightSailBonus += 1.0

        print "##################"
        print straightSailBonus
        
        # this was causing the boat to get stuck moving forward or back
        if 0:
            if not hasattr(self, "sailsDeployed"):
                self.sailsDeployed = 0.0
            if forward and reverse:
                # Way anchor:
                self.__speed = 0.0
                physObject.setVelocity(Vec3.zero())
            elif forward:
                self.sailsDeployed += 0.25
                if self.sailsDeployed > 1.0:
                    self.sailsDeployed = 1.0
            elif reverse:
                self.sailsDeployed -= 0.25
                if self.sailsDeployed < -1.0:
                    self.sailsDeployed = -1.0
            self.__speed = self.ship.acceleration * self.sailsDeployed
        else:
            self.__speed=(forward and self.ship.acceleration) or \
                (reverse and -self.ship.reverseAcceleration)
            #self.__speed=(forward and min(dt*(self.__speed + self.ship.acceleration), self.ship.maxSpeed) or
            #        reverse and min(dt*(self.__speed - self.ship.reverseAcceleration), self.ship.maxReverseSpeed))
            
        avatarSlideSpeed=self.ship.acceleration*0.5
        #self.__slideSpeed=slide and (
        #        (turnLeft and -avatarSlideSpeed) or
        #        (turnRight and avatarSlideSpeed))
        self.__slideSpeed=(forward or reverse) and (
                (slideLeft and -avatarSlideSpeed) or
                (slideRight and avatarSlideSpeed))
        self.__rotationSpeed=not slide and (
                (turnLeft and self.ship.turnRate) or
                (turnRight and -self.ship.turnRate))

        # Add in Straight Sailing Multiplier
        self.__speed *= straightSailBonus
         
        # Enable debug turbo mode
        maxSpeed = self.ship.maxSpeed * straightSailBonus
        debugRunning = inputState.isSet("debugRunning")
        if debugRunning or base.localAvatar.getTurbo():
            self.__speed*=4.0
            self.__slideSpeed*=4.0
            self.__rotationSpeed*=1.25
            maxSpeed = self.ship.maxSpeed * 4.0

        #self.__speed*=4.0
        #self.__slideSpeed*=4.0
        #self.__rotationSpeed*=1.25
        #maxSpeed = self.ship.maxSpeed * 4.0
        
        #*#
        self.currentTurning += self.__rotationSpeed
        if self.currentTurning > self.ship.maxTurn:
            self.currentTurning = self.ship.maxTurn
        elif self.currentTurning < -self.ship.maxTurn:
            self.currentTurning = -self.ship.maxTurn
        if turnLeft or turnRight:
            mult = .9
        elif forward or reverse:
            mult = .82
        else:
            mult = .8
        self.currentTurning *= mult
        if self.currentTurning < 0.001 and self.currentTurning > -0.001:
            self.currentTurning = 0.0
        self.__rotationSpeed = self.currentTurning


        if self.wantDebugIndicator:
            self.displayDebugInfo()

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0

        airborneHeight=self.getAirborneHeight()
        if airborneHeight > self.highMark:
            self.highMark = airborneHeight
            if __debug__:
                onScreenDebug.add("highMark", "% 10.4f"%(self.highMark,))
        #if airborneHeight < 0.1: #contact!=Vec3.zero():
        if 1:
            if (airborneHeight > self.avatarRadius*0.5
                    or physObject.getVelocity().getZ() > 0.0
                    ): # Check stair angles before changing this.
                # The avatar is airborne (maybe a lot or a tiny amount).
                self.isAirborne = 1
            else:
                # The avatar is very close to the ground (close
                # enough to be considered on the ground).
                if self.isAirborne and physObject.getVelocity().getZ() <= 0.0:
                    # the avatar has landed.
                    contactLength = contact.length()
                    if contactLength>self.__hardLandingForce:
                        messenger.send("shipJumpHardLand")
                    else:
                        messenger.send("shipJumpLand")
                    #self.priorParent.setVector(Vec3.zero())
                    self.isAirborne = 0
                elif jump:
                    #self.__jumpButton=0
                    messenger.send("shipJumpStart")
                    if 0:
                        # Jump away from walls and with with the slope normal.
                        jumpVec=Vec3(contact+Vec3.up())
                        #jumpVec=Vec3(rotAvatarToPhys.xform(jumpVec))
                        jumpVec.normalize()
                    else:
                        # Jump straight up, even if next to a wall.
                        jumpVec=Vec3.up()
                    jumpVec*=self.avatarControlJumpForce
                    physObject.addImpulse(Vec3(jumpVec))
                    self.isAirborne = 1 # Avoid double impulse before fully airborne.
                else:
                    self.isAirborne = 0
            if __debug__:
                onScreenDebug.add("isAirborne", "%d"%(self.isAirborne,))
        else:
            if contact!=Vec3.zero():
                # The avatar has touched something (but might
                # not be on the ground).
                contactLength = contact.length()
                contact.normalize()
                angle=contact.dot(Vec3.up())
                if angle>self.__standableGround:
                    # ...avatar is on standable ground.
                    if self.__oldContact==Vec3.zero():
                    #if self.__oldAirborneHeight > 0.1: #self.__oldContact==Vec3.zero():
                        # ...avatar was airborne.
                        self.jumpCount-=1
                        if contactLength>self.__hardLandingForce:
                            messenger.send("jumpHardLand")
                        else:
                            messenger.send("jumpLand")
                    elif jump:
                        self.jumpCount+=1
                        #self.__jumpButton=0
                        messenger.send("jumpStart")
                        jump=Vec3(contact+Vec3.up())
                        #jump=Vec3(rotAvatarToPhys.xform(jump))
                        jump.normalize()
                        jump*=self.avatarControlJumpForce
                        physObject.addImpulse(Vec3(jump))

        if contact!=self.__oldContact:
            # We must copy the vector to preserve it:
            self.__oldContact=Vec3(contact)
        self.__oldAirborneHeight=airborneHeight

        #------------------------------
        #debugTempH=self.avatarNodePath.getH()
        if __debug__:
            q1=self.avatarNodePath.getQuat()
            q2=physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr())
        assert self.avatarNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)
        #------------------------------

        # Check to see if we're moving at all:
        physVel = physObject.getVelocity()
        physVelLen = physVel.length()
        if (physVelLen!=0.
                or self.__speed
                or self.__slideSpeed
                or self.__rotationSpeed):
            distance = dt * self.__speed
            goForward = True
            if (distance < 0):
                goForward = False
            slideDistance = dt * self.__slideSpeed
            rotation = dt * self.__rotationSpeed

            # update pos:
            # Take a step in the direction of our previous heading.
            self.__vel=Vec3(
                Vec3.forward() * distance +
                Vec3.right() * slideDistance)

            # rotMat is the rotation matrix corresponding to
            # our previous heading.
            rotMat=Mat3.rotateMatNormaxis(
                self.avatarNodePath.getH(), Vec3.up())
            step=rotMat.xform(self.__vel)

            #newVector = self.acForce.getLocalVector()+Vec3(step)
            newVector = Vec3(step)
            #newVector=Vec3(rotMat.xform(newVector))
            #maxLen = maxSpeed
            if (goForward):
                maxLen = self.ship.acceleration
            else:
                maxLen = self.ship.reverseAcceleration
            if newVector.length() > maxLen:
                newVector.normalize()
                newVector *= maxLen


            if __debug__:
                onScreenDebug.add(
                    "newVector", newVector)
                onScreenDebug.add(
                    "newVector length", newVector.length())
            base.controlForce.setVector(newVector)
            assert base.controlForce.getLocalVector() == newVector
            assert base.controlForce.getPhysicsObject()
            assert base.controlForce.getPhysicsObject() == physObject


            #momentum = self.momentumForce.getLocalVector()
            #momentum *= 0.9
            #self.momentumForce.setVector(momentum)

            # update hpr:
            o=physObject.getOrientation()
            r=LRotationf()
            r.setHpr(Vec3(rotation, 0.0, 0.0))
            physObject.setOrientation(o*r)

            # sync the change:
            self.actorNode.updateTransform()
            #assert self.avatarNodePath.getH()==debugTempH-rotation
            messenger.send("avatarMoving")
        else:
            # even if there are no active inputs, we still might be moving
            assert physObject.getVelocity().length() == 0.
            #base.controlForce.setVector(Vec3.zero())
            goForward = True


        #*#
        speed = physVel
        if (goForward):
            if physVelLen > maxSpeed:
                speed.normalize()
                speed *= maxSpeed
        else:
            if physVelLen > self.ship.maxReverseSpeed:
                speed.normalize()
                speed *= self.ship.maxReverseSpeed

        #speed *= 1.0 - dt * 0.05

        # modify based on sail damage
        speed *= self.ship.Sp
        speed /= self.ship.maxSp
        ## physObject.setVelocity(speed)

        #rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
        #speed=rotMat.xform(speed)
        # The momentumForce makes it feel like we are sliding on ice -- Joe
        # f = Vec3(self.__vel)
        # f.normalize()
        # self.momentumForce.setVector(Vec3(f*(speed.length()*0.9)))


        if __debug__:
            q1=self.avatarNodePath.getQuat()
            q2=physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr()
        assert self.avatarNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)

        # Clear the contact vector so we can
        # tell if we contact something next frame
        self.actorNode.setContactVector(Vec3.zero())

        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        self.__oldDt = dt
        assert hasattr(self.ship, 'worldVelocity')
        self.ship.worldVelocity = self.__oldPosDelta*(1/self.__oldDt)
        if self.wantDebugIndicator:
            onScreenDebug.add("w __oldPosDelta vec",
                self.__oldPosDelta.pPrintValues())
            onScreenDebug.add("w __oldPosDelta len",
                "% 10.4f"%self.__oldPosDelta.length())
            onScreenDebug.add("w __oldDt",
                "% 10.4f"%self.__oldDt)
            onScreenDebug.add("w worldVelocity vec",
                self.ship.worldVelocity.pPrintValues())
            onScreenDebug.add("w worldVelocity len",
                "% 10.4f"%self.ship.worldVelocity.length())

        # if hasattr(self.ship, 'sailBillow'):
        #     self.ship.sailBillow = self.sailsDeployed

        if hasattr(self.ship, 'currentTurning'):
            self.ship.currentTurning = self.currentTurning

        return Task.cont
示例#13
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        # get the button states:
        run = inputState.isSet("run")
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("turnLeft")
        turnRight = inputState.isSet("turnRight")
        slideLeft = inputState.isSet("slideLeft")
        slideRight = inputState.isSet("slideRight")
        jump = inputState.isSet("jump")
        
        # Check for Auto-Run
        if base.localAvatar.getAutoRun():
            forward = 1
            reverse = 0
        
        # Determine what the speeds are based on the buttons:
        self.speed=(forward and self.avatarControlForwardSpeed or
                    reverse and -self.avatarControlReverseSpeed)
        # Slide speed is a scaled down version of forward speed
        self.slideSpeed=(slideLeft and -self.avatarControlForwardSpeed or
                         slideRight and self.avatarControlForwardSpeed) * 0.5
        self.rotationSpeed=not (slideLeft or slideRight) and (
                (turnLeft and self.avatarControlRotateSpeed) or
                (turnRight and -self.avatarControlRotateSpeed))

        debugRunning = inputState.isSet("debugRunning")

        if(debugRunning):
            self.speed*=base.debugRunningMultiplier
            self.slideSpeed*=base.debugRunningMultiplier
            self.rotationSpeed*=1.25
            
        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0
        if self.wantDebugIndicator:
            self.displayDebugInfo()
        if self.lifter.isOnGround():
            if self.isAirborne:
                self.isAirborne = 0
                assert self.debugPrint("isAirborne 0 due to isOnGround() true")
                impact = self.lifter.getImpactVelocity()
                if impact < -30.0:
                    messenger.send("jumpHardLand")
                    self.startJumpDelay(0.3)
                else:
                    messenger.send("jumpLand")
                    if impact < -5.0:
                        self.startJumpDelay(0.2)
                    # else, ignore the little potholes.
            assert self.isAirborne == 0
            self.priorParent = Vec3.zero()
            if jump and self.mayJump:
                # The jump button is down and we're close
                # enough to the ground to jump.
                self.lifter.addVelocity(self.avatarControlJumpForce)
                messenger.send("jumpStart")
                self.isAirborne = 1
                assert self.debugPrint("isAirborne 1 due to jump")
        else:
            if self.isAirborne == 0:
                assert self.debugPrint("isAirborne 1 due to isOnGround() false")
            self.isAirborne = 1

        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        # How far did we move based on the amount of time elapsed?
        self.__oldDt = ClockObject.getGlobalClock().getDt()
        dt=self.__oldDt

        # Check to see if we're moving at all:
        self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero())
        if self.moving:
            distance = dt * self.speed
            slideDistance = dt * self.slideSpeed
            rotation = dt * self.rotationSpeed

            # Take a step in the direction of our previous heading.
            if distance or slideDistance or self.priorParent != Vec3.zero():
                # rotMat is the rotation matrix corresponding to
                # our previous heading.
                rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                if self.isAirborne:
                    forward = Vec3.forward()
                else:
                    contact = self.lifter.getContactNormal()
                    forward = contact.cross(Vec3.right())
                    # Consider commenting out this normalize.  If you do so
                    # then going up and down slops is a touch slower and
                    # steeper terrain can cut the movement in half.  Without
                    # the normalize the movement is slowed by the cosine of
                    # the slope (i.e. it is multiplied by the sign as a
                    # side effect of the cross product above).
                    forward.normalize()
                self.vel=Vec3(forward * distance)
                if slideDistance:
                    if self.isAirborne:
                        right = Vec3.right()
                    else:
                        right = forward.cross(contact)
                        # See note above for forward.normalize()
                        right.normalize()
                    self.vel=Vec3(self.vel + (right * slideDistance))
                self.vel=Vec3(rotMat.xform(self.vel))
                step=self.vel + (self.priorParent * dt)
                self.avatarNodePath.setFluidPos(Point3(
                        self.avatarNodePath.getPos()+step))
            self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
        else:
            self.vel.set(0.0, 0.0, 0.0)
        if self.moving or jump:
            messenger.send("avatarMoving")
        return Task.cont
示例#14
0
        def handleAvatarControls(self, task):
            # If targetNp is not available, revert back to GravityWalker.handleAvatarControls.
            # This situation occurs when the target dies, but we aren't switched out of
            # battle walker control mode.

            targetNp = self.avatarNodePath.currentTarget
            if not BattleStrafe or targetNp == None or targetNp.isEmpty():
                return GravityWalker.GravityWalker.handleAvatarControls(self, task)

            # get the button states:
            run = inputState.isSet("run")
            forward = inputState.isSet("forward")
            reverse = inputState.isSet("reverse")
            turnLeft = inputState.isSet("turnLeft")
            turnRight = inputState.isSet("turnRight")
            slide = inputState.isSet("slide")
            jump = inputState.isSet("jump")
            # Determine what the speeds are based on the buttons:
            self.advanceSpeed=(forward and self.avatarControlForwardSpeed or
                               reverse and -self.avatarControlReverseSpeed)
            if run and self.advanceSpeed>0.0:
                self.advanceSpeed*=2.0 #*#
            # Should fSlide be renamed slideButton?
            self.slideSpeed=.15*(turnLeft and -self.avatarControlForwardSpeed or
                                 turnRight and self.avatarControlForwardSpeed)
            print 'slideSpeed: ', self.slideSpeed
            self.rotationSpeed=0
            self.speed=0

            debugRunning = inputState.isSet("debugRunning")
            if debugRunning:
                self.advanceSpeed*=4.0
                self.slideSpeed*=4.0
                self.rotationSpeed*=1.25

            if self.needToDeltaPos:
                self.setPriorParentVector()
                self.needToDeltaPos = 0
            if self.wantDebugIndicator:
                self.displayDebugInfo()
            if self.lifter.isOnGround():
                if self.isAirborne:
                    self.isAirborne = 0
                    assert self.debugPrint("isAirborne 0 due to isOnGround() true")
                    impact = self.lifter.getImpactVelocity()
                    if impact < -30.0:
                        messenger.send("jumpHardLand")
                        self.startJumpDelay(0.3)
                    else:
                        messenger.send("jumpLand")
                        if impact < -5.0:
                            self.startJumpDelay(0.2)
                        # else, ignore the little potholes.
                assert self.isAirborne == 0
                self.priorParent = Vec3.zero()
                if jump and self.mayJump:
                    # The jump button is down and we're close
                    # enough to the ground to jump.
                    self.lifter.addVelocity(self.avatarControlJumpForce)
                    messenger.send("jumpStart")
                    self.isAirborne = 1
                    assert self.debugPrint("isAirborne 1 due to jump")
            else:
                if self.isAirborne == 0:
                    assert self.debugPrint("isAirborne 1 due to isOnGround() false")
                self.isAirborne = 1

            self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
            # How far did we move based on the amount of time elapsed?
            self.__oldDt = ClockObject.getGlobalClock().getDt()
            dt=self.__oldDt

            # Before we do anything with position or orientation, make the avatar
            # face it's target.  Only allow rMax degrees rotation per frame, so
            # we don't get an unnatural spinning effect
            curH = self.avatarNodePath.getH()
            self.avatarNodePath.headsUp(targetNp)
            newH = self.avatarNodePath.getH()
            delH = reduceAngle(newH-curH)
            rMax = 10
            if delH < -rMax:
                self.avatarNodePath.setH(curH-rMax)
                self.rotationSpeed=-self.avatarControlRotateSpeed
            elif delH > rMax:
                self.avatarNodePath.setH(curH+rMax)
                self.rotationSpeed=self.avatarControlRotateSpeed

            # Check to see if we're moving at all:
            self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero())
            if self.moving:
                distance = dt * self.speed
                slideDistance = dt * self.slideSpeed
                print 'slideDistance: ', slideDistance
                rotation = dt * self.rotationSpeed

                # Take a step in the direction of our previous heading.
                self.vel=Vec3(Vec3.forward() * distance +
                              Vec3.right() * slideDistance)
                if self.vel != Vec3.zero() or self.priorParent != Vec3.zero():
                    if 1:
                        # rotMat is the rotation matrix corresponding to
                        # our previous heading.
                        rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                        step=(self.priorParent * dt) + rotMat.xform(self.vel)
                        self.avatarNodePath.setFluidPos(Point3(
                                self.avatarNodePath.getPos()+step))
                self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
            else:
                self.vel.set(0.0, 0.0, 0.0)

            """
            # Check to see if we're moving at all:
            self.moving = self.advanceSpeed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero())
            if self.moving:
                distance = dt * self.advanceSpeed
                slideDistance = dt * self.slideSpeed
                rotation = dt * self.rotationSpeed

                # Prevent avatar from getting too close to target
                d = self.avatarNodePath.getPos(targetNp)
                # TODO:  make min distance adjust for current weapon
                if (d[0]*d[0]+d[1]*d[1] < 6.0 and distance > 0):
                    # move the avatar sideways instead of forward
                    slideDistance += .2
                    distance = 0

                # Take a step in the direction of our previous heading.
                self.vel=Vec3(Vec3.forward() * distance +
                              Vec3.right() * slideDistance)
                if self.vel != Vec3.zero() or self.priorParent != Vec3.zero():
                    # rotMat is the rotation matrix corresponding to
                    # our previous heading.
                    rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                    step=rotMat.xform(self.vel) + (self.priorParent * dt)
                    self.avatarNodePath.setFluidPos(Point3(
                        self.avatarNodePath.getPos()+step))
                self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
            else:
                self.vel.set(0.0, 0.0, 0.0)
            """
            if self.moving or jump:
                messenger.send("avatarMoving")
            return Task.cont
示例#15
0
        def handleAvatarControls(self, task):
            # If targetNp is not available, revert back to GravityWalker.handleAvatarControls.
            # This situation occurs when the target dies, but we aren't switched out of
            # battle walker control mode.

            targetNp = self.avatarNodePath.currentTarget
            if not BattleStrafe or targetNp == None or targetNp.isEmpty():
                return GravityWalker.GravityWalker.handleAvatarControls(
                    self, task)

            # get the button states:
            run = inputState.isSet("run")
            forward = inputState.isSet("forward")
            reverse = inputState.isSet("reverse")
            turnLeft = inputState.isSet("turnLeft")
            turnRight = inputState.isSet("turnRight")
            slide = inputState.isSet("slide")
            jump = inputState.isSet("jump")
            # Determine what the speeds are based on the buttons:
            self.advanceSpeed = (forward and self.avatarControlForwardSpeed or
                                 reverse and -self.avatarControlReverseSpeed)
            if run and self.advanceSpeed > 0.0:
                self.advanceSpeed *= 2.0  #*#
            # Should fSlide be renamed slideButton?
            self.slideSpeed = .15 * (
                turnLeft and -self.avatarControlForwardSpeed
                or turnRight and self.avatarControlForwardSpeed)
            print 'slideSpeed: ', self.slideSpeed
            self.rotationSpeed = 0
            self.speed = 0

            debugRunning = inputState.isSet("debugRunning")
            if debugRunning:
                self.advanceSpeed *= 4.0
                self.slideSpeed *= 4.0
                self.rotationSpeed *= 1.25

            if self.needToDeltaPos:
                self.setPriorParentVector()
                self.needToDeltaPos = 0
            if self.wantDebugIndicator:
                self.displayDebugInfo()
            if self.lifter.isOnGround():
                if self.isAirborne:
                    self.isAirborne = 0
                    assert self.debugPrint(
                        "isAirborne 0 due to isOnGround() true")
                    impact = self.lifter.getImpactVelocity()
                    if impact < -30.0:
                        messenger.send("jumpHardLand")
                        self.startJumpDelay(0.3)
                    else:
                        messenger.send("jumpLand")
                        if impact < -5.0:
                            self.startJumpDelay(0.2)
                        # else, ignore the little potholes.
                assert self.isAirborne == 0
                self.priorParent = Vec3.zero()
                if jump and self.mayJump:
                    # The jump button is down and we're close
                    # enough to the ground to jump.
                    self.lifter.addVelocity(self.avatarControlJumpForce)
                    messenger.send("jumpStart")
                    self.isAirborne = 1
                    assert self.debugPrint("isAirborne 1 due to jump")
            else:
                if self.isAirborne == 0:
                    assert self.debugPrint(
                        "isAirborne 1 due to isOnGround() false")
                self.isAirborne = 1

            self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
            # How far did we move based on the amount of time elapsed?
            self.__oldDt = ClockObject.getGlobalClock().getDt()
            dt = self.__oldDt

            # Before we do anything with position or orientation, make the avatar
            # face it's target.  Only allow rMax degrees rotation per frame, so
            # we don't get an unnatural spinning effect
            curH = self.avatarNodePath.getH()
            self.avatarNodePath.headsUp(targetNp)
            newH = self.avatarNodePath.getH()
            delH = reduceAngle(newH - curH)
            rMax = 10
            if delH < -rMax:
                self.avatarNodePath.setH(curH - rMax)
                self.rotationSpeed = -self.avatarControlRotateSpeed
            elif delH > rMax:
                self.avatarNodePath.setH(curH + rMax)
                self.rotationSpeed = self.avatarControlRotateSpeed

            # Check to see if we're moving at all:
            self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (
                self.priorParent != Vec3.zero())
            if self.moving:
                distance = dt * self.speed
                slideDistance = dt * self.slideSpeed
                print 'slideDistance: ', slideDistance
                rotation = dt * self.rotationSpeed

                # Take a step in the direction of our previous heading.
                self.vel = Vec3(Vec3.forward() * distance +
                                Vec3.right() * slideDistance)
                if self.vel != Vec3.zero() or self.priorParent != Vec3.zero():
                    if 1:
                        # rotMat is the rotation matrix corresponding to
                        # our previous heading.
                        rotMat = Mat3.rotateMatNormaxis(
                            self.avatarNodePath.getH(), Vec3.up())
                        step = (self.priorParent * dt) + rotMat.xform(self.vel)
                        self.avatarNodePath.setFluidPos(
                            Point3(self.avatarNodePath.getPos() + step))
                self.avatarNodePath.setH(self.avatarNodePath.getH() + rotation)
            else:
                self.vel.set(0.0, 0.0, 0.0)
            """
            # Check to see if we're moving at all:
            self.moving = self.advanceSpeed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero())
            if self.moving:
                distance = dt * self.advanceSpeed
                slideDistance = dt * self.slideSpeed
                rotation = dt * self.rotationSpeed

                # Prevent avatar from getting too close to target
                d = self.avatarNodePath.getPos(targetNp)
                # TODO:  make min distance adjust for current weapon
                if (d[0]*d[0]+d[1]*d[1] < 6.0 and distance > 0):
                    # move the avatar sideways instead of forward
                    slideDistance += .2
                    distance = 0

                # Take a step in the direction of our previous heading.
                self.vel=Vec3(Vec3.forward() * distance +
                              Vec3.right() * slideDistance)
                if self.vel != Vec3.zero() or self.priorParent != Vec3.zero():
                    # rotMat is the rotation matrix corresponding to
                    # our previous heading.
                    rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
                    step=rotMat.xform(self.vel) + (self.priorParent * dt)
                    self.avatarNodePath.setFluidPos(Point3(
                        self.avatarNodePath.getPos()+step))
                self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
            else:
                self.vel.set(0.0, 0.0, 0.0)
            """
            if self.moving or jump:
                messenger.send("avatarMoving")
            return Task.cont
示例#16
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the avatar.
        """
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.append(
                    "localAvatar pos = %s\n" %
                    (base.localAvatar.getPos().pPrintValues(), ))
                onScreenDebug.append(
                    "localAvatar hpr = %s\n" %
                    (base.localAvatar.getHpr().pPrintValues(), ))
        #assert self.debugPrint("handleAvatarControls(task=%s)"%(task,))
        physObject = self.actorNode.getPhysicsObject()
        contact = self.actorNode.getContactVector()

        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("slideLeft") or inputState.isSet(
            "turnLeft")
        turnRight = inputState.isSet("slideRight") or inputState.isSet(
            "turnRight")
        slide = inputState.isSet("slide")
        slideLeft = 0
        slideRight = 0
        jump = inputState.isSet("jump")
        # Determine what the speeds are based on the buttons:

        # Check for Auto-Sailing
        if self.ship.getIsAutoSailing():
            forward = 1
            reverse = 0

        # How far did we move based on the amount of time elapsed?
        dt = ClockObject.getGlobalClock().getDt()

        if reverse or turnLeft or turnRight:
            # Reset Straight Sailing Bonus
            self.straightHeading = 0

        # Straight Sailing Acceleration Bonus
        straightSailDt += dt
        straightSailBonus = 0.0
        if straightSailDt > self.STRAIGHT_SAIL_BONUS_TIME / 2.0:
            straightSailBonus = (straightSailDt -
                                 (self.STRAIGHT_SAIL_BONUS_TIME /
                                  2.0)) / self.STRAIGHT_SAIL_BONUS_TIME / 2.0
        straightSailBonus *= self.MAX_STRAIGHT_SAIL_BONUS
        straightSailBonus += 1.0

        print "##################"
        print straightSailBonus

        # this was causing the boat to get stuck moving forward or back
        if 0:
            if not hasattr(self, "sailsDeployed"):
                self.sailsDeployed = 0.0
            if forward and reverse:
                # Way anchor:
                self.__speed = 0.0
                physObject.setVelocity(Vec3.zero())
            elif forward:
                self.sailsDeployed += 0.25
                if self.sailsDeployed > 1.0:
                    self.sailsDeployed = 1.0
            elif reverse:
                self.sailsDeployed -= 0.25
                if self.sailsDeployed < -1.0:
                    self.sailsDeployed = -1.0
            self.__speed = self.ship.acceleration * self.sailsDeployed
        else:
            self.__speed=(forward and self.ship.acceleration) or \
                (reverse and -self.ship.reverseAcceleration)
            #self.__speed=(forward and min(dt*(self.__speed + self.ship.acceleration), self.ship.maxSpeed) or
            #        reverse and min(dt*(self.__speed - self.ship.reverseAcceleration), self.ship.maxReverseSpeed))

        avatarSlideSpeed = self.ship.acceleration * 0.5
        #self.__slideSpeed=slide and (
        #        (turnLeft and -avatarSlideSpeed) or
        #        (turnRight and avatarSlideSpeed))
        self.__slideSpeed = (forward or reverse) and (
            (slideLeft and -avatarSlideSpeed) or
            (slideRight and avatarSlideSpeed))
        self.__rotationSpeed = not slide and (
            (turnLeft and self.ship.turnRate) or
            (turnRight and -self.ship.turnRate))

        # Add in Straight Sailing Multiplier
        self.__speed *= straightSailBonus

        # Enable debug turbo mode
        maxSpeed = self.ship.maxSpeed * straightSailBonus
        debugRunning = inputState.isSet("debugRunning")
        if debugRunning or base.localAvatar.getTurbo():
            self.__speed *= 4.0
            self.__slideSpeed *= 4.0
            self.__rotationSpeed *= 1.25
            maxSpeed = self.ship.maxSpeed * 4.0

        #self.__speed*=4.0
        #self.__slideSpeed*=4.0
        #self.__rotationSpeed*=1.25
        #maxSpeed = self.ship.maxSpeed * 4.0

        #*#
        self.currentTurning += self.__rotationSpeed
        if self.currentTurning > self.ship.maxTurn:
            self.currentTurning = self.ship.maxTurn
        elif self.currentTurning < -self.ship.maxTurn:
            self.currentTurning = -self.ship.maxTurn
        if turnLeft or turnRight:
            mult = .9
        elif forward or reverse:
            mult = .82
        else:
            mult = .8
        self.currentTurning *= mult
        if self.currentTurning < 0.001 and self.currentTurning > -0.001:
            self.currentTurning = 0.0
        self.__rotationSpeed = self.currentTurning

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0

        airborneHeight = self.getAirborneHeight()
        if airborneHeight > self.highMark:
            self.highMark = airborneHeight
            if __debug__:
                onScreenDebug.add("highMark", "% 10.4f" % (self.highMark, ))
        #if airborneHeight < 0.1: #contact!=Vec3.zero():
        if 1:
            if (airborneHeight > self.avatarRadius * 0.5
                    or physObject.getVelocity().getZ() >
                    0.0):  # Check stair angles before changing this.
                # The avatar is airborne (maybe a lot or a tiny amount).
                self.isAirborne = 1
            else:
                # The avatar is very close to the ground (close
                # enough to be considered on the ground).
                if self.isAirborne and physObject.getVelocity().getZ() <= 0.0:
                    # the avatar has landed.
                    contactLength = contact.length()
                    if contactLength > self.__hardLandingForce:
                        messenger.send("shipJumpHardLand")
                    else:
                        messenger.send("shipJumpLand")
                    #self.priorParent.setVector(Vec3.zero())
                    self.isAirborne = 0
                elif jump:
                    #self.__jumpButton=0
                    messenger.send("shipJumpStart")
                    if 0:
                        # Jump away from walls and with with the slope normal.
                        jumpVec = Vec3(contact + Vec3.up())
                        #jumpVec=Vec3(rotAvatarToPhys.xform(jumpVec))
                        jumpVec.normalize()
                    else:
                        # Jump straight up, even if next to a wall.
                        jumpVec = Vec3.up()
                    jumpVec *= self.avatarControlJumpForce
                    physObject.addImpulse(Vec3(jumpVec))
                    self.isAirborne = 1  # Avoid double impulse before fully airborne.
                else:
                    self.isAirborne = 0
            if __debug__:
                onScreenDebug.add("isAirborne", "%d" % (self.isAirborne, ))
        else:
            if contact != Vec3.zero():
                # The avatar has touched something (but might
                # not be on the ground).
                contactLength = contact.length()
                contact.normalize()
                angle = contact.dot(Vec3.up())
                if angle > self.__standableGround:
                    # ...avatar is on standable ground.
                    if self.__oldContact == Vec3.zero():
                        #if self.__oldAirborneHeight > 0.1: #self.__oldContact==Vec3.zero():
                        # ...avatar was airborne.
                        self.jumpCount -= 1
                        if contactLength > self.__hardLandingForce:
                            messenger.send("jumpHardLand")
                        else:
                            messenger.send("jumpLand")
                    elif jump:
                        self.jumpCount += 1
                        #self.__jumpButton=0
                        messenger.send("jumpStart")
                        jump = Vec3(contact + Vec3.up())
                        #jump=Vec3(rotAvatarToPhys.xform(jump))
                        jump.normalize()
                        jump *= self.avatarControlJumpForce
                        physObject.addImpulse(Vec3(jump))

        if contact != self.__oldContact:
            # We must copy the vector to preserve it:
            self.__oldContact = Vec3(contact)
        self.__oldAirborneHeight = airborneHeight

        #------------------------------
        #debugTempH=self.avatarNodePath.getH()
        if __debug__:
            q1 = self.avatarNodePath.getQuat()
            q2 = physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr())
        assert self.avatarNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)
        #------------------------------

        # Check to see if we're moving at all:
        physVel = physObject.getVelocity()
        physVelLen = physVel.length()
        if (physVelLen != 0. or self.__speed or self.__slideSpeed
                or self.__rotationSpeed):
            distance = dt * self.__speed
            goForward = True
            if (distance < 0):
                goForward = False
            slideDistance = dt * self.__slideSpeed
            rotation = dt * self.__rotationSpeed

            # update pos:
            # Take a step in the direction of our previous heading.
            self.__vel = Vec3(Vec3.forward() * distance +
                              Vec3.right() * slideDistance)

            # rotMat is the rotation matrix corresponding to
            # our previous heading.
            rotMat = Mat3.rotateMatNormaxis(self.avatarNodePath.getH(),
                                            Vec3.up())
            step = rotMat.xform(self.__vel)

            #newVector = self.acForce.getLocalVector()+Vec3(step)
            newVector = Vec3(step)
            #newVector=Vec3(rotMat.xform(newVector))
            #maxLen = maxSpeed
            if (goForward):
                maxLen = self.ship.acceleration
            else:
                maxLen = self.ship.reverseAcceleration
            if newVector.length() > maxLen:
                newVector.normalize()
                newVector *= maxLen

            if __debug__:
                onScreenDebug.add("newVector", newVector)
                onScreenDebug.add("newVector length", newVector.length())
            base.controlForce.setVector(newVector)
            assert base.controlForce.getLocalVector() == newVector
            assert base.controlForce.getPhysicsObject()
            assert base.controlForce.getPhysicsObject() == physObject

            #momentum = self.momentumForce.getLocalVector()
            #momentum *= 0.9
            #self.momentumForce.setVector(momentum)

            # update hpr:
            o = physObject.getOrientation()
            r = LRotationf()
            r.setHpr(Vec3(rotation, 0.0, 0.0))
            physObject.setOrientation(o * r)

            # sync the change:
            self.actorNode.updateTransform()
            #assert self.avatarNodePath.getH()==debugTempH-rotation
            messenger.send("avatarMoving")
        else:
            # even if there are no active inputs, we still might be moving
            assert physObject.getVelocity().length() == 0.
            #base.controlForce.setVector(Vec3.zero())
            goForward = True

        #*#
        speed = physVel
        if (goForward):
            if physVelLen > maxSpeed:
                speed.normalize()
                speed *= maxSpeed
        else:
            if physVelLen > self.ship.maxReverseSpeed:
                speed.normalize()
                speed *= self.ship.maxReverseSpeed

        #speed *= 1.0 - dt * 0.05

        # modify based on sail damage
        speed *= self.ship.Sp
        speed /= self.ship.maxSp
        ## physObject.setVelocity(speed)

        #rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
        #speed=rotMat.xform(speed)
        # The momentumForce makes it feel like we are sliding on ice -- Joe
        # f = Vec3(self.__vel)
        # f.normalize()
        # self.momentumForce.setVector(Vec3(f*(speed.length()*0.9)))

        if __debug__:
            q1 = self.avatarNodePath.getQuat()
            q2 = physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr()
        assert self.avatarNodePath.getPos().almostEqual(
            physObject.getPosition(), 0.0001)

        # Clear the contact vector so we can
        # tell if we contact something next frame
        self.actorNode.setContactVector(Vec3.zero())

        self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
        self.__oldDt = dt
        assert hasattr(self.ship, 'worldVelocity')
        self.ship.worldVelocity = self.__oldPosDelta * (1 / self.__oldDt)
        if self.wantDebugIndicator:
            onScreenDebug.add("w __oldPosDelta vec",
                              self.__oldPosDelta.pPrintValues())
            onScreenDebug.add("w __oldPosDelta len",
                              "% 10.4f" % self.__oldPosDelta.length())
            onScreenDebug.add("w __oldDt", "% 10.4f" % self.__oldDt)
            onScreenDebug.add("w worldVelocity vec",
                              self.ship.worldVelocity.pPrintValues())
            onScreenDebug.add("w worldVelocity len",
                              "% 10.4f" % self.ship.worldVelocity.length())

        # if hasattr(self.ship, 'sailBillow'):
        #     self.ship.sailBillow = self.sailsDeployed

        if hasattr(self.ship, 'currentTurning'):
            self.ship.currentTurning = self.currentTurning

        return Task.cont
示例#17
0
    def handleAvatarControls(self, task):
        """
        Check on the arrow keys and update the "avatar" (ship).
        """
        if __debug__:
            if self.wantDebugIndicator:
                onScreenDebug.append(
                    "localAvatar pos = %s\n" %
                    (base.localAvatar.getPos().pPrintValues(), ))
                onScreenDebug.append(
                    "localAvatar hpr = %s\n" %
                    (base.localAvatar.getHpr().pPrintValues(), ))
        assert self.debugPrint("handleAvatarControls(task=%s)" % (task, ))
        physObject = self.actorNode.getPhysicsObject()
        contact = self.actorNode.getContactVector()
        # get the button states:
        forward = inputState.isSet("forward")
        reverse = inputState.isSet("reverse")
        turnLeft = inputState.isSet("slideLeft") or inputState.isSet(
            "turnLeft")
        turnRight = inputState.isSet("slideRight") or inputState.isSet(
            "turnRight")
        slide = inputState.isSet("slide")
        slideLeft = 0
        slideRight = 0
        jump = inputState.isSet("jump")
        # Determine what the speeds are based on the buttons:

        # Check for Auto-Sailing
        if self.ship.getIsAutoSailing():
            forward = 1
            reverse = 0
        else:
            forward = 0

        # How far did we move based on the amount of time elapsed?
        dt = ClockObject.getGlobalClock().getDt()

        if reverse or turnLeft or turnRight or not forward:
            # Reset Straight Sailing Bonus
            self.straightHeading = 0
        else:
            # Add in the Straight Sailing Time
            self.straightHeading += dt

        # Straight Sailing Acceleration Bonus
        straightSailBonus = 0.0
        #if self.straightHeading > self.STRAIGHT_SAIL_BONUS_TIME * 0.333:
        #    straightSailBonus = (self.straightHeading - (self.STRAIGHT_SAIL_BONUS_TIME * 0.333)) / self.STRAIGHT_SAIL_BONUS_TIME * 0.666
        if self.straightHeading > (self.STRAIGHT_SAIL_BONUS_TIME * 0.5):
            straightSailBonus = (self.straightHeading -
                                 (self.STRAIGHT_SAIL_BONUS_TIME *
                                  0.5)) / self.STRAIGHT_SAIL_BONUS_TIME * 0.5
        straightSailBonus = min(
            self.MAX_STRAIGHT_SAIL_BONUS,
            straightSailBonus * self.MAX_STRAIGHT_SAIL_BONUS)
        straightSailBonus += 1.0

        self.__speed=(forward and self.ship.acceleration * straightSailBonus) or \
                      (reverse and -self.ship.reverseAcceleration)

        avatarSlideSpeed = self.ship.acceleration * 0.5 * straightSailBonus
        #self.__slideSpeed=slide and (
        #        (turnLeft and -avatarSlideSpeed) or
        #        (turnRight and avatarSlideSpeed))
        self.__slideSpeed = (forward or reverse) and (
            (slideLeft and -avatarSlideSpeed) or
            (slideRight and avatarSlideSpeed))
        self.__rotationSpeed = not slide and (
            (turnLeft and self.ship.turnRate) or
            (turnRight and -self.ship.turnRate))

        # Add in Straight Sailing Multiplier
        self.__speed *= straightSailBonus
        self.__slideSpeed *= straightSailBonus
        maxSpeed = self.ship.maxSpeed * straightSailBonus

        # Enable debug turbo modec
        debugRunning = inputState.isSet("debugRunning")
        if (debugRunning):
            self.__speed *= base.debugRunningMultiplier
            self.__slideSpeed *= base.debugRunningMultiplier
            self.__rotationSpeed *= 1.25
            maxSpeed = self.ship.maxSpeed * base.debugRunningMultiplier

        #*#
        self.currentTurning += self.__rotationSpeed
        if self.currentTurning > self.ship.maxTurn:
            self.currentTurning = self.ship.maxTurn
        elif self.currentTurning < -self.ship.maxTurn:
            self.currentTurning = -self.ship.maxTurn
        if turnLeft or turnRight:
            mult = .9
        elif forward or reverse:
            mult = .82
        else:
            mult = .8
        self.currentTurning *= mult
        if self.currentTurning < 0.001 and self.currentTurning > -0.001:
            self.currentTurning = 0.0
        self.__rotationSpeed = self.currentTurning

        if self.wantDebugIndicator:
            self.displayDebugInfo()

        if self.needToDeltaPos:
            self.setPriorParentVector()
            self.needToDeltaPos = 0

        #------------------------------
        #debugTempH=self.shipNodePath.getH()
        if __debug__:
            q1 = self.shipNodePath.getQuat()
            q2 = physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or (q1.getHpr() == q2.getHpr())
        assert self.shipNodePath.getPos().almostEqual(physObject.getPosition(),
                                                      0.0001)
        #------------------------------

        # Check to see if we're moving at all:
        physVel = physObject.getVelocity()
        physVelLen = physVel.length()
        if (not physVel.almostEqual(Vec3(0), 0.1) or self.__speed
                or self.__slideSpeed or self.__rotationSpeed):
            # don't factor in dt, the physics system will do that
            distance = self.__speed  #dt * self.__speed
            goForward = True
            if (distance < 0):
                goForward = False
            slideDistance = self.__slideSpeed
            rotation = self.__rotationSpeed
            if debugRunning:
                rotation *= 4

            # update pos:
            # Take a step in the direction of our previous heading.
            self.__vel = Vec3(Vec3.forward() * distance +
                              Vec3.right() * slideDistance)

            # rotMat is the rotation matrix corresponding to
            # our previous heading.
            rotMat = Mat3.rotateMatNormaxis(self.shipNodePath.getH(),
                                            Vec3.up())
            step = rotMat.xform(self.__vel)

            #newVector = self.acForce.getLocalVector()+Vec3(step)
            newVector = Vec3(step)
            #newVector=Vec3(rotMat.xform(newVector))
            #maxLen = maxSpeed
            if (goForward):
                maxLen = self.ship.acceleration * straightSailBonus
            else:
                maxLen = self.ship.reverseAcceleration

            if newVector.length() > maxLen and \
               not (debugRunning or base.localAvatar.getTurbo()):
                newVector.normalize()
                newVector *= maxLen

            if __debug__:
                onScreenDebug.add("newVector", newVector)
                onScreenDebug.add("newVector length", newVector.length())

            base.controlForce.setVector(newVector)

            assert base.controlForce.getLocalVector() == newVector, '1'
            assert base.controlForce.getPhysicsObject(), '2'
            assert base.controlForce.getPhysicsObject() == physObject, '3'

            #momentum = self.momentumForce.getLocalVector()
            #momentum *= 0.9
            #self.momentumForce.setVector(momentum)

            # update hpr:
            o = physObject.getOrientation()
            r = LRotationf()
            # factor in dt since we're directly setting the rotation here
            r.setHpr(Vec3(rotation * dt, 0.0, 0.0))
            physObject.setOrientation(o * r)

            # sync the change:
            self.actorNode.updateTransform()
            #assert self.shipNodePath.getH()==debugTempH-rotation
            messenger.send("avatarMoving")
        else:
            # even if there are no active inputs, we still might be moving
            assert physObject.getVelocity().almostEqual(Vec3(0), 0.1)
            #base.controlForce.setVector(Vec3.zero())
            goForward = True

        #*#
        speed = physVel
        if (goForward):
            if physVelLen > maxSpeed:
                speed.normalize()
                speed *= maxSpeed
        else:
            if physVelLen > self.ship.maxReverseSpeed:
                speed.normalize()
                speed *= self.ship.maxReverseSpeed

        #speed *= 1.0 - dt * 0.05

        # modify based on sail damage
        speed *= self.ship.Sp
        speed /= self.ship.maxSp

        if __debug__:
            q1 = self.shipNodePath.getQuat()
            q2 = physObject.getOrientation()
            q1.normalize()
            q2.normalize()
            assert q1.isSameDirection(q2) or q1.getHpr() == q2.getHpr()
        assert self.shipNodePath.getPos().almostEqual(physObject.getPosition(),
                                                      0.0001)

        # Clear the contact vector so we can
        # tell if we contact something next frame
        self.actorNode.setContactVector(Vec3.zero())

        oldPosDelta = self.shipNodePath.getPosDelta(render)
        oldDt = dt
        assert hasattr(self.ship, 'worldVelocity')
        if oldDt:
            self.ship.worldVelocity = oldPosDelta * (1 / oldDt)
        if self.wantDebugIndicator:
            onScreenDebug.add("w __oldPosDelta vec",
                              oldPosDelta.pPrintValues())
            onScreenDebug.add("w __oldPosDelta len",
                              "% 10.4f" % oldPosDelta.length())
            onScreenDebug.add("w __oldDt", "% 10.4f" % oldDt)
            onScreenDebug.add("w worldVelocity vec",
                              self.ship.worldVelocity.pPrintValues())
            onScreenDebug.add("w worldVelocity len",
                              "% 10.4f" % self.ship.worldVelocity.length())

        # if hasattr(self.ship, 'sailBillow'):
        #     self.ship.sailBillow = self.sailsDeployed

        if hasattr(self.ship, 'currentTurning'):
            self.ship.currentTurning = self.currentTurning

        return Task.cont