I wrote this awhile ago to experiment with controling the cameraa with the mouse. The amount you can turn your head/twist your neck is limited. There is a compass to show which way the player body is facing and head is facing.
Mainly uploading it to save it off computer.
#playing with spin speed
import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
from pandac.PandaModules import *
from direct.gui.OnscreenImage import OnscreenImage
from pandac.PandaModules import TransparencyAttrib
from direct.gui.DirectGui import *
# Figure out what directory this program is in.
MYDIR=os.path.abspath(sys.path[0])
MYDIR=Filename.fromOsSpecific(MYDIR).getFullpath()
# Function to put instructions on the screen.
def addInstructions(pos, msg):
return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
pos=(-1.3, pos), align=TextNode.ALeft, scale = .05)
# Function to put title on the screen.
def addTitle(text):
return OnscreenText(text=text, style=1, fg=(1,1,1,1),
pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
class World(DirectObject):
def __init__(self):
self.keyMap = {"run":0, "left":0, "right":0, "backward":0, "turn-left":0, "turn-right":0, "look":1, "forward":0}
self.SPIN_RATE = 80 #how fast you can turn/spin around
self.PITCH_RATE = 1 #how fast you can raise/lower your head
self.FORWARD_SPEED = 2
self.BACKWARD_SPEED = 1
self.WALK_SPEED = 2
self.RUN_SPEED = 10
self.prevtime = 0 #initialize elapse time variable
self.neckTwist = 0
self.title = addTitle("My Template")
self.inst1 = addInstructions(0.95, "[ESC]: Quit")
self.inst2 = addInstructions(0.90, "[A]: Move Left")
self.inst3 = addInstructions(0.85, "[D]: Move Right")
self.inst4 = addInstructions(0.80, "[W]: Move Forward")
self.inst4 = addInstructions(0.75, "[S]: Move Backward")
self.inst6 = addInstructions(0.70, "[RMB]: Toggle camera control on/off ")
self.inst6 = addInstructions(0.65, "[Mouse]: Look Around")
self.inst8 = addInstructions(0.55, "")
self.inst9 = addInstructions(0.50, "")
#place mouse cursor at center of screen at start
base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2)
#Load the first environment model
self.environ = loader.loadModel("models/ground")
self.environ.reparentTo(render)
self.environ.setPos(0,0,0)
texHcompass = loader.loadTexture("textures/hCompass.png")
texBcompass = loader.loadTexture("textures/bCompass.png")
texcompass = loader.loadTexture("textures/compass.png")
self.Hcompass = loader.loadModel("models/tPlane")
self.Hcompass.setTexture(texHcompass,1)
self.Hcompass.reparentTo(base.camera)
self.Hcompass.setPos(0.6,2,0.4)
self.Hcompass.setScale(0.050)
self.Bcompass = loader.loadModel("models/tPlane")
self.Bcompass.setTexture(texBcompass,1)
self.Bcompass.reparentTo(base.camera)
self.Bcompass.setPos(0.6,2,0.4)
self.Bcompass.setScale(0.065)
self.compass = loader.loadModel("models/tPlane")
self.compass.setTexture(texcompass,1)
self.compass.reparentTo(base.camera)
self.compass.setPos(0.6,2,0.4)
self.compass.setScale(0.065)
#set the camera
base.disableMouse()
base.camera.reparentTo(render)
base.camera.setPos(0,0,1)
#output camera info
CameraPosition = "Camera Position: " + str(base.camera.getPos()) +" H: " + str(base.camera.getH()) +" P: " + str(base.camera.getP())
self.inst9.setText(CameraPosition)
#player's body
self.bodyNP = loader.loadModel("models/cube")
self.bodyNP.reparentTo(render)
self.bodyNP.setPos(0,0,1)
#output player info
PlayerPosition = "Player Position: " + str(self.bodyNP.getPos()) +" H: " + str(self.bodyNP.getH()) +" P: " + str(self.bodyNP.getP())
self.inst8.setText(PlayerPosition)
#set up some objects
self.object2NP = loader.loadModel("models/cube")
self.object2NP.reparentTo(render)
self.object2NP.setPos(15,0,0)
self.object3NP = loader.loadModel("models/cube")
self.object3NP.reparentTo(render)
self.object3NP.setPos(0,25,0)
#set lighting
self.alight = AmbientLight('alight')
self.alight.setColor(VBase4(0.2, 0.2, 0.2, 1))
self.alnp = render.attachNewNode(self.alight)
self.plightN = PointLight('plightN')
self.plightN.setColor(VBase4(0.8, 0.8, 0.8, 1))
self.plightNP = self.bodyNP.attachNewNode(self.plightN)
self.plightNP.setPos(2,2,2)
self.lightBulbNP = loader.loadModel("models/cube")
self.lightBulbNP.reparentTo(self.plightNP)
self.lightBulbNP.setPos(0,0,0)
self.lightBulbNP.setScale(0.2,0.2,0.2)
#choose objects affected by lighting
render.setLight(self.alnp)
self.bodyNP.setLight(self.plightNP)
#set up keyboard input response
self.accept("escape", sys.exit)
self.accept("q", self.setKey, ["left",1])
self.accept("e", self.setKey, ["right",1])
self.accept("w", self.setKey,["forward", 1])
self.accept("s", self.setKey, ["backward",1])
self.accept("a", self.setKey, ["turn-left",1])
self.accept("d", self.setKey, ["turn-right",1])
self.accept("q-up", self.setKey, ["left",0])
self.accept("e-up", self.setKey, ["right",0])
self.accept("w-up", self.setKey, ["forward",0])
self.accept("s-up", self.setKey, ["backward",0])
self.accept("a-up", self.setKey, ["turn-left",0])
self.accept("d-up", self.setKey, ["turn-right",0])
self.accept("mouse3", self.camToggle)
self.accept("space", self.runToggle)
#update every frame
#taskMgr.add(self.keepHewRange, "keepHewRangeTask")
taskMgr.add(self.moving,"movingTask")
def moving (self, task):
if ((self.keyMap["look"]!=0) and base.mouseWatcherNode.hasMouse()) :
self.MmoveHead()
self.moveBody()
self.Hcompass.setR(base.camera.getH()*-1)
self.Bcompass.setR(self.bodyNP.getH()*-1)
return Task.cont
def keepHewRange (self, task):
#keeps Hew between 0 and 360
if self.bodyNP.getH()>360:
self.bodyNP.setH(self.bodyNP.getH()-360)
if self.bodyNP.getH()<0:
self.bodyNP.setH(self.bodyNP.getH()+360)
if base.camera.getH()>360:
base.camera.setH(base.camera.getH()-360)
if base.camera.getH()<0:
base.camera.setH(base.camera.getH()+360)
return Task.cont
def runToggle (self):
if self.keyMap["run"] == 1:
self.FORWARD_SPEED = self.WALK_SPEED
self.keyMap["run"] = 0
else:
self.keyMap["run"] = 1
self.FORWARD_SPEED = self.RUN_SPEED
def camToggle (self):
if self.keyMap["look"] == 0:
self.keyMap["look"] = 1
else:
self.keyMap["look"] = 0
def setKey(self, key, value):
self.keyMap[key] = value
#print key, " = ", value #testing
def moveBody(self):
#used to compensate for differences in the time a task takes
elapsed = 0.02
#print "Elapsed: ", elapsed
if (self.keyMap["turn-left"]!=0):
self.bodyNP.setH(self.bodyNP.getH() + elapsed*self.SPIN_RATE )
base.camera.setH(base.camera.getH() + elapsed*self.SPIN_RATE )
if (self.keyMap["turn-right"]!=0):
self.bodyNP.setH(self.bodyNP.getH() - elapsed*self.SPIN_RATE )
base.camera.setH(base.camera.getH() - elapsed*self.SPIN_RATE )
if (self.keyMap["forward"]==1):
forward = self.bodyNP.getNetTransform().getMat().getRow3(1)
forward.setZ(0)
forward.normalize()
oldPos = self.bodyNP.getPos() #testing
self.bodyNP.setPos(self.bodyNP.getPos() + forward*elapsed*self.FORWARD_SPEED)
newPos = self.bodyNP.getPos() #teting
distanceF = newPos - oldPos #teting
print "DistanceF: ", distanceF #teting
if (self.keyMap["backward"]!=0):
backward = self.bodyNP.getNetTransform().getMat().getRow3(1)
backward.setZ(0)
backward.normalize()
self.bodyNP.setPos(self.bodyNP.getPos() - backward*elapsed*self.BACKWARD_SPEED)
if (self.keyMap["left"]!=0):
left = self.bodyNP.getNetTransform().getMat().getRow3(0)
left.setZ(0)
left.normalize()
oldPosL = self.bodyNP.getPos() #testing
self.bodyNP.setPos(self.bodyNP.getPos() - left*elapsed*6 )
newPosL = self.bodyNP.getPos() #teting
distanceL = newPosL - oldPosL #teting
print "DistanceL: ", distanceL #teting
if (self.keyMap["right"]!=0):
right = self.bodyNP.getNetTransform().getMat().getRow3(0)
right.setZ(0)
right.normalize()
self.bodyNP.setPos(self.bodyNP.getPos() + right*elapsed*6 )
base.camera.setPos(self.bodyNP.getPos())
PlayerPosition = "Player Position: " + str(self.bodyNP.getPos()) +" H: " + str(self.bodyNP.getH()) +" P: " + str(self.bodyNP.getP())
self.inst8.setText(PlayerPosition)
CameraPosition = "Camera Position: " + str(base.camera.getPos()) +" H: " + str(base.camera.getH()) +" P: " + str(base.camera.getP())
self.inst9.setText(CameraPosition)
def MmoveHead(self):
mpos = base.mouseWatcherNode.getMouse()
#pitch
self.camPitch=base.camera.getP()
fUpOrDown = mpos.getY() #a negative fUD is focus Down
cPitch = self.PITCH_RATE * fUpOrDown * abs(fUpOrDown)
if (self.camPitch + cPitch) < 89 and (self.camPitch + cPitch) > -65 :
oldP = self.camPitch #testing
base.camera.setP(self.camPitch + cPitch)
newP = base.camera.getP() #testing
changeP = oldP-newP#testing
#print
#print "Change Pitch: ", changeP #testing
#print "Pitch: ", self.camPitch #testing
#print
#hew
self.neckTwist = base.camera.getH() - self.bodyNP.getH()
fLR = mpos.getX() #focus on the left or right
cHew = 22*fLR*abs(fLR) #can be + or -
if (abs(self.neckTwist + cHew*-1)) <45.00:
base.camera.setH(base.camera.getH() + cHew*-1)
print "cHEW*-1", cHew*-1
print "camera hew: ",base.camera.getH()
print "body hew: ",self.bodyNP.getH()
print "NeckTwist", self.neckTwist
print
PlayerPosition = "Player Position: " + str(self.bodyNP.getPos()) +" H: " + str(self.bodyNP.getH()) +" P: " + str(self.bodyNP.getP())
self.inst8.setText(PlayerPosition)
CameraPosition = "Camera Position: " + str(base.camera.getPos()) +" H: " + str(base.camera.getH()) +" P: " + str(base.camera.getP())
self.inst9.setText(CameraPosition)
w = World()
run()