PANDA3D入门
----------古道天马
一、前言
这个就是我自学的总结。
因为刚开始瞧PANDA3D的教程,发现在瞧天书,静下心来学后,感觉其实就是教程不够深入浅出,没有照顾我们这些一点基础都没有的初学者。因此,把我自学的一点心得记录下来,便于自己及她人参考。
学习PANDA3D的目的就是编制一个三维的设备管理程序。嫌C#运行效率低下,C++的语言不够简练,瞧好了PYTHON编程。百度了一下,PYTHON的3D图形库有PYGLET,PANDA3D,BLENDER等,最初就是想用BLENDER,但就是BELNDER侧重于建模,于我的用途不太符合。改用PYGLET的,瞧中它也就是很简练的库,后来发现PYGLET缺乏维护,教程也少。因此转向PANDA3D,PANDA3D的教程以及维护要完善的多。
但就是按网上的说法,学习曲线就是比较陡峭的。果然,刚开始时一头雾水,经过查阅官方教程后,又通过自己一点点的实验与摸索,稍微有点头绪了。顺便提一下,我的PYTHON与PANDA3D就是同步学的,都在初级阶段。这里侧重写PANDA3D的特点,PYTHON的略微提到些。
注意:这不就是手册,很多进阶的东东请查官网手册。
二、安装
我的系统就是WIN7 64位,安装PYTHON的2、7、6版本32位版,
PANDA3D的1、8、1版本(自带2、7、3版本的PYTHON)。
打开“开始”菜单,运行PANDA3D下的范例文件,第一个范例就是
ASTEROIDS,小行星。
点击“Run Asteroids”,出现游戏界面
这说明PANDA3D内含的PYTHON2、7、3已经可以运行了。
现在,大家肯定都迫不及待的要瞧瞧源代码了吧。
点击View Source Code
出现文件夹
点击Tut-Asteroids、py,结果出现提示没有找到模块,说明您的PYTHON2、7、6还没找到PANDA3D的模块。那么按下面的方法做。
在C:\Python27\Lib\site-packages的目录下,建一个PANDA、PTH的文件,用写字本添加下列文本(这里的文件路径就是默认的,如果您修改过的话,根据实际情况调整)
C:\Panda3D-1、8、1
C:\Panda3D-1、8、1/direct/src/actor
C:\Panda3D-1、8、1/direct/src/cluster
C:\Panda3D-1、8、1/direct/src/controls
C:\Panda3D-1、8、1/direct/src/directbase
C:\Panda3D-1、8、1/direct/src/directdevices
C:\Panda3D-1、8、1/direct/src/directnotify
C:\Panda3D-1、8、1/direct/src/directscripts
C:\Panda3D-1、8、1/direct/src/directtools
C:\Panda3D-1、8、1/direct/src/directutil
C:\Panda3D-1、8、1/direct/src/distributed
C:\Panda3D-1、8、1/direct/src/extensions
C:\Panda3D-1、8、1/direct/src/extensions_native C:\Panda3D-1、8、1/direct/src/ffi
C:\Panda3D-1、8、1/direct/src/fsm
C:\Panda3D-1、8、1/direct/src/gui
C:\Panda3D-1、8、1/direct/src/interval
C:\Panda3D-1、8、1/direct/src/leveleditor
C:\Panda3D-1、8、1/direct/src/motiontrail
C:\Panda3D-1、8、1/direct/src/particles
C:\Panda3D-1、8、1/direct/src/physics
C:\Panda3D-1、8、1/direct/src/pyinst
C:\Panda3D-1、8、1/direct/src/showbase
C:\Panda3D-1、8、1/direct/src/showutil
C:\Panda3D-1、8、1/direct/src/task
C:\Panda3D-1、8、1/direct/src/tkpanels
C:\Panda3D-1、8、1/direct/src/tkwidgets
C:\Panda3D-1、8、1/bin
再次点击Tut-Asteroids、py,瞧瞧就是否成功运行。
三、正式开始
现在安装工作已经完成,我们可以正式开始了。
右键Tut-Asteroids、py文件,用IDLE打开,我们可以瞧到源程序,按F5可以调试运行。
不过拿这个源程序作为我们的开端,显然就是不合适。
3、1 第一个PANDA程序
现在我们开始编写第一个PANDA3D程序。
第一个程序,当然要简单粗暴些。
新建一个TEST、PY(注:PANDA3D似乎不支持中文目录,所以您的程序不要放在中文目录下),
用IDLE编辑(原则上您也可以用其它文本编辑器编辑)
输入以下两行
import direct、directbase、DirectStart
run()
CTRL-S保存,F5运行(顺便提一下,PYTHON2、7以前的IDLE就是不支持右键复制黏贴的,不用快捷键会很蛋疼,2、7的版本就是懒人的福音)
出现一个灰色的空窗口,比较简陋些,不过作为第一个程序已经够了。
根据官网的解释,
第一句import direct、directbase、DirectStart,建立ShowBase的实例
第二句run(),循环运行ShowBase实例,监视键盘鼠标输入,并反馈。
(试试:如果删了RUN()会咋样?)
老版本的PANDA的语法就是这样写的。
from direct、showbase、ShowBase import ShowBase
p3dApp = ShowBase()
p3dApp、run()
这里的ShowBase就是显式的,新的语法里都简化了。有兴趣的话,您可以打开C:\Panda3D-1、8、1\direct\directbase瞧瞧里面的源程序。
不过,本着初学者够用就行的态度,咱们就不用深究这些了,只要记住这两句的作用如下:
import direct、directbase、DirectStart # 建立舞台
run() # 演出开始了!
# 就是PYTHON的注释方法
保存时,程序会提示您有中文注释,要加# -*- coding: cp936 -*- ,同意它修改就好。
3、2 加料
灰色窗口太不起眼了,需要加点料,事实上只要加两行就能让它大变样。
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
environ = loader、loadModel("models/environment")
environ、reparentTo(render)
run() # 演出开始了!
F5出现
哈哈,两行代码就有这么大变化,:-O,厉害的!
还有更厉害的,试着按住鼠标左右键拖动瞧瞧!
默认的鼠标控制方式如下:(当然,这个控制方式很不人道)
Key Action
鼠标左键左右进行平移
鼠标右键前后移动
鼠标中键围绕程序的坐标原点进行旋转
鼠标右键与中键围绕视野中心轴进行滚动
对这两句代码的解释如下
第一句代码:
environ, 就是我们自行规定的一个变量,这个变量现在代表了我们在等号后面导入的模型。loader、loadModel( ),它的作用就是导入一个模型。(注意:PYTHON对大小写敏感)
这句代码稀奇的就是,我们并没有新建这个模型,可就是却可以导入这个模型。那么这个模型在哪里呢?原来,这个模型在C:\Panda3D-1、8、1\models 下,文件名为environment、egg、pz。
(注意:在代码里面的文件路径用的就是LINUX的斜杠”/ ”,与WIN下的反斜杠” \ ”不一样)
这个*、pz文件,就是一种压缩格式,后面会提到。
这里我们只要理解了,程序在默认的文件夹下找到了environment的模型文件。当然,这个文件有可能就是environment、egg、pz或者environment、egg或者environment、bam。(试试,将C:\Panda3D-1、8、1\models 下的environment、egg、pz改名或者挪个位置)
事实上,如果我们在程序所在文件夹下新建一个models文件夹并将environment、egg、pz拷贝在此文件夹下,程序同样可以找到模型。
(想想,如果有两个同名模型会咋样?)
第二句代码:environ、reparentTo(render),意思就是将environ模型置于render节点下。节点就是个术语,就是为了更好的组织各个模型。模型只有置于节点下,才能被程序渲染。整个结构就是个树型表。
有个比较容易理解的比喻就是,将节点瞧成文件夹。Render就就是根目录C:,模型就就是文件,我们要瞧到模型,就必须把文件拷到C:(关于节点的用法,我们后面详述)。
当然,为了方便管理,我们可以在C:盘下建立目录,以及子目录,这种目录叫做空节点
四、创建模型
上面那个environment模型,超出了我们的理解能力。现在,我们试着自行建立一个模型。
在您程序所在文件夹下,创建一个models文件夹。
4、1 建立正方形
在models文件夹下,新建一个square、egg模型文件。
用记事本编辑square、egg,并拷入下列代码。
现在将我们的TEST、PY修改为
F5运行,咦,还就是没东东啊。
我们还需要加代码。
box、setPos(0,20,-3),含义就是将模型按其原点(0,0,0)对应PANDA3D坐标的(0,20,-3)的对应关系放置。
一个梯形。
如果您按住鼠标左键移动的话,会发现,原来就是个一个水平放置的正方形。
现在我们得了解一下PANDA3D 的坐标系以及EGG 文件了。
下面就是PANDA3D 的坐标系
从屏幕上瞧,就就是X 方向就是屏幕的宽,Z 方向就就是屏幕的高,Y 方向就就是屏幕的深了。
X
Y
Z
X
Y
Z
简单解释一下square、egg文件代码的含义
上面点的坐标就是相对模型空间的原点(0,0,0)的值,原点也就是setPos( )函数操作的点。
这句的意思就就是将box模型按照模型空间原点(0,0,0)对应屏幕空间点(0,20,-3)的方式放置。实践:
1)调整程序文件中的setPos()的参数,瞧瞧有什么变化。
2)模型文件中的增加或者减少多边型的点,改变点的坐标,改变多边形点的排列顺序,瞧瞧能否找到什么规律(注意,一次最好只改一项)
刚才我们在用鼠标移动那个水平放置的正方形时,会发现正方形移动到屏幕上方会消失。
这说明这个正方形就是有方向型的,它的反面就是不可见的。
模型的方向就是右手性的。
右手螺旋系
当然,PANDA的坐标系也就是右手性的。
反面不可见就是为了减少计算量,所以我们要确保多边形在正确的方向上,以免瞧不到。
4、2 建立正方体
现在我们可以通过修改EGG文件来创建一个正方体模型了。
在MODELS文件夹下新建CUBE、EGG文件。
小心调整方向后,我们得到下面这些代码。
1、0 1、0 -1、0
}
1、0 -1、0 -1、0
}
-1、0 -1、0 -1、0
}
-1、0 1、0 -1、0
}
1、0 1、0 1、0
}
1、0 -1、0 1、0
}
-1、0 -1、0 1、0
}
-1、0 1、0 1、0
}
}
}
}
}
}
}
}
}
因为模型名字变了,所以在我们的TEST、PY中将模型改为cube box = loader、loadModel("models/cube") # 导入模型
4、3 增加颜色
一个纯白的正方体,太朴素了,我们给它加点颜色
修改cube、egg文件,在顶点1的属性中加入一行颜色。
1、0 -1、0 -1、0
}
我们给顶点1 变成红色,
现在我们得到一个有一个红角的正方体。
注意中间的粉色,就是通过对4个顶点的颜色插值得到的。
试着修改其它点的颜色吧。
注意白色就是
这就是我得到一个混色正方体。
4、4 调整比例
在PANDA3D中我们可以随意设置模型的三个方向的比例尺。
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
box、setPos(0,20,-3) #设置BOX的原点位置
box、setScale(0、5, 0、5, 0、5) #设置BOX的三个方向的比例尺,对模型放大缩小
run() # 演出开始了!
您可以试试通过setScale( )把正方体变成长方体。
五、镜头
首先我们可以想象我们就是通过一个镜头在观察模型。事实上,PANDA3D中确实有这个镜头。
如果您对镜头的具体数据不关心的话,您可以跳到5、3。
5、1 近距
我们知道,如果模型在镜头之后(Y<0),显然就是不可见的。但就是模型在镜头之前就必定被渲染了么?
下面我们做个试验来测试一下。
我们设计一个正方形,它在模型空间的Y值为0, 放置于屏幕空间就会平行于屏幕。Square、egg文件如下:
Test、py如下
box、reparentTo(render)
box、setPos(0,16,0)
run()
下面我们调整setPos( ) 的Y值
注意当Y值变化时,这个2*2的正方形的视觉变化;
Y=16 Y=8 Y=4
Y=2、9 Y= 1、0000001 Y=1
从这个试验,我们大致可以得到两个结论:
1)Y<=1时,模型不会被渲染(如果模型的部分区域Y<=1,则这部分会被裁减,其余部分仍可见)
2)Y>1时,模型会被渲染(跟据我的两台电脑,双显卡应该就是Y>1、00000018左右,单显卡Y>1、00000006,当然这个值意义不大)
3)Y=1、0000001时,正方形出现惊人的效果,一半可见,一半不可见(这大概就是因为双显卡交火的问题,我在笔记本上未发现此现象)。
Y=1,这个参数叫做镜头的近距(near distance),PANDA默认比这个距离更贴近镜头的物体区域就是不可见的。
5、2 视场
在上面那个实验中,Y在2、8左右时,2*2的正方形差不多撑满窗口屏幕宽度(默认窗口模式(4:3),非全屏)。
按照三角公式
Tan(α/2)=1/2、8
计算出α大约为39、3度。
这个角度叫做镜头的视场(field of view)。PANDA3D官方给的数据就是默认为40度。大致就是全画幅的60mm镜头。
当然,如果显示比例为16:9,或者16:10,视场也扩大
问题:在非常规窗口比例中,视场为多少?
我们可以将Y=3、8,然后用鼠标对窗口进行变形。
4:3 近似16:9 1:2
可以瞧出PANDA将宽与高的视场限制为不小于约30度。也就就是默认的宽视场。
就上面的例子而言,得到的效果就就是,无论您如何变换窗口,都无法遮住正方形,而且正方形也不会产生形变。
5、3 镜头的位置
这个就是我们最常用的镜头参数。
现在我们来显式的控制我们的镜头。
回到我们的立方体的例子
在TEST、PY里,我们首先禁止鼠标控制镜头
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
base、disableMouse() # 禁止鼠标控制镜头
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
box、setPos(0,20,0) #设置BOX的原点位置
run() # 演出开始了!
现在,镜头不能动了。
目的就是为了减少控制冲突,两个鼠标一起动的感觉您懂的。
这下瞧不到立方体的上面了,咋办呢。
把镜头挪挪吧。
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
base、disableMouse() # 禁止鼠标控制镜头
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
box、setPos(0,20,0) #设置BOX的原点位置
camera、setPos(0,0,3) # 设置镜头的位置
run() # 演出开始了!
六、任务
下面
现在我们要设计一段代码,让我们的镜头动起来。
基本思路就是隔一秒,镜头进1。
注意: 根据PYTHON的规定,缩进就是很讲究的,如果下面的程序拷到test、PY后运行出错,一般就是因为缩进不符合PYTHON的规定。请用TAB键而不就是空格键来控制缩进。
# -*- coding: cp936 -*-
import time
import direct、directbase、DirectStart # 建立舞台
base、disableMouse() # 禁止鼠标控制镜头
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
box、setPos(0,20,0) #设置BOX的原点位置
for i in range(10):
time、sleep(1)
camera、setPos(0,i,3)
run() # 演出开始了!
在10秒黑屏后突兀出现了最后的画面。
离我们的理想有差距啊。
问题在哪里呢
我们的镜头变换循环并不与渲染同步进行。镜头变换完后才进行的渲染。
现在我们需要引入一个工具。
Task 任务
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
from direct、task import Task # 建立任务表
base、disableMouse() # 禁止鼠标控制镜头
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
上面这个办法比较笨的实现了镜头的前进。一跳一跳的。
为了顺畅的运行,我将步进改为0、01秒, 同时规定镜头移动10后停止。
# -*- coding: cp936 -*-
import direct、directbase、DirectStart # 建立舞台
from direct、task import Task # 建立任务表
base、disableMouse() # 禁止鼠标控制镜头
box = loader、loadModel("models/cube") # 导入模型
box、reparentTo(render) # 将模型加入渲染列表
box、setPos(0,20,0) #设置BOX的原点位置
CamY = 0
def Task1(task):
global CamY
camera、setPos(0,CamY,3)
CamY = CamY +0、01 # 步进改为0、01
task、delayTime = 0、01 # 延迟改为0、01秒
if CamY > 10:
return Task、done # 任务停止
else:
瞧着不错。不过有个问题,有点慢,预计10秒就该完成的任务用了17秒。咋回事呢?为了解决这个问题,我们换个方式
与setY类似的有setX(),setY(),setZ(),setH(),setP(),setR()等等
详见:
建议对每个函数都用一下,熟悉她们的用法。
将上个test、py中的Task1任务,旋转方向做调整,也可以将旋转对象改为box、def Task1(task):
CamY = task、time #task、time从任务开始时计时,以秒为单位,
box、setH(CamY)
if CamY > 100:
return Task、done # 任务停止
else:
return Task、cont #下一帧继续
瞧瞧效果。
《jQuery前端开发实战教程》试卷 得分 单选题(每题2分,共计30分) 1.页面中存在可见元素div,代码“if( $("div").show().is(:animated) ){ $("div").hide(1000); }” 的执行效果是() A、元素以动画效果隐藏 B、元素没有任何变化 C、元素无动画效果隐藏 D、元素先以动画效果隐藏,再无动画形式显示 2.关于代码“$.fn.test = function() { };”,下列说法错误的是() A、test方法可以被jQuery对象调用 B、test方法被jQuery对象调用时,this指向调用该方法的jQuery对象 C、在test方法中可以书写代码“return this”来实现链式编程 D、$.fn是jQuery原型对象jQuery.prototype的简写3.jQuery Mobile选择菜单中,当选择菜单中含有多个类别时,可添加()元素,让jQuery Mobile根据此元素中label属性的文本创建含有分割项的选项。 A、label B、optgroup C、select D、option 4.在使用tree组件时,dnd属性和lines属性设置为true分别代表()含义。 A、显示横线条显示竖线条 B、显示竖线条显示横线条 C、表示可拖动表示可拖拽 D、表示可拖动表示显示竖线条 5.下列哪种方法不可以让元素设置为不可见() A、fadeIn B、fadeOut C、fadeTo D、hide 总分题型单选题多选题填空题简答题题分 得分
6.在jQuery Mobile列表视图中,可以将任意大小的图片自动缩放到()像素,展示到列表中。 A、60 B、70 C、80 D、90 7.跟jQuery相继诞生的JavaScript库还有很多,不包括() A、Prototype B、ExtJS C、YUI D、node.js 8.下面选项中this的使用说法正确的是() A、this指向当前元素 B、this可以用来绑定事件 C、this可以获取到所有元素 D、this是一种方法9.使用animate方法实现与代码$("div").fadeIn(600)相同效果的代码写法是() A、$("div").animate({"opacity":"1"}) B、$("div").animate({"opacity":"1"},"fast") C、$("div").animate({"opacity":"1"},600) D、$("div").animate({"opacity":"1"},"normal") 10.从EasyUI网站下载到的“jquery-easyui-1.5.4.2.zip”压缩包解压,保存到“chapter08\ easyui-1.5.4.2”目录中下面说法错误的是() A、locale目录是国际化资源文件包 B、plugins是插件包目录 C、jsrc是源码包目录 D、demo和demo-mobile目录都是样例,没有区别 11.在jQuery事件中,当调整浏览器窗口时触发的事件是()事件。 A、resize() B、change() C、scroll() D、select()
2020年中国游戏产业报告 如果有人要写中国游戏行业发展史,20xx年可能是具有节点意义的一年。这一年,移动游戏的市场份额第一次超过客户端游戏,成为份额最大的细分市场。下文是小编收集的关于中国游戏产业的分析报告,欢迎阅读!中国游戏产业报告 如果有人要写中国游戏行业发展史,20xx年可能是具有节点意义的一年。 这一年,移动游戏的市场份额第一次超过客户端游戏,成为份额最大的细分市场。 游戏产业年会上,中国音数协游戏工委(GPC)、伽马数据(CNG 中新游戏研究)、国际数据公司(IDC)发布了《20xx中国游戏产业报告》。报告总结了游戏行业这一年的发展状况,覆盖市场份额、代表性产品、典型企业以及游戏相关文化等方向。 报告体现了一些趋势和变化,有些在我们的意料之中,比如端游份额的负增长、电竞行业的快速发展;有些虽然不算太意外但可能来得快了很多,或是程度上出乎意料,比如直播的迅猛上升、比如普遍认为卡牌手游日渐式微的时候出现了《阴阳师》这样能引起广泛话题性的产品。 以上数据及观点出自伽马数据(CNG中新游戏研究)撰写的《20xx 年中国游戏产业报告(摘要版)》。
819亿元,手游份额首次超过端游 按细分市场划分,20xx年移动游戏市场销售收入为819.2亿元,占比超过客户端游戏市场,达到49.5%,成为份额最大、增速最快的细分市场。 与此同时,端游销售收入在近20xx年中首次出现负增长,相比20xx年的611.6亿元,20xx年端游市场582.5亿元的收入下降了4.8%。 不论是近几年移动硬件的发展、移动端原生用户的增长,还是国内厂商的普遍布局、以及产品和用户日益明显的硬核趋向,都在清晰地告诉我们----手游的份额超过端游只是时间问题。只不过,对于非移动端原生用户和从业者来说,这个时间也许比主观上预想早了些。 尽管国内游戏市场还远未饱和,但“此消彼长”的状态还是切实存在的。移动游戏较短的投入-回报周期展现了更多的商机,相比之下端游的高投入高风险势必会成为更谨慎的大厂玩法。而腾讯网易之类的典型厂商都将重心转移到了移动端,这些业内有目共睹。不少端游IP改编的手游也分流了一些用户,这也对已成存量市场的端游领域造成了一定冲击。 此外,纵观全年能在国内游戏行业引起热议的几个现象级新品,诸如《Pokemon Go》《阴阳师》《王者荣耀》和《守望先锋》等,也多以手游为主,一定程度上也从侧面反映了端游领域后继乏力的事实。 占比30%的电竞市场和正在兴起的移动电竞 最近几年,电子竞技的快速发展并不是什么让人意外的事儿。对
jQuery入门[1]-构造函数 https://www.doczj.com/doc/7c10068802.html,/archive/2008/03/05/1091816.html jQuery优点 ?体积小(v1.2.3 15kb) ?丰富的DOM选择器(CSS1-3 + XPath) ?跨浏览器(IE6,FF,Safari,Opera) ?链式代码 ?强大的事件、样式支持 ?强大的AJAX功能 ?易于扩展,插件丰富 jQuery的构造函数接收四种类型的参数: jQuery(expression,context) jQuery(html) jQuery(elements) jQuery(fn) 第一种根据表达式(ID,DOM元素名,CSS表达式,XPath表达式)找出文档中的元素,并组装成一个jQuery对象返回。 DEMO: DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.doczj.com/doc/7c10068802.html,/TR/xhtml1/DTD/xhtml1-transitional.dtd">