里约残奥会乒乓球冠军:Blender游戏的基础教程

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 12:04:46

引用:

本译文中的“命令”与“函数”的意义相同。——译者注。

让我们从最简单的开始:

启动你的blender,并且分割视图,把右边的视图设置为python文本编辑器。现在输入下面的这些:
代码:

print "hello"
 


给这个脚本起名为“starter”。现在选择默认存在的plane并且给它添加一个always sensor,和一个python controller(以"starter"为脚本),并把它们连接起来。
把鼠标放在3D视图种,按下 P ,然后按Esc并且查看你的blender控制台窗口,应该会看到输出了N多遍的“hello”。刚才这只是标准而经典的输出命令,如果除了输出无聊的字符串以外还能做点别的那会更有用。
删除原来那行,输入这些:
代码:

print dir(GameLogic)
 


把鼠标放在3D视图种,按下 P ,然后看看你的blender控制台窗口。对于那条命令如果你还没看明白,那么其中 dir 含义是 directory ,而 GameLogic 是包含了游戏引擎里各种命令的对象,dir命令会把其中所包括的命令输出出来。现在你会看到 GameLogic 所包含的所有命令,其中比较常用的是“getCurrentController”命令。那么现在把你的代码改成这样:
代码:

print dir(GameLogic.getCurrentController)
 


按下 P 并看看你的控制台窗口。你不仅可以输出 GameLogic 的所有命令,也可以输出它所有的子命令。当你想要得到actuator或sensor的命令列表是这一点就会很有用了。刚才那样的代码会把命令列表输出大约20次以上,因为 ALWAYS sensors 一直在反复运行那段脚本,所以只看最下面的输出就可以了。(其实对于always sensor,如果你让其中的两个按钮都处于弹起的状态,那么它所连的脚本就只会执行一次。——译者注)

想要知道 getCurrentController 的含义对吗?
它可以得到和python controller 相连的任何物体的信息,在这个例子里,和这个 python controller 相连的是默认存在的 plane 。
那么它有什么用呢?
恩……当我们得到 controller 之后,我们可以得到相连的那些 sensor 和 actuator 并且改变它们。我们也可以得到拥有这个 controller 的物体,并且改变这个物体的 propertie、位置、旋转状况,任何东东。那么让我们从更多的代码开始吧,把你的代码改成这样:
代码:

cont = GameLogic.getCurrentController()
own = cont.getOwner()
 


“cont”只不过是变量的名字(你也可以换个名字),不过这第一行可以让我们以后需要的时候不必都打 “GameLogic.getCurrentController()” 这么长的一段了。另外这行末尾有一对圆括号,这是因为如果没有这对圆括号的话就会出错(lol 我一直不知道这到底是为什么,有的命令需要一对空的圆括号才能正常工作,不过别管它,就这样吧)。(这个……我个人认为这个需要圆括号是因为它是成员函数而不是成员变量……。——译者注;)不管怎么样,现在“cont”就是一个包含了那个python controller的所有信息的变量了。
现在,关于 own ,这个变量里包含的是那个python controller的拥有者(也就是拥有这个controller的物体——译者注),换句话说,它里面是包含了这个python controller的物体。这两行是最基本的代码,并且在大多数的脚本里都应该在开头放上这两行(指任何需要访问物体或逻辑块的信息的脚本)。另外,代码里的空格不会带来什么问题,你可以有一个空格如“x = 1”或者没有,如“x=1”。

为了得到点乐趣,在这些代码下面输入:
代码:

print dir(cont)
 


按下 P ,看看控制台窗口。你会发现它会向你显示出一些供你使用的有趣的命令。那么让我们来试一个。给默认的 plane 添加一个新的 actuator ,设置为 motion actuator,并且把它和 python controller 连接起来。把这个 actuator 重命名为 “move”。现在在文本编辑视图里,在现有的代码之下输入这些:
代码:

move = cont.getActuator("move")
 


这行代码得到了与 python controller 相连的actuator,并且允许我们访问它来进行某些操作。这里dir命令可以再次给予我们帮助。接下来输入:
代码:

print dir(move)
 


按下 P,看看控制台窗口,看看有些什么好东东。Now choose your poison and lets move on, for sake of the tute, ill choose to use DLoc.(这句话不知道啥意思……——译者 -_-!)
去掉那行print代码,加入这些:
代码:

speed = move.getDLoc()[1]
 


这行代码获得了在actuator里设置的速度的Y轴分量(目前应该是0.0)。
这个“[1]”是做什么用的?恩……在这个actuator的DLoc部分里有4个值,x、y、z和local(也就是界面里末端的那个小按钮)(这4个值组成了一个数组,getDLoc函数返回的就是这个数组。——译者注)。Python里的数组下标从0开始,所以为了获得其中的Y值(数组的第二个元素),需要访问下标为1的元素(又例如: x=[0], y=[1], z=[2], and local=[3])。变量“speed”保存了actuator里DLoc部分的信息数组,如果 print dir(speed) ,它输出这样的数组 [0.0,0.0,0.0,1],所以在getDLoc之后使用 [1] 会返回其中的第二个元素,应该是0。(这句话似乎有问题……因为按照上面的代码,speed变量保存的应该是一个数组元素,我也不明白……——译者注)不管怎么样,让我们继续。

我们所要的,是让我们的plane逐渐地获得速度,而因为我们的脚本是“always”运行的,所以每次脚本运行时,我们就要增加一点速度。所以“speed”一行的下面输入:
代码:

speed = speed + 0.001
 


这行让speed的值增加0.001。现在我们需要用新的速度值来更新 actuator 。在最后一行下面输入:
代码:

move.setDLoc(0.0, speed, 0.0, 1)
 


