首先贴一段代码:
from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
import random
class Application(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.cam.setPos(0,-50,10)
self.setupCD()
self.addSmiley()
self.addFloor()
taskMgr.add(self.updateSmiley,"UpdateSmiley")
#add the method that initializes the collision detection system
def setupCD(self):
'''
base is the __builtin__ variable
'''
base.cTrav=CollisionTraverser()
base.cTrav.showCollisions(render)
self.notifier=CollisionHandlerEvent()
self.notifier.addInPattern("%fn-in-%in")
self.accept("frowney-in-floor",self.onCollision)
#implement the method for adding the frowney model to the scene
def addSmiley(self):
self.frowney=loader.loadModel("frowney")
self.ballpath=render.attachNewNode("ballcenter")
self.frowney.reparentTo(self.ballpath)
self.frowney.setPos(0,0,10)
self.frowney.setPythonTag("velocity",0)
col=self.frowney.attachNewNode(CollisionNode("frowney"))
col.node().addSolid(CollisionSphere(0,0,0,1.1))
col.show()
base.cTrav.addCollider(col,self.notifier)
#add a floor plane to the scene and handle the collision response
def addFloor(self):
floor=render.attachNewNode(CollisionNode("floor"))
floor.node().addSolid(CollisionPlane(Plane(Vec3(0,0,1),Point3(0,0,0))))
floor.show()
def onCollision(self,entry):
vel=random.uniform(0.01,0.2)
self.frowney.setPythonTag("velocity",vel)
#make the frrowney model bounce up and down
def updateSmiley(self,task):
vel=self.frowney.getPythonTag("velocity")
z=self.frowney.getZ()
self.frowney.setZ(z+vel)
vel-=0.001
self.frowney.setPythonTag("velocity",vel)
return task.cont
a=Application()
run()
最让人困惑的可能是两个加红的中间addSmiley的函数了。下面简单的介绍一下addSmiley创建模型,挂载模型到render,挂载碰撞体到模型的过程。
如上面所说addSmiley首先创建模型由如下代码完成
self.frowney=loader.loadModel("frowney")
这里loader.loadModel返回的是NodePath是PandaNode的handle
然后挂载模型到render完成显示由如下代码完成
self.ballpath=render.attachNewNode("ballcenter")
self.frowney.reparetoTo(self.ballpath)
其中self.ballpath是中心在(0,0,0)点的NodePath,这是panda3d的常用技巧在之后的对self.frowney 的调整就是相对于self.ballpath了。
下面介绍挂载一个球星碰撞体到frowney模型的方法,由如下代码完成
col=self.frowney.attachNewNode(CollisionNode("frowney"))
col.node().addSolid(CollisionSphere(0,0,0,1.1))
加载了名为“frowney”的CollisionNode到self.frowney上,这样CollisionNode可以跟随self.frowney所代表的模型一同运动了,然后再CollisionNode中加入CollisonSphere这样碰撞体就为一个碰撞球。
从上面对addSmiley函数的解析中可以看出panda3d的组织结构:
以PandaNode为载体可以加载相应的性质,而加载的对象又以PandaNode为载体加载相应的属性对象(如这里的碰撞球的加载)。给出继承关系帮助大家理解:
PandaNode:
CollisionNode:为可以加载不同碰撞体类型(CollisionSolid类)的类
CollisionSolid: