toontown-just-works/toontown/cogdominium/CogdoMazeCameraManager.py
2024-07-07 18:08:39 -05:00

135 lines
5.2 KiB
Python

from direct.showbase.PythonUtil import bound as clamp
import CogdoMazeGameGlobals as Globals
import math
import random
class CogdoMazeCameraManager:
toonJumpSpeed = 30.0
toonJumpDir = 1.0
toonMaxHeight = 1.8
maxHeightOffset = 1.5
savedShakeStrength = 0.0
toonIsShaking = False
rumbleOffDuration = 2.0
rumbleOnDuration = 1.5
rumbleOffTimer = 0.0
rumbleOnTimer = -1
savedCamZ = 0.0
savedCamX = 0.0
shakeStrengthThreshold = 2.8
savedRumbleTimer = 0.0
rumbleFreq = 0.1
rumbleSmall = 0.05
rumbleBig = 0.16
rumbleMagnitude = rumbleSmall
def __init__(self, toon, maze, cam, root):
self.toon = toon
self.maze = maze
self.camera = cam
self.root = root
self.shakeStrength = 0.0
self.shakeOffset = 0.0
self.shakeTime = 0.0
self.defaultHeight = 0.0
self.minPos = self.maze.tile2world(3, 5)
self.maxPos = self.maze.tile2world(self.maze.width - 3, self.maze.height - 3)
self._camAngle = Globals.CameraAngle
self._camDistance = Globals.CameraMinDistance
self._camTargetDistance = self._camDistance
def enable(self):
self.parent = self.root.attachNewNode('GameCamParent')
self.parent.setPos(self.toon, 0, 0, 0)
self.parent.setHpr(self.root, 180, self._camAngle, 0)
self.camera.reparentTo(self.parent)
self.camera.setPos(0, self._camDistance, 0)
self.camera.lookAt(self.toon)
self.defaultHeight = self.parent.getZ()
self.update(0)
def setCameraTargetDistance(self, distance):
self._camTargetDistance = distance
def disable(self):
self.camera.wrtReparentTo(render)
self.parent.removeNode()
del self.parent
def update(self, dt):
toonPos = self.toon.getPos()
self.parent.setPos(self.toon.getParent(), clamp(toonPos.getX(), self.minPos[0], self.maxPos[0]), clamp(toonPos.getY(), self.minPos[1], self.maxPos[1]), 0)
if self._camDistance != self._camTargetDistance:
self._updateCameraDistance()
if self.shakeOffset > 0 or self.shakeStrength > 0:
self.updateShake(dt)
self.updateRumble(dt)
def _updateCameraDistance(self):
if self._camDistance < self._camTargetDistance:
self._camDistance += min(0.4 * (self._camDistance / self._camTargetDistance), self._camTargetDistance - self._camDistance)
elif self._camDistance > self._camTargetDistance:
self._camDistance += max(-0.4 * (self._camDistance / self._camTargetDistance), self._camTargetDistance - self._camDistance)
self.camera.setY(self._camDistance)
def updateShake(self, dt):
if self.shakeStrength > 0:
if self.shakeStrength > Globals.CameraShakeMax:
self.shakeStrength = Globals.CameraShakeMax
height = self.defaultHeight + self.shakeStrength
self.shakeStrength = self.shakeStrength - Globals.CameraShakeFalloff * dt
if self.shakeStrength < 0.0:
self.shakeStrength = 0.0
else:
height = self.shakeStrength
def shake(self, strength):
self.shakeStrength += strength * 1.5
self.toonIsShaking = True
def updateToonShake(self, dt):
if self.toonIsShaking:
newHeight = self.toon.getZ() + self.toonJumpDir * dt * self.savedShakeStrength * self.toonJumpSpeed
maxHeight = self.savedShakeStrength * self.maxHeightOffset
if maxHeight > self.toonMaxHeight:
maxHeight = self.toonMaxHeight
if newHeight >= maxHeight:
newHeight = maxHeight
self.toonJumpDir = -1.0
elif newHeight <= 0.0:
newHeight = 0.0
self.toonJumpDir = 1.0
self.toonIsShaking = False
self.toon.setZ(newHeight)
def updateRumble(self, dt):
if self.rumbleOnTimer == -1:
self.rumbleOffTimer += dt
if self.rumbleOffTimer > self.rumbleOffDuration:
self.rumbleOnTimer = 0.0
self.savedRumbleTimer = 0.0
self.rumbleOffTimer = -1
self.rumbleOnDuration = 1.5
self.savedCamZ = self.camera.getZ()
self.savedCamX = self.camera.getX()
else:
if self.rumbleOnTimer > self.savedRumbleTimer + self.rumbleFreq:
self.savedRumbleTimer += self.rumbleFreq
self.rumble(self.rumbleMagnitude)
self.rumbleOnTimer += dt
if self.rumbleOnTimer > self.rumbleOnDuration:
self.rumbleOffTimer = 0.0
self.rumbleOnTimer = -1
if self.shakeStrength > self.shakeStrengthThreshold:
self.rumbleOffDuration = 0.5
self.rumbleMagnitude = self.rumbleBig
else:
self.rumbleOffDuration = random.uniform(1.0, 3.0)
self.rumbleMagnitude = self.rumbleSmall
def rumble(self, magnitude):
self.rumbleMagnitude *= -1.0
dz = self.rumbleMagnitude
self.camera.setZ(self.savedCamZ + dz)
dx = dz
self.camera.setZ(self.savedCamX + dx)