首先尝试在命令窗口中使用Python调用Panda3D。

打开任意编辑器,在其中输入以下内容:

import direct.directbase.DirectStart

run()

将该文件命名为myscript.py,保存在某个目录中,例如C:\Temp或/root。注意一定要以Python能够识别的格式进行保存,例如,最简单的UTF-8格式,支持CR/LF终结符。随后,在命令窗口中,进入文件所在目录C:\Temp或/root,输入执行命令,如果没有配置问题,Panda3D将通过运行myscript.py启动,如图2.4~2.5所示。执行命令为:

python myscript.py

如果运行异常,需要检查Panda3D和Python配置,在Windows中主要是通过修改Path变量加以解决,在Linux中主要是通过安装缺少的软件包加以解决。

当然,这两行Python脚本只能让Panda3D弹出一个非常简单的窗口。


文件myscript.py可在DVD的Ch2目录Python子目录下找到(代码文件非DOS格式,建议用UltraEdit等通用编辑器打开,不要转换格式,全书类似情况处理方法相同)。

接下来,我们用Python开发一个小的脚本,创建一片青葱绿地和竹林,让憨态可掬的熊猫在那里来回溜达溜达,向大家问个好,就是“你好,大熊猫”。

打开编辑器,创建一系列名称为HelloPanda3D-0X.py的脚本,按步骤编辑代码。

Panda3D引擎典型的Python代码程序段结构是(HelloPanda3D-01.py):

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

def __init__(self):

ShowBase.__init__(self)

#其他代码

app = MyApp()

app.run()

上述代码继承ShowBase创建主程序类MyApp。ShowBase类会自动加载大部分Panda3D模块。其中的run()函数构成游戏引擎的主循环,渲染主框架,处理后台任务。一般不返回,只需在脚本最后一行进行调用。在myscript.py中,我们曾通过导入DirectStart使用ShowBase的__builtin__进行实例化,以后还是尽量使用面向对象开发模式,派生专门的应用子类,更为清晰可读。

启动Panda3D引擎后,主要使用数据结构访问控制各种游戏元素。其中,Scene Graph以树的方式容纳各种需要渲染的对象。树的根对象是Render。场景对象则通过reparentTo()设置自己的父实例。随后,使用setScale()、setPos()调整模型比例和位置。将代码修改如下(HelloPanda3D-02.py):

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

def __init__(self):

ShowBase.__init__(self)

# 载入环境模型

self.environ = self.loader.loadModel("models/environment")

# 设置环境模型的父实例

self.environ.reparentTo(self.render)

# 对模型进行比例及位置调整

self.environ.setScale(0.25, 0.25, 0.25)

self.environ.setPos(-8, 42, 0)

app = MyApp()

app.run()

执行HelloPanda3D-02.py后,显示如图2.6所示的青葱绿地和竹林。用鼠标在场景中拖动,可以转换场景的不同视角。有关动画视频可以在配书光盘的Ch2目录Python子目录中找到(HelloPanda3D-02.mp4)。值得一提的是,文件目录使用的是正斜杠“/”,Panda3D使用的是地理坐标系统,环境文件environment是以“egg”格式记录保存的三维模型,俗称“蛋”。详细情况以后说明。


用鼠标控制场景也称为相机控制,默认情况下,控制效果如表2.2所示。

表2.2  默认相机控制方法

鼠标按键

相机控制效果

左键

左移或右移

右键

远近移动(前移或后移)

中间键

绕原点旋转

右键 + 中间键

沿轴线旋转

在游戏中,相机控制需要通过编程来实现。常用方法是通知任务管理器在每一帧场景中调用相机控制函数。假设现在需要旋转相机,应该编写以下代码(HelloPanda3D-03.py):

