一、前言
最近工作时间安排地非常紧凑,除了周日一天,已经没有其他空闲时间了。不过到了 10 月份会慢慢恢复,目前我在抽出一点时间好好准备这个 Godot 系列,边写边学习边迎接 Godot 3.1 版本的到来,也算是一件高兴地事情,哈哈。 :sunglasses:
主要内容: Godot 2D 小游戏入门之场景和节点创建
阅读时间: 6-8 分钟
永久链接:http://liuqingwen.me/blog/2018/09/11/introduction-of-godot-3-part-2-game-scene-and-node/
二、正文
本篇目标
- 学习场景的创建和基本设置,游戏的运行,第一个小 Demo
- 了解几个基本节点的相关功能:
Node2D/Sprite/RigidBody2D/CollisionShape2D/
- 丰富我们的小游戏场景,学习静态物体和刚体碰撞以及 Debug 功能
创建场景
我们的目标是在 Godot 中创建一个物理小世界,做个碰撞小测试。相关的图片资源和最终项目我会上传到 Github ,算是第一个小 Demo 吧。 :smile:
第一步:首先是进行一个视窗设置,游戏最终窗口大小。在菜单栏 -> Project -> Project Settings -> General 下,选择 Display -> Window -> Size 下设置宽度和高度,如果找不到设置选项可以点击搜索,我这里设置的是 600 x 1000 ,根据自己的需求随意设定,另外我们还可以设置游戏的视口( viewport ),这里暂时不设置,后续文章我再详谈。
第二步:如果你现在急着运行的话, Godot 会提示你没有选择初始场景入口,所以我们先要在场景中创建一个主节点。在节点窗口添加一个根节点,你可以选择 Node ,也可以选择 Node2D ,甚至其他节点都没关系。还记得上一篇我介绍过的吗? Node 是 2D 和 3D 节点的共同父节点,所以 2D 游戏场景中使用 Node 作为父节点没任何问题。我这里选择的是 Node2D ,接着单击命名为 Game ,保存场景为 Game.tscn
,然后按 F5 运行,选择刚保存的 Game 场景作为游戏启动入口,确定运行。
第三步:在上一步完成后游戏运行我们知道啥都没有是因为场景中只有一个空的根节点。是时候添加一些游戏元素了,这就是 Godot 中丰富的节点体系。我们要做一个自由落体小 Demo 。简单描绘一下:有一个地面作为静态物体,做一个球体从空中自由落下,观察碰撞情形。非常非常简单,是不是?如何在 Godot 中实现呢?有两种方式,如下:
第一种方式:
在场景中添加一个 Sprite 作为圆球显示载体(把属性 Texture
设置为圆球图片),既然我们需要做自由落体,那么也就是需要一个刚体,所以我们给 Sprite 添加刚体属性,如果你学过 Unity 的话,那么你会很熟练地在对应的 GameObject 上添加一个 Rigidbody2D Component ,即所谓的刚体组件,然后设置刚体的质量、弹力、角速度等,在 Godot 中理论是一样的,但是实现却不一样,我们实现刚体特性是通过添加其他功能子节点来实现父节点的相关特性的。这里我们选中 Sprite 节点,按 Ctrl+A 快捷键添加一个 RigidBody2D 节点,接着出现一个警告小三角,点击它会有如下提示:
意思很清楚,就是告诉你, RigidBody2D 刚体节点没有碰撞形状节点是不能进行正常物理交互的!解决这个问题很简单,给 RigidBody2D 添加一个 CollisionShape2D 的子节点就 OK 了,这时候你会发现另一个警告:
同样的道理, CollisionShape2D 也需要一个实实在在的形状来进行碰撞交互,这个形状的创建非常简单,选择 CollisionShape2D ,在它的属性面板里的 Shape
属性下点击选择 New CircleShape2D
创建一个圆形碰撞体,场景中立刻出现一个蓝色的圆,这个圆就是用于物理交互的碰撞体,碰撞体形状默认大小很小,我们可以点击 Shape 里刚才创建的这个圆形碰撞体进入 CircleShape2D 的详细设置面板,然后设置半径 Radius
为 28 就差不多和圆形 Sprite 大小相当了。
第一种方案算是完成了,运行游戏,结果出乎意料?圆球纹丝不动!什么原因呢?是不是没设置重力或者质量?哈哈,别急,卖个关子,看了第二种方案你就会理解了。 :sunglasses:
第二种方式
Godot 中的节点非常强大,而且又不失灵活性!既然 RigidBody2D 表示的就是刚体,而 Sprite 仅仅只是作为一个图片显示的载体,那我们是不是可以把 Sprite 作为 RigidBody2D 的子节点而提供图片显示作用,而 RigidBody2D 作为父节点提供真实的物理交互功能呢?按此理论,我们开启第二种方式。
在第一种方式的基础上,我相信大家对添加节点的操作应该比较熟悉了,直接 Ctrl+A 添加相关的节点,这里要注意的是: RigidBody2D 节点和刚才我们第一种方法中的 Sprite 节点都是场景 Game 根节点的直接子节点,平起平坐,添加的时候别弄错了。
添加设置完节点后,为了区分两种不同的方式,我分别移动了他们的位置,你也可以直接在属性面板里设置两个父节点 Sprite 和 RigidBody2D 的 Transform/Position
位置的值,记住一定是父节点,别弄错了!结果如图:
经过两种方案后,我想你应该已经知道第一种方案不可行的原因了吧!没错,正是由于 Sprite 并不会因为有一个 RigidBody2D 子节点而改变图片渲染位置,虽然子节点的位置受重力的影响会移动,而在第二个方案里, Sprite 作为 RigidBody2D 的子节点,父节点位置发生变化, Sprite 子节点相应跟随运动。如何证明?这里我们可以使用 Godot 强大又舒爽的 Debug 功能一探究竟:选择菜单栏的 Debug 菜单,勾选 Visible Collision Shape ,然后运行,效果一目了然! :laughing:
丰富场景
这个 Demo 虽小,但是到此为止的话,那就有点无趣了,由于是自由落体运动,球体会永无禁止地运动下去!如何让它们落地呢?很简单,给我们的小游戏添加一个带碰撞体的地面就 OK 啦!
这里要说明的是,地面(静态)和刚体都具有碰撞物理特性,但是他们关键点在于:地面的碰撞体是静态的!所以这里我们使用 StaticBody2D 作为父节点,然后添加一个 Sprite 图片作为显示渲染载体,制作一个简单的平铺地层。并没有什么难度,唯一要提醒的是怎么让我们的地面实现水平平铺( Repeat-X )以及使用 SegmentShape2D 作为静态碰撞体的交互形状,关于设置直接看图介绍吧:
完成后,最终的效果如下:
最后的最后,我在地面碰撞体背景中使用的是 SegmentShape2D 而非 LineShape2D ,原因可以引用官方文档的解释,并在此建议大家在单向直线碰撞体中优先使用 SegmentShape2D 吧:
LineShape2D: Line shape for 2D collisions. It works like a 2D plane and will not allow any body to go to the negative side. Not recommended for rigid bodies, and usually not recommended for static bodies either because it forces checks against it on every frame.
SegmentShape2D: Segment shape for 2D collisions. Consists of two points, a and b.
总结
本篇讲解到的知识点:
- 几个基本的节点添加和使用
- 刚体碰撞体设置
- 静态碰撞体设置
- 材质背景平铺设置
- 可视化 Debug 功能
本篇没有使用任何代码,仅仅利用 Godot 丰富的节点系统就完成了这个小 Demo ,算是入门中的入门吧,在后续文章中我会详细说明使用 GDScript 代码来加强和丰富我们的游戏功能。嗯,估计新手朋友们早就想跃跃欲试了吧,你完全可以尝试给节点添加代码,实现一些基本的功能,其实 GDScript 非常简单,如 Python 兄弟般,嘿嘿。 :sunglasses:
三、其他
嗯,这次就这些,我本意是希望阅读我的文章的朋友们(特别是初学者)能有不错的收获,我也会尽量做到吧,当然,第一次做这种系列的文章,难题和问题在所难免,还请大家多多包涵,多多提出意见和建议,非常感谢!附上 Demo 的 Github 地址: https://github.com/spkingr/Godot-Demos 。
好吧,下次继续,还是那句话:原创不易啊,希望大家喜欢! :smile:
我的博客地址: http://liuqingwen.me ,欢迎关注我的微信公众号: