Hello,
I am new in program with Panda3D
and now I have a few questions.
Things that work:
- loding the terrain from a heightmap
- scroling in and out (using: mouse wheel)
- walking (using: w)
- turning around (using: a & d)
- turning camera (using: q & e)
My first question is like the subject suggests
how do I get that the camera moves around a actor using the right mouse button?
Here is my script:
I used the sample Roaming Ralph
and changed some things
from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import *
from pandac.PandaModules import *
import sys
loadPrcFileData('', 'window-title My Game')
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.speed = 0.1
self.isMoving = False
render.setShaderAuto()
base.disableMouse()
self.props = WindowProperties()
# create a basic terrain
self.geomipterrain = GeoMipTerrain ('geomipterrain')
self.geomipterrain.setBlockSize (16)
self.geomipterrain.setNearFar (80, 100)
self.geomipterrain.setHeightfield ('models/heightmap.pgm')
self.geomipterrain.setAutoFlatten (GeoMipTerrain.AFMOff)
self.geomipterrain.setFocalPoint(Point3(0,0,0))
self.geomipterrain.setBruteforce(True)
self.geomipterrain.setMinLevel(3)
self.terrainRoot = self.geomipterrain.getRoot()
self.terrainRoot.setSz (100) # significant height differences
self.terrainRoot.setPos (Point3(-257/2, -257/2, 0)) # re-center the terrain
self.terrainRoot.reparentTo (render)
# generate terrain squares
self.geomipterrain.generate()
# assign a texture
self.terrainRoot.clearTexture()
ts = TextureStage('baseColor')
tex = loader.loadTexture('models/ground.jpg')
tex.setMagfilter (Texture.FTLinear)
tex.setMinfilter (Texture.FTLinearMipmapLinear)
tex.setWrapU(Texture.WMRepeat)
tex.setWrapV(Texture.WMRepeat)
self.terrainRoot.setTexture(ts, tex)
self.terrainRoot.setTexScale(ts, 32, 32)
# define a shiny material so i can also see some specular lighting on our
# terrain when autoshader is on
terrainMat = Material()
terrainMat.setShininess (12.5)
terrainMat.setAmbient (VBase4 (1, 1, 1, 1))
terrainMat.setDiffuse (VBase4 (1, 1, 1, 1))
terrainMat.setEmission (VBase4 (0, 0, 0, 0))
terrainMat.setSpecular (VBase4 (1, 1, 1, 1))
self.terrainRoot.setMaterial (terrainMat)
self.keyMap = {"left":0, "right":0, "forward":0, "jump":0, "cam-left":0, "cam-right":0,
"mouse1":0, "mouse2":0, "cam-out":0, "cam-in":0 }
self.mousePos = {"X":0, "Y":0,"X2":0, "Y2":0}
self.camPos = {"W":0,"H":0}
base.win.setClearColor(Vec4(0,0,0,1))
self.ralph = Actor("models/ralph.egg.pz",
{"run":"models/ralph-run.egg.pz",
"walk":"models/ralph-walk.egg.pz"})
self.ralph.reparentTo(render)
self.ralph.setScale(.2)
self.ralph.setPos(0,0,0)
# Create Jump Interval
self.ralph.jumpUp = LerpFunc(self.move_z,fromData=0,toData=2,duration=0.1,extraArgs=[self.ralph])
self.ralph.jumpDown = LerpFunc(self.move_z,fromData=2,toData=0,duration=0.1,extraArgs=[self.ralph])
# Create a floater object. I use the "floater" as a temporary
# variable in a variety of calculations.
self.floater = NodePath(PandaNode("floater"))
self.floater.reparentTo(render)
# dummy node for camera, we will rotate the dummy node fro camera rotation
self.camnode = render.attachNewNode('camparent')
self.camnode.reparentTo(self.ralph) # inherit transforms
#self.camnode.setEffect(CompassEffect.make(render)) # NOT inherit rotation
self.camnode.setZ(3)
#self.camnode.setX(5)
self.camera.reparentTo(self.camnode)
self.camera.setX(0)
self.camera.setY(20)
self.camera.setZ(0)
#self.camera.lookAt(self.camnode)
self.camera.lookAt(self.ralph)
# camera distance from model
#self.camera.setZ(10)
# Accept the control keys for movement and rotation
self.accept("escape", sys.exit)
self.accept("a", self.setKey, ["left",1])
self.accept("d", self.setKey, ["right",1])
self.accept("w", self.setKey, ["forward",1])
self.accept("q", self.setKey, ["cam-left",1])
self.accept("e", self.setKey, ["cam-right",1])
self.accept("space", self.setKey, ["jump",1])
self.accept("mouse1", self.setMouse, ["mouse1",1])
self.accept("mouse3", self.setMouse2, [True])
self.accept("wheel_up", self.setKey, ["cam-in",1])
self.accept("wheel_down", self.setKey, ["cam-out",1])
self.accept("a-up", self.setKey, ["left",0])
self.accept("d-up", self.setKey, ["right",0])
self.accept("w-up", self.setKey, ["forward",0])
self.accept("q-up", self.setKey, ["cam-left",0])
self.accept("e-up", self.setKey, ["cam-right",0])
self.accept("space-up", self.setKey, ["jump",0])
self.accept("mouse1-up", self.setMouse, ["mouse1",0])
self.accept("mouse3-up", self.setMouse2, [False])
self.accept("u", self.debug )
self.taskMgr.add(self.move,"moveTask")
# Game state variables
self.isMoving = False
self.CamDist = 10.0
self.jumpCalc = {"Time":0.0,"Activ":0}
self.heading = 0
self.pitch = 0
# Set up the camera
base.camera.setPos(self.ralph.getX(),self.ralph.getY()+self.CamDist,2)
def debug(self):
print "H:",self.heading," P:",self.pitch
def setKey(self, key, value):
self.keyMap[key] = value
def setMouse2(self,state):
self.mousePos["X"]=base.win.getPointer(0).getX()
self.mousePos["Y"]=base.win.getPointer(0).getY()
if state:
base.win.movePointer(0, 300, 300)
self.taskMgr.add(self.thirdPersonCameraTask, 'thirdPersonCameraTask')
else:
self.taskMgr.remove('thirdPersonCameraTask')
self.props.setCursorHidden(state)
base.win.requestProperties(self.props)
def setMouse(self, key, value):
self.keyMap[key] = value
self.mousePos["X"]=base.win.getPointer(0).getX()
self.mousePos["Y"]=base.win.getPointer(0).getY()
#print "X:",self.mousePos["X"]
#print "Y:",self.mousePos["Y"]
def move_z(self,value,actor):
actor.setZ(actor,value)
def move(self, task):
self.ralph.setZ(self.terrainRoot,
self.geomipterrain.getElevation(self.ralph.getX(self.terrainRoot),
self.ralph.getY(self.terrainRoot)))
self.geomipterrain.update()
# If the camera-left key is pressed, move camera left.
# If the camera-right key is pressed, move camera right.
#base.camera.lookAt(self.ralph)
if (self.keyMap["cam-left"]!=0):
angelDegrees = self.camPos["W"] / (pi / 180.0) - 5.0
self.camPos["W"] = angelDegrees * (pi / 180.0)
if (self.keyMap["cam-right"]!=0):
angelDegrees = self.camPos["W"] / (pi / 180.0) + 5.0
self.camPos["W"] = angelDegrees * (pi / 180.0)
if (self.keyMap["cam-out"]!=0):
self.keyMap["cam-out"]=0
if (self.CamDist < 10):
self.CamDist = self.CamDist + 1.0
if (self.keyMap["cam-in"]!=0):
self.keyMap["cam-in"]=0
if (self.CamDist > 1):
self.CamDist = self.CamDist - 1.0
self.camera.setY(8 * self.CamDist)
#save ralph's initial position so that we can restore it,
# in case he falls off the map or runs into something.
startpos = self.ralph.getPos()
# If a move-key is pressed, move ralph in the specified direction.
if (self.keyMap["left"]!=0):
self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt())
if (self.keyMap["right"]!=0):
self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
if (self.keyMap["forward"]!=0):
self.ralph.setY(self.ralph, -25 * globalClock.getDt())
if (self.keyMap["jump"]!=0):
self.jumpCalc["Activ"]=1
self.keyMap["jump"]=0
self.jump()
# If ralph is moving, loop the run animation.
# If he is standing still, stop the animation.
if ((self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0)) and (self.jumpCalc["Activ"]==0):
if self.isMoving is False:
self.ralph.loop("run")
self.isMoving = True
else:
if self.isMoving:
self.ralph.stop()
self.ralph.pose("walk",5)
self.isMoving = False
# should move the camera around ralph
#if (self.keyMap["mouse2"]!=0):
# x = self.mousePos["X"] - base.win.getPointer(0).getX()
# y = self.mousePos["Y"] - base.win.getPointer(0).getY()
#self.mousePos["X"]=base.win.getPointer(0).getX()
#self.mousePos["Y"]=base.win.getPointer(0).getY()
# p=base.mouseWatcherNode.getMouse()
# base.win.movePointer(0, self.mousePos["X2"], self.mousePos["Y2"])
#print "X:",x," Y:",y
#base.camera.setX(base.camera.getX()+x*10)
# if x > 0:
# angelDegrees = self.camPos["W"] / (pi / 180.0) + 5.0
# self.camPos["W"] = angelDegrees * (pi / 180.0)
# if x < 0:
# angelDegrees = self.camPos["W"] / (pi / 180.0) - 5.0
# self.camPos["W"] = angelDegrees * (pi / 180.0)
#self.camera.setPos(20 * sin(self.camPos["W"]),-20.0 * cos(self.camPos["W"]), 3)
#base.camera.setZ(self.ralph.getZ()+(self.CamDist/30.0*10.0))
#sets the distance of the camera
#camvec = self.ralph.getPos() - base.camera.getPos()
#camvec.setZ(0)
#camdist = camvec.length()
#camvec.normalize()
#if (camdist > self.CamDist):
# base.camera.setPos(base.camera.getPos() + camvec*(camdist-self.CamDist))
# camdist = self.CamDist
#if (camdist < self.CamDist):
# base.camera.setPos(base.camera.getPos() - camvec*(self.CamDist-camdist))
# camdist = self.CamDist
#self.floater.setPos(self.ralph.getPos())
#self.floater.setZ(self.ralph.getZ() + 1.0)
#base.camera.lookAt(self.floater)
return Task.cont
def jump(self):
if self.jumpCalc["Activ"]==0:
return
jumphight=0.1
if(self.jumpCalc["Time"] > 0):
Sequence(self.ralph.jumpUp).start()
#if(self.jumpCalc["Time"] > 0.2):
# Sequence(self.ralph.jumpDown).start()
if(self.jumpCalc["Time"] > 0.3):
self.jumpCalc["Time"] = 0
self.jumpCalc["Activ"] = 0
self.jumpCalc["Time"]+= globalClock.getDt()
def thirdPersonCameraTask(self,task):
md = base.win.getPointer(0)
x = md.getX()
y = md.getY()
if base.win.movePointer(0, 300, 300):
self.heading = self.heading - (x - 300) * 0.5
self.pitch = self.pitch - (y - 300) * 0.5
if self.pitch > 90:
self.pitch = 90
if self.pitch < 0:
self.pitch = 0
self.camnode.setHpr(self.heading, self.pitch,0)
return task.cont
app = MyApp()
app.run()
2 screens:
an other question:
on the second screen you can see that the actor is standing in the ground
how can i fix that ?
I would be happy about some comments
sorry for bad englisch, german …