Blender 游戏引擎的乐趣与混乱
使用键盘或鼠标作为控制器创建 3D 游戏。
我已经使用 Blender 3D 几年了,但我最近才开始玩游戏引擎。我从中获得了许多乐趣,我相信您也会如此。使用 Blender 游戏引擎 (BGE),您可以使用键盘或鼠标作为控制器创建 3D 游戏。您的游戏可以在对象相互碰撞或彼此靠近到一定距离时触发事件。它内置了状态引擎,因此游戏中的对象可以根据需要更改其行为。虽然有一个强大且文档完善的 Python API,但我们今天不会使用它。事实上,我们甚至不会编写一行代码!
在 2009 年 4 月的《Linux Journal》杂志中,我撰写了一篇文章,通过创建少于 100 行 C 代码的基本 3D 环境来演示 Irrlicht 3D 引擎。在本文中,我将通过创建一个功能齐全的视频游戏来演示 BGE,该游戏具有逼真的物理效果,而我所要做的就是连接点。
BGE 的最大吸引力之一是内置的 Bullet 物理引擎。物理引擎允许用户为 Blender 模型中的对象分配各种物理特性,例如质量,并配置它们如何响应碰撞和运动。如果操作正确,用户最终会得到掉落时会坠落、碰撞时会翻滚的方块。球会滚下山,多米诺骨牌会互相推倒。
为了演示 BGE 和 Bullet 物理引擎的重要方面,我设计了一个名为《超级巨型拆除德比》的小游戏。游戏的前提很简单;您可以使用各种类型的建筑材料建造墙壁和塔楼等。然后,您驾驶汽车穿过它们,观看它们崩塌成碎片!好吧,我不知道您实际上会如何在这样的游戏中计分,但游戏的目的是为了好玩,而且根据我花费在破坏积木墙上的时间来看,我认为这是一个有趣的游戏。
图 1 显示了我玩游戏时制作的测试动画的动作镜头。如您所见,建模和纹理非常简单(这并非建模教程)。我相信您可以看出这是经典的“驾驶汽车驶过斜坡并穿过墙壁”的特技。为了设置这个特技,我创建了三堆积木,每堆四块高。我把紫色球放在顶部。然后,我在墙壁前面放置了一个斜坡,并将汽车放置在稍远的地方。设置好灯光和摄像机角度后,我启动了游戏,并将汽车开上斜坡。
图 1. 测试动画的动作镜头
创建游戏的第一步是为所有不同的对象创建模型。竞技场只是一个 100x100 的平面。然后我挤压边缘以创建围栏,以防止汽车驶出竞技场边缘。汽车是由一个立方体创建的,该立方体被缩放和挤压以形成一个非常基本的汽车形状。其余的游戏对象都非常简单。
游戏对象完成后,就该开始游戏逻辑了。由于汽车既有物理属性又有键盘控制,因此它是最复杂的,我们将从这里开始。选择汽车并按 F4 会弹出“逻辑”菜单。图 2 显示了我用于汽车的配置。在这里您可以看到三列控件。第一列是您配置对象的物理属性的位置,我稍后会讨论。现在,让我们看一下“传感器”、“控制器”和“执行器”列。
图 2. 逻辑面板
“传感器”列是您选择要让游戏对象响应的事件的位置。在这种情况下,您可以看到汽车响应向上、向左和向右箭头键。键盘传感器允许您配置各种参数,例如重复率和键盘修饰符。游戏对象还可以响应鼠标事件、碰撞、与其他对象的接近程度、计时器以及从其他对象发送的消息。
传感器连接到控制器,控制器本质上充当过滤器,并确定何时对给定的传感器感兴趣。如您所见,我选择了布尔逻辑等效于“始终”来确定汽车何时应该响应键盘事件。如果我选择这样做,我可以引用 Python 代码或 30 种不同的游戏状态中的任何一种,但这只会引入比游戏需要的更多复杂性。状态引擎可以用于向游戏中引入陷阱、谜题和其他隐藏元素。实现真正的智能可能需要一些 Python 代码。
“执行器”列是动作的来源。虽然我为汽车的键盘事件使用了“简单运动”,但可能性一开始有点令人生畏。我可以选择沿 X、Y 或 Z 轴更改对象的位置和旋转。我还可以选择施加力或扭矩。最后,我可以选择更改对象的线速度和角速度。通过选择右侧的 L,我告诉 BGE 使用对象的局部方向来应用运动更改,而不是使用全局坐标。
让汽车的操控“感觉”正确需要一些调整,而且就目前而言,它仍然更像是在泥泞中驾驶,而不是在草地竞技场中驾驶。在它正确之前还需要进行更多调整。另一方面,我能够使用材质设置向驾驶表面添加随机颠簸,这会导致汽车稍微弹跳。
BGE 允许您做的不仅仅是移动对象。您可以使用执行器来发出声音、向其他对象发送消息、创建和销毁对象、更改游戏状态、更改摄像机,甚至启动动画序列。很难想到有什么是 BGE 提供的执行器无法完成的。例如,我考虑过创建一系列执行器来销毁一个盒子对象,并将其替换为应用了“爆炸”修改器的外观相同的盒子。这将使我能够创建一个在撞击时爆炸的盒子,但我还没有尝试过。
现在您有了一辆可以驾驶的汽车,您需要让它和其他游戏对象按照物理定律运行。这是通过使用图 2 中“逻辑”面板的第一列中的控件完成的。您要做的第一件事是确定您想要的对象类型,这本质上决定了“多少”物理定律适用于该对象。您有几种类型可供选择,包括静态、动态、刚体、柔体和传感器。
静态对象响应碰撞,但不受重力影响。例如,我将斜坡配置为静态对象。这样,如果汽车从后面撞到斜坡,斜坡会做出真实的反应,但我也可以“堆叠”斜坡以构建更复杂的障碍赛道。
动态对象与静态对象非常相似,只是它们受重力影响。它们不受滚动物理的影响。当我最初将汽车设置为动态时,我发现它没有像我预期的那样驶上斜坡。它更像是一段通往斜坡顶端的自动扶梯,因为汽车在穿过斜坡时没有倾斜。
当我将我的汽车配置为刚体时,我拥有了一切。汽车会从斜坡上飞下来,掉到地上,如果撞击太猛或在掉落过程中撞到什么东西,就会滚动。游戏中的大多数对象都配置为刚体。
柔体类型玩起来很有趣。通过调整各种参数,我能够想出一个巨大的沙滩球,它在掉落时会弹跳和变形。通过稍微放松一下,我最终得到了一个巨大的果冻球,谁没有梦想过驾驶汽车穿过一个巨大的酸橙果冻球呢?我知道我有。这是用于您希望在撞击时变形的对象的类型。
传感器只是一个可以用来触发事件的对象,但不必对其应用完整的物理定律。例如,传感器可以用于触发陷阱、释放敌人或仅在碰撞时更改游戏状态。在本游戏示例中,传感器对象可以放置在平台的中间,以在汽车正确定位时触发电梯上升
确定您想要的对象类型后,就该调整各种参数了。例如,您可以确定对象的质量,这将决定它是像羽毛一样落下还是像传说中的一吨铅一样落下,以及它与其他对象碰撞时的行为方式。通过单击“高级”按钮,您还可以设置对象可以移动的速度限制等等。最重要的调整之一是“边界”配置。此配置确定如何进行碰撞检测。我发现,如果我对汽车使用球形边界,事情就不会很好地工作——汽车最终会沿着通往斜坡的路径滚动,而不是沿着路径行驶。
您还可以使用物理面板为对象分配各种属性。例如,您可以为汽车分配一个“伤害”属性,并为其分配一个初始值 0。然后,对于每次碰撞,您可以创建一个执行器来增加此值。最后,您可以使用该属性作为传感器,并在其超过某个值时触发一个动作。
那么,到目前为止我们有什么?图 3 是从另一个摄像机角度拍摄的游戏截图——这是一辆可以在包含几个不同障碍物的环境中驾驶的汽车。这辆汽车(以及游戏中的障碍物)具有物理属性,例如线性和角动量、质量和弹性。所有这些对象的行为都与您在现实生活中期望的行为一致。
由此,我期望为游戏创建更有趣的对象。例如,我认为可以很容易地创建一个质量非常轻的对象,例如扑克牌。由此,可以建造纸牌屋并随后将其摧毁。多米诺骨牌虽然看起来很有趣,但创建起来太简单了,几乎没什么意思。在我看来,沙滩球和巨大的果冻球肯定值得进一步研究。
图 3. 游戏截图
通过将摄像机与汽车父级化,我能够设计驾驶舱视角或第三人称视角。使用此视角,我可以像任何其他驾驶模拟一样在竞技场周围驾驶。唯一的缺点是,一旦我驾驶汽车穿过墙壁,我就无法观看它滚落到地面,除非我快速转动汽车。在游戏中设置多个摄像机,策略性地放置它们并创建键盘触发器来选择它们可能会很好。尽管如此,使用 BGE 很容易做到这一点。
如您所见,BGE 非常强大,并且无需任何编程即可上手。但是,如果您知道或愿意学习 Python,您可以做更多有趣的事情。网络上的教程演示了如何使用 Python 代码来创建抛射武器。我已经暗示了使用 Python 代码赋予游戏对象人工智能的想法。BGE Python API 的文档也非常好。事实上,BGE 是我开始学习 Python 的唯一原因。
尽管 BGE 非常酷,但它确实有一些限制。与 Blender 本身一样,BGE 非常强大,虽然它们都有完善的文档,但入门可能会让人望而生畏。水和布料模拟在游戏引擎中不起作用。我还注意到这款游戏中的对象没有投射阴影。我还没有弄清楚如何解决这个问题。我使用 BGE 面临的最大挑战是对象纹理在 BGE 中的工作方式似乎并不总是与在渲染引擎中的工作方式相同。显然,由于 BGE 实时生成屏幕图像,因此必须做出一些妥协。我最终获得了令人满意的结果,但有时我不得不求助于将纹理 UV 映射到对象上才能使其正常工作。也许我遗漏了什么。
如您所见,BGE 和 Bullet 物理引擎是非常强大且可配置的方式,可以快速创建栩栩如生的游戏环境。我最初为本文制定的计划是使用简单的飞行模拟作为演示。一旦我开始写作,我就认为飞行模拟并不能完全展示 BGE 的强大功能。
其他类型的游戏也很适合使用 BGE 编写。例如,台球游戏是一个显而易见的选择。也许越野或怪物卡车驾驶模拟会很有趣。不必编写代码即可使游戏对象直观地运行意味着您可以专注于创建具有逼真内容的有趣游戏,这真的很酷。
资源
Blender: http://www.blender.org
Mike Diehl 撰写的“使用 Irrlicht 进行 3D 图形编程”,LJ,2009 年 4 月: https://linuxjournal.cn/article/10294