[翻译完成]《Blender游戏的基础教程》中文版
火鸡
|
1#
火鸡 发表于 2008-08-05 03:05
[翻译完成]《Blender游戏的基础教程》中文版英文版在这: 转贴:Blender游戏的基础教程 http://bbs.blendercn.org/viewtopic.php?t=124&start=0&postdays=0&postorder=asc&highlight= 引用: 本译文中的“命令”与“函数”的意义相同。——译者注。 让我们从最简单的开始: 启动你的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失去响应。(个人认为……这种情况是因为写的代码中出现了死循环……——译者注-_-!) 为什么这里会有两个等号呢?恩……布尔运算有各种不同的比较操作符: “==” 指的是 “等于” “>=” 指的是 “大于或等于” “>” 指的是 “大于” “ 代码: if this > that and this “or”也是用于两个比较语句之间的,比如: 代码: if this > that or this > theother: do this *记住,所有拼写都是大小写敏感的,并且不要忘了在条件判断语句的末尾放上冒号,还要确保在条件判断语句下面的代码前要插入 tab 。 -blengine |