import glm from gui.visual.mouse import Mouse from gui.visual.player import Player class Camera: def __init__(self, player: Player) -> None: self.position = glm.vec3(0, 0, 1) self.pith = 10 self.yaw = 0 self.roll = 0 self.angleAroundPlayer = 0 self.player = player self.distanceFromPlayer = 10 self.mx = 0 self.my = 0 self.scale = 1 def setPosition(self, x, y): self.player.position = glm.vec3(x, y, 0) def setZoomScale(self, scale): self.scale = scale def setZoom(self, zoom): self.distanceFromPlayer = 0.70140280561122 * zoom - 0.028056112224449 #values from linear interpolation def move(self): self.calculateZoom() self.calculatePitchAndAngleAroundPLayer() horizontalDistance = self.calculateHorizotalDistance() verticalDistance = self.calculateVerticalDistance() self.calculateCameraPosition(horizontalDistance, verticalDistance) def calculateZoom(self): zoomLevel = Mouse.getDWheel() * self.scale self.distanceFromPlayer -= zoomLevel if self.distanceFromPlayer < 0.1: self.distanceFromPlayer = 0.1 def calculateCameraPosition(self, horizontalDistance, verticalDistance): theta = self.player.rotY + self.angleAroundPlayer offsetX = horizontalDistance * glm.sin(glm.radians(theta)) offsetY = horizontalDistance * glm.cos(glm.radians(theta)) self.position.x = self.player.position.x - offsetX self.position.y = self.player.position.y + offsetY self.position.z = self.player.position.z + verticalDistance yaw = 180 - theta def calculateHorizotalDistance(self): return self.distanceFromPlayer * glm.cos(glm.radians(self.pith)) def calculateVerticalDistance(self): return self.distanceFromPlayer * glm.sin(glm.radians(self.pith)) def calculatePitchAndAngleAroundPLayer(self): if Mouse.isButtonDown(Mouse.MOUSE_LEFT): dx = Mouse.getX() - self.mx dy = Mouse.getY() - self.my pitchChange = dy * 0.1 self.pith += pitchChange if self.pith < -90: self.pith = -89.99 if self.pith > 90: self.pith = 89.99 angleChange = dx * 0.3 self.angleAroundPlayer -= angleChange elif Mouse.isButtonDown(Mouse.MOUSE_RIGHT): dx = Mouse.getX() - self.mx dy = Mouse.getY() - self.my theta = glm.radians(self.player.rotY + self.angleAroundPlayer) scale = self.distanceFromPlayer * 10 / 250 self.player.position.x += (dx * glm.cos(theta) + dy * glm.sin(theta)) * 0.1 * scale self.player.position.y += (dx * glm.sin(theta) - dy * glm.cos(theta)) * 0.1 * scale self.mx = Mouse.getX() self.my = Mouse.getY()