mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-26 21:22:27 -06:00
136 lines
5.2 KiB
Python
136 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)
|