Recently, I wanted to get started on making a 3d tester game with panda3d using python. However, I can't seem to mimic the mouse rotation within the environment that other popular first-person games have. Let me explain: If I move my mouse slowly over a long period of time, starting on the left side of my mousepad and moving to the right, I have to move it to about the center of the mousepad to make a full 360 degree turn within the game. However, If I move my mouse really quickly over a shorter period of time, I can make a full revolution in much less space, allowing me to make even more rotations in one mouse motion. This does not happen in games that I play daily. In popular games that I have played, mouse speed did not effect the amount turned. After testing, I attempted to set the movement delta so that it would be a flat movement each time, instead of mouse distance from the center. However, this ended up having the opposite event occurring, where moving the mouse slower over a longer period of time caused the camera to rotate more. Unfortunately, I am unable to upload clips of it occurring, but I am happy to provide the code, for other people to test it themselves. Start by looking at the box, then moving your mouse slowly over a longer period of time, counting the revolutions, and then try moving your mouse faster. I got about 2 revolutions for the slow test, and 4 for the fast one. Code: from direct.showbase.ShowBase import ShowBase from panda3d.core import CardMaker, LVector3, Vec4, NodePath, Mat3, WindowProperties from math import sin, cos, radians class WalkingGame(ShowBase): def __init__(self): global base base=self ShowBase.__init__(self) cm = CardMaker("ground") cm.setFrame(-10, 10, -10, 10) self.plane = NodePath(cm.generate()) self.plane.reparentTo(self.render) self.plane.setHpr(0, -90, 0) self.plane.setColor(Vec4(1, 1, 1, 1)) # White self.player = self.loader.loadModel("models/box") self.player.reparentTo(self.render) self.player.setScale(0.5) self.player.setPos(0, 0, 0) self.camLens.setFov(75) # Camera self.taskMgr.add(self.update_camera, "camera_task") self.taskMgr.add(self.update_movement, "move_task") self.camera.setPos(0.2,2,2) # Detect key presses self.keys = [] self.buttonThrowers[0].node().setButtonDownEvent('any') self.buttonThrowers[0].node().setButtonUpEvent('any-up') self.accept('escape',self.userExit) self.accept('any', self.press) self.accept('any-up', self.release) self.disableMouse() props = WindowProperties() props.setCursorHidden(True) props.setFullscreen(True) self.win.requestProperties(props) def lockMouse(self, task): center_x = self.win.getXSize() // 2 center_y = self.win.getYSize() // 2 self.win.movePointer(0, center_x, center_y) return task.cont def press(self, key: str): key=key.replace("shift-","") self.keys.append(key) def release(self, key: str): key=key.replace("shift-","") self.keys.remove(key) def update_movement(self, task): yaw=self.camera.getHpr()[0] rotation_matrix = Mat3.rotateMatNormaxis(yaw, LVector3(0, 0, 1)) direction = rotation_matrix.xform(LVector3(0, 1, 0)) yaw_rad = radians(yaw+90) right_x = -sin(yaw_rad) right_y = cos(yaw_rad) pos = self.camera.getPos() speed = 0.1 if "shift" in self.keys else 0.05 if "w" in self.keys: pos += direction * speed if "s" in self.keys: pos -= direction * speed if "a" in self.keys: pos.x += right_x * speed pos.y += right_y * speed if "d" in self.keys: pos.x -= right_x * speed pos.y -= right_y * speed self.camera.setPos(pos) return task.cont def update_camera(self, task): sensitivity = 100 center_x = base.win.getXSize() // 2 center_y = base.win.getYSize() // 2 if base.mouseWatcherNode.hasMouse(): # Get current mouse position x = base.win.getPointer(0).getX() y = base.win.getPointer(0).getY() # Calculate movement delta dx = center_x - x dy = center_y - y # Get current camera rotation h, p, r = self.camera.getHpr() new_h = h + dx * sensitivity * 0.003 new_p = max(min(p + dy * sensitivity * 0.003, 90), -90) # Clamp pitch # Apply self.camera.setHpr(new_h, new_p, r) # Reset mouse position to the center base.win.movePointer(0, center_x, center_y) return task.cont if __name__ == "__main__": game = WalkingGame() game.run() Continue reading...