I have a problem with my controller that puts things in motion, but not as desired. It seems the character jumps between the new position and the old one when I hold whatever movement direction key, as if he were shaking. I guess the problem is related to how I’m organizing my file, because somewhere below there is a piece of code that both clamps the maximum speed and decelerates when the speed is different than 0. I guess I should try to clamp the speed and decelerate separately, but how? For both mouse and keyboard input, by the way (which could be tackled by the same restructuring).
def setSpeedValues(self):
# Define static variables to be changed through the control method
self.mouseXSpeed = 0
self.mouseYSpeed = 0
self.forward = 0
self.sides = 0
self.vert = 0
self.roll = 0
def lookControl(self, task):
# Define orientation vector and rotation quaternion
# to be transformed by mouse input
self.rotateQuat = Quat()
# Let's define the new orientation through mouse coordinates
# Get mouse coordinates
md = base.win.getPointer(0)
x = md.getX()
y = md.getY()
# Centre the cursor and register its displacement in delta variables
if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
deltaX = x - base.win.getXSize()/2
deltaY = y - base.win.getYSize()/2
if (deltaX != 0):
self.mouseXSpeed = deltaX * TURN_ACCEL * MAX_TURN_SPEED * -1
if (deltaY != 0):
self.mouseYSpeed = deltaY * TURN_ACCEL * MAX_TURN_SPEED * -1
# Apply deceleration when the cursor stops moving but still carries some speed
if (self.mouseXSpeed != 0):
self.mouseXSpeed = max(min(self.mouseXSpeed, MAX_TURN_SPEED), -MAX_TURN_SPEED)
lerpSpeed = self.mouseXSpeed + (0 - self.mouseXSpeed) * TURN_DECEL
self.mouseXSpeed = max(min(lerpSpeed, 0), lerpSpeed)
if (self.mouseYSpeed != 0):
self.mouseYSpeed = max(min(self.mouseYSpeed, MAX_TURN_SPEED), -MAX_TURN_SPEED)
lerpSpeed = self.mouseYSpeed + (0 - self.mouseYSpeed) * TURN_DECEL
self.mouseYSpeed = max(min(lerpSpeed, 0), lerpSpeed)
# Transform the roll value
if (self.keyMap["roll-right"] != 0):
self.roll += ROLL_ACCEL * MAX_ROLL_SPEED
if (self.keyMap["roll-left"] != 0):
self.roll -= ROLL_ACCEL * MAX_ROLL_SPEED
# Clamp the roll value to the maximum speed values and
# interpolate with zero when the key is released
if (self.roll != 0):
self.roll = max(min(self.roll, MAX_ROLL_SPEED), -MAX_ROLL_SPEED)
lerpRoll = self.roll + (0 - self.roll) * ROLL_DECEL
self.roll = max(min(lerpRoll, 0), lerpRoll)
self.rotateQuat.setHpr(Vec3(self.mouseXSpeed, self.mouseYSpeed, self.roll))
self.character.setQuat(self.character, self.rotateQuat)
return task.cont
def moveControl(self, task):
# Move the character by incrementing speed values
# when the keys are pressed
# Transform the forward value
if (self.keyMap["forward"] != 0):
self.forward += MOVE_ACCEL * MAX_MOVE_SPEED
if (self.keyMap["backward"] != 0):
self.forward -= MOVE_ACCEL * MAX_MOVE_SPEED
if (self.keyMap["right"] != 0):
self.sides += MOVE_ACCEL * MAX_MOVE_SPEED
if (self.keyMap["left"] != 0):
self.sides -= MOVE_ACCEL * MAX_MOVE_SPEED
if (self.keyMap["up"] != 0):
self.vert += MOVE_ACCEL * MAX_MOVE_SPEED
if (self.keyMap["down"] != 0):
self.vert -= MOVE_ACCEL * MAX_MOVE_SPEED
# Clamp the forward value to the maximum speed values and
# interpolate with zero when the key is released
if (self.forward != 0):
self.forward = max(min(self.forward, MAX_MOVE_SPEED), -MAX_MOVE_SPEED)
lerpForward = self.forward + (0 - self.forward) * MOVE_DECEL
self.forward = max(min(lerpForward, 0), lerpForward)
wantVec = self.character.getQuat(render).getForward()
self.character.setPos(self.character.getPos() + wantVec * self.forward * globalClock.getDt())
if (self.sides != 0):
self.sides = max(min(self.sides, MAX_MOVE_SPEED), -MAX_MOVE_SPEED)
lerpSides = self.sides + (0 - self.sides) * MOVE_DECEL
self.sides = max(min(lerpSides, 0), lerpSides)
wantVec = self.character.getQuat(render).getRight()
self.character.setPos(self.character.getPos() + wantVec * self.sides * globalClock.getDt())
if (self.vert != 0):
self.vert = max(min(self.vert, MAX_MOVE_SPEED), -MAX_MOVE_SPEED)
lerpVert = self.vert + (0 - self.vert) * MOVE_DECEL
self.vert = max(min(lerpVert, 0), lerpVert)
wantVec = self.character.getQuat(render).getUp()
self.character.setPos(self.character.getPos() + wantVec * self.vert * globalClock.getDt())
return task.cont