from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# 载入环境模型
self.environ = self.loader.loadModel("models/environment")
# 设置环境模型的父实例
self.environ.reparentTo(self.render)
# 对模型进行比例及位置调整
self.environ.setScale(0.25, 0.25, 0.25)
self.environ.setPos(-8, 42, 0)
# 通知任务管理器调用SpinCameraTask控制相机
self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
# 定义旋转相机
def spinCameraTask(self, task):
angleDegrees = task.time * 6.0
angleRadians = angleDegrees * (pi / 180.0)
self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
self.camera.setHpr(angleDegrees, 0, 0)
return Task.cont
app = MyApp()
app.run()
其中,taskMgr.add()指定了相机控制函数,在处理每帧场景时加以调用。在上述相机控制函数中,系统根据已经流逝的时间计算相机距离原点的角度和半径,然后通过调用setPos()设置相机位置、setHpr()设置相机方向,每秒旋转6度。有关动画视频可以在配书光盘的Ch2目录Python子目录中找到(HelloPanda3D-03.mp4)。
角色是游戏中的另一个要素,Panda3D通过Actor类载入。场景一般是静态的,通过loadModel()载入。角色一般是动态的,输入参数是角色模型、容纳构造动画时使用的一系列文件名称的字典。
假设需要在场景中引入一只熊猫,应该编写以下代码(HelloPanda3D-04.py):
from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# 载入环境模型
self.environ = self.loader.loadModel("models/environment")
# 设置环境模型的父实例
self.environ.reparentTo(self.render)
# 对模型进行比例及位置调整
self.environ.setScale(0.25, 0.25, 0.25)
self.environ.setPos(-8, 42, 0)
# 通知任务管理器调用SpinCameraTask控制相机
self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
# 载入熊猫角色
self.pandaActor = Actor("models/panda-model",
{"walk": "models/panda-walk4"})
self.pandaActor.setScale(0.005, 0.005, 0.005)
self.pandaActor.reparentTo(self.render)
# 动画循环
self.pandaActor.loop("walk")
# 定义旋转相机
def spinCameraTask(self, task):
angleDegrees = task.time * 6.0
angleRadians = angleDegrees * (pi / 180.0)
self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
self.camera.setHpr(angleDegrees, 0, 0)
return Task.cont
app = MyApp()
app.run()
上述代码中,载入角色后,调用setScale()设置比例、reparentTo()设置父实例。调用loop()开始循环。有关动画视频HelloPanda3D-04.mp4可以在配书光盘中Ch2目录的Python子目录下找到。
Panda3D游戏引擎运行中两个重要的概念是“幕”和“情节”。“幕”是按照给定的时间间隔修改属性值的任务,一般通过后台进程完成。“情节”是一幕接一幕地执行一系列任务。分别表示为Intervals和Sequences。通过“幕”和“情节”,游戏开发人员能够实现不同的关卡。现在编写以下代码(HelloPanda3D-05.py):
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 Sequence
from panda3d.core import Point3
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# 禁用鼠标
self.disableMouse()
# 载入环境模型
self.environ = self.loader.loadModel("models/environment")
# 设置环境模型的父实例
self.environ.reparentTo(self.render)
# 对模型进行比例及位置调整
self.environ.setScale(0.25, 0.25, 0.25)
self.environ.setPos(-8, 42, 0)
# 通知任务管理器调用SpinCameraTask控制相机
self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")
# 载入熊猫角色
self.pandaActor = Actor("models/panda-model",
{"walk": "models/panda-walk4"})
self.pandaActor.setScale(0.005, 0.005, 0.005)
self.pandaActor.reparentTo(self.render)
# 动画循环
self.pandaActor.loop("walk")
# 创建四幕
PosInterval1 = self.pandaActor.posInterval(13,
Point3(0, -10, 0),
startPos=Point3(0, 10, 0))
PosInterval2 = self.pandaActor.posInterval(13,
Point3(0, 10, 0),
startPos=Point3(0, -10, 0))
HprInterval1 = self.pandaActor.hprInterval(3,
Point3(180, 0, 0),
startHpr=Point3(0, 0, 0))
HprInterval2 = self.pandaActor.hprInterval(3,
Point3(0, 0, 0),
startHpr=Point3(180, 0, 0))
# 创建情节并运行四幕
self.pandaPace = Sequence(PosInterval1,
HprInterval1,
PosInterval2,
HprInterval2,
name="pandaPace")
self.pandaPace.loop()
# 定义旋转相机
def spinCameraTask(self, task):
angleDegrees = task.time * 6.0
angleRadians = angleDegrees * (pi / 180.0)
self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
self.camera.setHpr(angleDegrees, 0, 0)
return Task.cont
app os= MyApp()
app.run()

上述代码中,幕PosInterval1开始后,熊猫将用13秒时间从三维坐标(0, 10, 0)移动到(0, -10, 0);幕PosInterval2开始后,熊猫将用13秒时间从三维坐标(0, -10, 0)移回到(0, 10, 0);幕HprInterval1开始后,熊猫将用3秒时间从方向(0, 0, 0)转动到(180, 0, 0);幕HprInterval2开始后,熊猫将用3秒时间从方向(180, 0, 0)转回到(0, 0, 0)。整个情节由这四幕依次构成,命名为pandaPace。情节由pandaPace.loop()启动。有关动画视频可以在配书光盘的Ch2目录Python子目录中找到(HelloPanda3D-05.mp4)。

整个脚本参看HelloPanda3D.py,运行效果如图2.7所示。本书所有视频文件推荐使用免费软件“完美者解码”(PotPlayer)观看。