mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
ghost mode
This commit is contained in:
parent
a7d9badea0
commit
5a713cbba9
@ -6,6 +6,7 @@ from ShowBaseGlobal import *
|
||||
|
||||
import Avatar
|
||||
import DirectNotifyGlobal
|
||||
import GhostWalker
|
||||
import GravityWalker
|
||||
import NonPhysicsWalker
|
||||
import PhysicsWalker
|
||||
@ -21,7 +22,10 @@ class ControlManager:
|
||||
def __init__(self, avatar):
|
||||
self.avatar = avatar
|
||||
assert(self.debugPrint("ControlManager()"))
|
||||
self.swimControls=NonPhysicsWalker.NonPhysicsWalker()
|
||||
self.swimControls=GravityWalker.GravityWalker(
|
||||
gravity = -32.1740 * 2.0)
|
||||
#self.swimControls=NonPhysicsWalker.NonPhysicsWalker()
|
||||
self.ghostControls=GhostWalker.GhostWalker()
|
||||
if self.wantAvatarPhysics:
|
||||
self.walkControls=GravityWalker.GravityWalker(
|
||||
gravity = -32.1740 * 2.0) # * 2.0 is a hack;
|
||||
@ -57,6 +61,7 @@ class ControlManager:
|
||||
inputState.watch("jump", "alt-control", "alt-control-up")
|
||||
inputState.watch("jump", "shift-control", "shift-control-up")
|
||||
|
||||
# FYI, ghost mode uses jump for slide.
|
||||
inputState.watch("slide", "slide-is-disabled", "slide-is-disabled")
|
||||
|
||||
#inputState.watch("slideLeft", "shift-arrow_left", "shift-arrow_left-up")
|
||||
@ -71,6 +76,24 @@ class ControlManager:
|
||||
#inputState.watch("slideRight", "shift-arrow_right", "shift-arrow_right-up")
|
||||
inputState.watch("slideRight", "slide-is-disabled", "slide-is-disabled")
|
||||
|
||||
def add(self, controls, name="basic"):
|
||||
controls = self.controls.get(name)
|
||||
if controls is not None:
|
||||
print "Replacing controls:", name
|
||||
controls.delete()
|
||||
self.controls[name] = controls
|
||||
|
||||
def use(self, name="basic"):
|
||||
controls = self.controls.get(name)
|
||||
if controls is not None:
|
||||
if controls is not self.currentControls:
|
||||
self.currentControls.disableAvatarControls()
|
||||
self.currentControls.setCollisionsActive(0)
|
||||
self.currentControls = controls
|
||||
self.currentControls.setCollisionsActive(1)
|
||||
else:
|
||||
print "Unkown controls:", name
|
||||
|
||||
def useSwimControls(self):
|
||||
assert(self.debugPrint("useSwimControls()"))
|
||||
if self.currentControls is not self.swimControls:
|
||||
@ -81,6 +104,16 @@ class ControlManager:
|
||||
if self.isEnabled:
|
||||
self.currentControls.enableAvatarControls()
|
||||
|
||||
def useGhostControls(self):
|
||||
assert(self.debugPrint("useGhostControls()"))
|
||||
if self.currentControls is not self.ghostControls:
|
||||
self.currentControls.disableAvatarControls()
|
||||
self.currentControls.setCollisionsActive(0)
|
||||
self.ghostControls.setCollisionsActive(1)
|
||||
self.currentControls = self.ghostControls
|
||||
if self.isEnabled:
|
||||
self.currentControls.enableAvatarControls()
|
||||
|
||||
def useWalkControls(self):
|
||||
assert(self.debugPrint("useWalkControls()"))
|
||||
if self.currentControls is not self.walkControls:
|
||||
@ -106,6 +139,11 @@ class ControlManager:
|
||||
toonJumpForce,
|
||||
toonReverseSpeed,
|
||||
toonRotateSpeed)
|
||||
self.ghostControls.setWalkSpeed(
|
||||
toonForwardSpeed,
|
||||
toonJumpForce,
|
||||
toonReverseSpeed,
|
||||
toonRotateSpeed)
|
||||
self.walkControls.setWalkSpeed(
|
||||
toonForwardSpeed,
|
||||
toonJumpForce,
|
||||
@ -116,7 +154,7 @@ class ControlManager:
|
||||
return self.currentControls.getSpeeds()
|
||||
|
||||
def initializeCollisions(self, cTrav,
|
||||
wallBitmask, floorBitmask, avatarRadius, floorOffset):
|
||||
wallBitmask, floorBitmask, ghostBitMask, avatarRadius, floorOffset):
|
||||
assert(self.debugPrint("initializeCollisions()"))
|
||||
|
||||
self.walkControls.initializeCollisions(cTrav, self.avatar,
|
||||
@ -130,6 +168,12 @@ class ControlManager:
|
||||
self.swimControls.setAirborneHeightFunc(self.avatar.getAirborneHeight)
|
||||
self.swimControls.disableAvatarControls()
|
||||
self.swimControls.setCollisionsActive(0)
|
||||
|
||||
self.ghostControls.initializeCollisions(cTrav, self.avatar,
|
||||
ghostBitMask, floorBitmask, avatarRadius, floorOffset)
|
||||
self.ghostControls.setAirborneHeightFunc(self.avatar.getAirborneHeight)
|
||||
self.ghostControls.disableAvatarControls()
|
||||
self.ghostControls.setCollisionsActive(0)
|
||||
|
||||
self.walkControls.setCollisionsActive(1)
|
||||
self.walkControls.enableAvatarControls()
|
||||
@ -138,6 +182,7 @@ class ControlManager:
|
||||
assert(self.debugPrint("deleteCollisions()"))
|
||||
self.walkControls.deleteCollisions()
|
||||
self.swimControls.deleteCollisions()
|
||||
self.ghostControls.deleteCollisions()
|
||||
|
||||
def collisionsOn(self):
|
||||
assert(self.debugPrint("collisionsOn()"))
|
||||
|
@ -23,53 +23,5 @@ class GhostWalker(NonPhysicsWalker.NonPhysicsWalker):
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("GhostWalker")
|
||||
|
||||
def handleAvatarControls(self, task):
|
||||
"""
|
||||
Check on the arrow keys and update the avatar.
|
||||
"""
|
||||
# get the button states:
|
||||
forward = inputState.isSet("forward")
|
||||
reverse = inputState.isSet("reverse")
|
||||
turnLeft = inputState.isSet("turnLeft")
|
||||
turnRight = inputState.isSet("turnRight")
|
||||
# Ghosts slide instead of jump:
|
||||
slide = inputState.isSet("jump")
|
||||
# Determine what the speeds are based on the buttons:
|
||||
self.speed=(forward and self.avatarControlForwardSpeed or
|
||||
reverse and -self.avatarControlReverseSpeed)
|
||||
# Should fSlide be renamed slideButton?
|
||||
self.slideSpeed=slide and (
|
||||
(turnLeft and -self.avatarControlForwardSpeed) or
|
||||
(turnRight and self.avatarControlForwardSpeed))
|
||||
self.rotationSpeed=not slide and (
|
||||
(turnLeft and self.avatarControlRotateSpeed) or
|
||||
(turnRight and -self.avatarControlRotateSpeed))
|
||||
|
||||
# How far did we move based on the amount of time elapsed?
|
||||
dt=min(ClockObject.getGlobalClock().getDt(), 0.1)
|
||||
# Check to see if we're moving at all:
|
||||
if self.speed or self.slideSpeed or self.rotationSpeed:
|
||||
if self.stopThisFrame:
|
||||
distance = 0.0
|
||||
slideDistance = 0.0
|
||||
rotation = 0.0
|
||||
self.stopThisFrame = 0
|
||||
else:
|
||||
distance = dt * self.speed
|
||||
slideDistance = dt * self.slideSpeed
|
||||
rotation = dt * self.rotationSpeed
|
||||
|
||||
# Take a step in the direction of our previous heading.
|
||||
self.vel=Vec3(Vec3.forward() * distance +
|
||||
Vec3.right() * slideDistance)
|
||||
if self.vel != Vec3.zero():
|
||||
# rotMat is the rotation matrix corresponding to
|
||||
# our previous heading.
|
||||
rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
|
||||
step=rotMat.xform(self.vel)
|
||||
self.avatarNodePath.setFluidPos(Point3(self.avatarNodePath.getPos()+step))
|
||||
self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
|
||||
messenger.send("avatarMoving")
|
||||
else:
|
||||
self.vel.set(0.0, 0.0, 0.0)
|
||||
return Task.cont
|
||||
# Ghosts slide instead of jump:
|
||||
slideName = "jump"
|
||||
|
@ -39,6 +39,11 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
|
||||
self.mayJump = 1
|
||||
self.jumpDelayTask = None
|
||||
|
||||
self.controlsTask = None
|
||||
self.fixCliffTask = None
|
||||
self.indicatorTask = None
|
||||
|
||||
self.falling = 0
|
||||
self.needToDeltaPos = 0
|
||||
self.physVelocityIndicator=None
|
||||
@ -149,7 +154,7 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
"""
|
||||
# This is a sphere on the ground to detect barrier collisions
|
||||
self.avatarRadius = avatarRadius
|
||||
self.cSphere = CollisionSphere(0.0, 0.0, avatarRadius, avatarRadius)
|
||||
self.cSphere = CollisionSphere(0.0, 0.0, avatarRadius+0.5, avatarRadius)
|
||||
cSphereNode = CollisionNode('GW.cWallSphereNode')
|
||||
cSphereNode.addSolid(self.cSphere)
|
||||
cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
|
||||
@ -159,8 +164,8 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
|
||||
# set up collision mechanism
|
||||
handler = CollisionHandlerPusher()
|
||||
handler.setInPattern("enter%in")
|
||||
handler.setOutPattern("exit%in")
|
||||
handler.setInPattern("pusher_enter%in")
|
||||
handler.setOutPattern("pusher_exit%in")
|
||||
|
||||
handler.addCollider(cSphereNodePath, self.avatarNodePath)
|
||||
self.pusher = handler
|
||||
@ -172,7 +177,7 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
"""
|
||||
# This is a sphere on the ground to detect barrier collisions
|
||||
self.avatarRadius = avatarRadius
|
||||
self.cSphere = CollisionSphere(0.0, 0.0, avatarRadius-0.1, avatarRadius)
|
||||
self.cSphere = CollisionSphere(0.0, 0.0, avatarRadius-0.1, avatarRadius*1.04)
|
||||
cSphereNode = CollisionNode('GW.cFloorSphereNode')
|
||||
cSphereNode.addSolid(self.cSphere)
|
||||
cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
|
||||
@ -204,7 +209,7 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
|
||||
self.setupRay(floorBitmask, self.floorOffset)
|
||||
self.setupWallSphere(wallBitmask, avatarRadius)
|
||||
self.setupFloorSphere(floorBitmask, avatarRadius)
|
||||
self.setupFloorSphere(wallBitmask|floorBitmask, avatarRadius)
|
||||
|
||||
self.setCollisionsActive(1)
|
||||
|
||||
@ -236,6 +241,9 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
assert(self.debugPrint("collisionsActive(active=%s)"%(active,)))
|
||||
if self.collisionsActive != active:
|
||||
self.collisionsActive = active
|
||||
# Each time we change the collision geometry, make one
|
||||
# more pass to ensure we aren't standing in a wall.
|
||||
self.oneTimeCollide()
|
||||
if active:
|
||||
self.cTrav.addCollider(self.cWallSphereNodePath, self.pusher)
|
||||
self.cTrav.addCollider(self.cFloorSphereNodePath, self.event)
|
||||
@ -244,15 +252,25 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
self.cTrav.removeCollider(self.cWallSphereNodePath)
|
||||
self.cTrav.removeCollider(self.cFloorSphereNodePath)
|
||||
self.cTrav.removeCollider(self.cRayNodePath)
|
||||
# Now that we have disabled collisions, make one more pass
|
||||
# right now to ensure we aren't standing in a wall.
|
||||
self.oneTimeCollide()
|
||||
|
||||
def getCollisionsActive(self):
|
||||
assert(self.debugPrint("getCollisionsActive() returning=%s"%(
|
||||
self.collisionsActive,)))
|
||||
return self.collisionsActive
|
||||
|
||||
def FixCliff(self, task):
|
||||
"""
|
||||
People are still making polygons that are marked
|
||||
as floor, but are nearly vertical. This ray is
|
||||
a hack to help deal with the cliff.
|
||||
"""
|
||||
if self.lifter.isInOuterSpace():
|
||||
temp = self.cRayNodePath.getZ()
|
||||
self.cRayNodePath.setZ(14.0)
|
||||
self.oneTimeCollide()
|
||||
self.cRayNodePath.setZ(temp)
|
||||
return Task.cont
|
||||
|
||||
def oneTimeCollide(self):
|
||||
"""
|
||||
Makes one quick collision pass for the avatar, for instance as
|
||||
@ -294,7 +312,7 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
reverse = inputState.isSet("reverse")
|
||||
turnLeft = inputState.isSet("turnLeft")
|
||||
turnRight = inputState.isSet("turnRight")
|
||||
slide = inputState.isSet("slide")
|
||||
slide = 0 #hack -- was: inputState.isSet("slide")
|
||||
jump = inputState.isSet("jump")
|
||||
pie = inputState.isSet("pie")
|
||||
# Determine what the speeds are based on the buttons:
|
||||
@ -328,6 +346,8 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
onScreenDebug.add("velocity", self.lifter.getVelocity()) #*#
|
||||
onScreenDebug.add("isAirborne", self.isAirborne) #*#
|
||||
onScreenDebug.add("jump", jump) #*#
|
||||
|
||||
onScreenDebug.add("inOuterSpace", self.lifter.isInOuterSpace()) #*#
|
||||
if self.lifter.isOnGround():
|
||||
if self.isAirborne:
|
||||
self.isAirborne = 0
|
||||
@ -408,13 +428,26 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
if __debug__:
|
||||
self.accept("control-f3", self.spawnTest) #*#
|
||||
|
||||
taskName = "AvatarControls%s"%(id(self),)
|
||||
# remove any old
|
||||
taskMgr.remove(taskName)
|
||||
if self.controlsTask:
|
||||
self.controlsTask.remove()
|
||||
# spawn the new task
|
||||
taskMgr.add(self.handleAvatarControls, taskName, 25)
|
||||
taskName = "AvatarControls%s"%(id(self),)
|
||||
self.controlsTask = taskMgr.add(self.handleAvatarControls, taskName, 25)
|
||||
|
||||
# remove any old
|
||||
if self.fixCliffTask:
|
||||
self.fixCliffTask.remove()
|
||||
# spawn the new task
|
||||
taskName = "AvatarControls-FixCliff%s"%(id(self),)
|
||||
self.fixCliffTask = taskMgr.add(self.FixCliff, taskName, 31)
|
||||
|
||||
if self.physVelocityIndicator:
|
||||
taskMgr.add(self.avatarPhysicsIndicator, "AvatarControlsIndicator%s"%(id(self),), 35)
|
||||
if self.indicatorTask:
|
||||
self.indicatorTask.remove()
|
||||
self.indicatorTask = taskMgr.add(
|
||||
self.avatarPhysicsIndicator,
|
||||
"AvatarControlsIndicator%s"%(id(self),), 35)
|
||||
|
||||
def disableAvatarControls(self):
|
||||
"""
|
||||
@ -422,11 +455,15 @@ class GravityWalker(DirectObject.DirectObject):
|
||||
"""
|
||||
assert(self.debugPrint("disableAvatarControls()"))
|
||||
print id(self), "GW.disableAvatarControls()"
|
||||
taskName = "AvatarControls%s"%(id(self),)
|
||||
taskMgr.remove(taskName)
|
||||
|
||||
taskName = "AvatarControlsIndicator%s"%(id(self),)
|
||||
taskMgr.remove(taskName)
|
||||
if self.controlsTask:
|
||||
self.controlsTask.remove()
|
||||
self.controlsTask = None
|
||||
if self.fixCliffTask:
|
||||
self.fixCliffTask.remove()
|
||||
self.fixCliffTask = None
|
||||
if self.indicatorTask:
|
||||
self.indicatorTask.remove()
|
||||
self.indicatorTask = None
|
||||
|
||||
if __debug__:
|
||||
self.ignore("control-f3") #*#
|
||||
|
@ -23,6 +23,9 @@ class NonPhysicsWalker(DirectObject.DirectObject):
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")
|
||||
|
||||
# Ghost mode overrides this:
|
||||
slideName = "slide-is-disabled"
|
||||
|
||||
# special methods
|
||||
def __init__(self):
|
||||
DirectObject.DirectObject.__init__(self)
|
||||
@ -151,7 +154,7 @@ class NonPhysicsWalker(DirectObject.DirectObject):
|
||||
reverse = inputState.isSet("reverse")
|
||||
turnLeft = inputState.isSet("turnLeft")
|
||||
turnRight = inputState.isSet("turnRight")
|
||||
slide = inputState.isSet("slide")
|
||||
slide = inputState.isSet(self.slideName)
|
||||
#jump = inputState.isSet("jump")
|
||||
# Determine what the speeds are based on the buttons:
|
||||
self.speed=(forward and self.avatarControlForwardSpeed or
|
||||
|
Loading…
x
Reference in New Issue
Block a user