现在我们的Y值就等于我们的speed值了。最后一件事,我们需要在游戏里激活这个新的值。所以接下来输入:
代码:

GameLogic.addActiveActuator(move,1)
 


这一行把 move actuator 加回游戏之中,而参数1是用来指明是要启用该actuator,还是关闭actuator而只是更新其中的值(其实这第二个参数是bool型的,用来指定第一个参数所指的actuator是启用还是关闭,True为启用,False为关闭。——译者注),我们这里是要启用它。现在按下 P ,如果一切正常那么你的plane应该会逐渐地获得Y轴上的速度。


所以你最终的 motion 脚本应该是这样的(记住脚本里是区分大小写的):
代码:

cont=GameLogic.getCurrentController()
own = cont.getOwner()
move = cont.getActuator("move")
speed = move.getDLoc()[1]

speed = speed + 0.001
move.setDLoc(0.0, speed, 0.0, 1)
GameLogic.addActiveActuator(move,1)
 

 

Now lets get crazy with this script.(不知道该如何翻译……——译者注 *^_^*)
给plane增加一个新的 property ,取名为“go”,并且给它赋初值为0。增加一个 keyboard sensor ,取名为“up”,在the prompt thing那按下向上的方向键。(这里的the prompt thing不知道该怎么翻译,反正这里就是在keyboard sensor里,先点一下“key”右边的空白方块,然后按下键盘上的有个键,这样这个keyboard sensor就会监控你所指定的那个键的状态了。——译者注)。把它和 python controller 连接起来。再增加另一个 keyboard sensor ,取名为“down”并且使它监视向下的方向键的状态。把它也和 python controller 连接起来。现在,在第三行下面,也就是“own”变量的下面,输入这两行:
代码:

pressup = cont.getSensor("up")
pressdown = cont.getSensor("down")
 


这两行获得了那两个 keyboard sensor 。现在,在“speed”变量的下面,“speed = speed+0.001”的上面加上这两行:
代码:

if pressup.isPositive():
   own.go = 1
elif pressdown.isPositive():
   own.go = 0
 


那么如果 press up sensor 被激活了(也就是向上的方向键被按下了),它就会把物体的 property “go” 赋值为1。而如果向下的方向键被按下了,就把物体的 property “go” 赋值为0。
现在我们需要仅在“go”等于1时才让物体有所动作。所以把代码重排为这个样子:
代码:

if own.go == 1:
   speed = speed + 0.001
   move.setDLoc(0.0, speed, 0.0, 1)
   GameLogic.addActiveActuator(move,1)
else:
   speed = 0
   move.setDLoc(0.0, speed, 0.0, 1)
   GameLogic.addActiveActuator(move,0)
 


OK,现在从头开始解释一下。如果 property “go” 等于1,那么就如以前那样执行脚本,增加 speed 并且移动我们的plane,但是如果“go”不等于1,那么就把speed重设为0并且把 actuator 关闭。


所以最终版本的脚本是这样的:
代码:

cont=GameLogic.getCurrentController()
own = cont.getOwner()
move = cont.getActuator("move")
speed = move.getDLoc()[1]

if pressup.isPositive():
   own.go = 1
elif pressdown.isPositive():
   own.go = 0

if own.go == 1:
   speed = speed + 0.001
   move.setDLoc(0.0, speed, 0.0, 1)
   GameLogic.addActiveActuator(move,1)
else:
   speed = 0
   move.setDLoc(0.0, speed, 0.0, 1)
   GameLogic.addActiveActuator(move,0)
 


 

 


最后浏览一下。前面4行设置了我们所需要的变量。接下来的两个“if”语句决定了“go”应该等于0还是1,而再接下来的两个判断语句在“go”等于1时会启用动作,而在“go”等于0时复位并关闭动作。

这里还有一些基本的信息:

关于数组(list,不过似乎python里这个都翻译为“列表”。——译者注):
数组是十分常用的数据结构。它把一些信息或变量简单的用方括号合在了一起。例如,getDLoc()函数返回一个数组如 [0, 0, 0, 1] 。要知道关于数组的更多信息,请阅读随python附带的文档。

布尔操作(if,elif,else,while):
~“if”语句非常简单。 if 条件成立,那么就做某事……
~“elif”语句是用在“if”语句之后的,它的含义是“如果之前的条件不成立而这个条件成立,那么就做某事……”(“elif”的含义其实就是“else if”。——译者注)。例如:如果没有按向上的方向键,但是向下的方向键被按下了,那么 own.go = 1。你可以在一个“if”语句之后接上多个“elif”。阅读python文档可以获得更多的信息。
~“else”的含义是“如果所有的条件都没有成立,那么就做某事……”
~“while”语句是这样使用的:
代码:

while own.go ==1:
   value = value + 1
   ……
 

其含义是:当 own.go 等于1时,就不停地给“value”增加1。可是对我来说使用“while”总是出错,会让blender失去响应。(个人认为……这种情况是因为写的代码中出现了死循环……——译者注-_-!)

为什么这里会有两个等号呢?恩……布尔运算有各种不同的比较操作符:
“==” 指的是 “等于”
“>=” 指的是 “大于或等于”
“>” 指的是 “大于”
“<=” 指的是 “小于或等于”
“<” 指的是 “小于”
“!=” 指的是 “不等于”
“and”用于两个比较语句之间,比如:
代码:

if this > that and this <= theother:
   do this
 

“or”也是用于两个比较语句之间的,比如:
代码:

if this > that or this > theother:
   do this
 


*记住,所有拼写都是大小写敏感的,并且不要忘了在条件判断语句的末尾放上冒号,还要确保在条件判断语句下面的代码前要插入 tab