用Godot制作你的第一款游戏
本文档将制作一个简单的横版游戏Demo,类似超级玛丽的那种横版游戏。期间会涉及一些代码,使用的是Godot自己的脚本语言GDScript
,你可以不用理解所见到的代码,因为目的是通过制作游戏,快速熟悉Godot的整体,且如何快速的让一个游戏运行起来。
安装Godot
Godot官网:https://godotengine.org/
- 进入官网,点击Download Latest
- 点击
Godot Engine
进行下载,点击后会弹出一个框,不用动,稍等一会会自动下载 下载后会得到一个压缩包,解压后有两个exe文件,那个100多M的就是编辑器,双击打开就能用,不需要安装。
创建项目
点击左上角的新建
按钮来新建项目。
创建并编辑
,就可以进入了Godot制作游戏了。游戏资源
为了制作我们的游戏,会需要一些资源(Assets),如:Sprites(精灵)、Models(模型)、Textures(纹理)、Sounds(声音)等。 点击下载
将资源导入到Godot中非常简单,在Godot左下角的文件系统
中,默认情况下只有一个icon.svg
文件系统
空白处右击,新建assets
文件夹,用来存放资源。选中assets
文件夹,将下载的资源直接拖拽进去,或者粘贴进去。Node节点
在Godot中制作任何内容,都会用到Nodes(节点)。 如果想制作一个玩家角色,通过组合一堆节点来实现。如果想制作一个敌人,同样是通过组合节点来完成。如果想制作主菜单,还是使用节点来完成。因此,节点是构成游戏的基本构件单元。
节点有多种类型,有些用于显示图像,有些用于播放声音,或者添加物理效果,甚至可以扩展现有节点以构建功能更强大的节点,所以可以理解为,在Godot中制作游戏就是组合和扩展节点来得到我们想要的结果。Scenes场景
如在在一个大世界中,用节点构建玩家、敌人、主菜单以及所有关卡都放在一起,随着游戏越来越大,很快就会变的混乱且不利于管理,因此,我们使用场景(Scenes),场景能够将节点打包成可重用的模块,一个场景可以是一个角色、一件武器、一个菜单。
场景可以小到一个单一的可收集金币,也可以大到整个关卡。 场景让我们能够专注于构建游戏的一部分,然后逐步将他们组合起来,使我们的游戏越来越大,这是因为我们可以在其他场景内部嵌套场景。比如:一个玩家场景、一个平台场景和一个可收集金币场景,并将它们全部放置在另一个第一关的场景中。 场景是可复用的,那么就可以只制作一次场景,在整个游戏中多次使用。比如:一个可收集金币场景,我们可以创建多个关卡,它们都使用相同的可收集金币场景,如果何时需要修改金币,那么只需要修改这个金币场景,修改后就会自动应用到其它使用该场景的地方。一次制作,到处使用。 游戏中的所有节点和场景呈现出一种树状结构,称之为场景树
,树的最初始节点为根节点
。 玩家1.0版
创建一个场景,把所有东西组合起来,这是一个2D游戏,所以选择创建2D场景
将创建的Node2D场景重命名为Game,右键弹出菜单选择重命名,或者双击重命名,然后进行保存,按下ctrl + s
保存,保存时新建scenes文件夹,之后我们会将所有的场景都存储到scenes目录中。 此时就可以运行我们的游戏了,虽然什么内容都么有,但并不影响,点击右上方的播放按钮,或者直接按F5
,它会提示还没选择主场景,需要告诉Godot要运行哪个场景,现在要运行的是当前场景,所以点击选择当前
。 运行后,在Godot中文件系统
处,所运行的场景变成了蓝色,这说明它现在是主场景了。运行后弹出的虽什么内容都没有,但此时已经将游戏跑起来了。 停止时,点击停止
按钮或者直接按F8。接着来添加玩家角色,我会将角色制作成角色场景,所以点击菜单:场景 -> 新建场景,会发现在Game场景的旁边多出一个空tab
页,聪明的你一定知道了点击tab
页旁边的+
也可以新建场景,并且在制作中想对哪个场景做修改,直接切换tab
页即可。 之前提到过场景树,那么玩家场景树的根节点将是一个称为CharacterBody2D
的东西,它是专门用于通过脚本移动的角色的2D物理物体,非常适合与环境发生碰撞的玩家角色。点击Godot中左侧场景的+
按钮来添加新节点,或者按ctrl + a
,在搜索栏中输入关键字body2D
,选择CharacterBody2D
并点击创建
。 建好后是空的,什么都没有,需要添加一些图形来展示玩家角色
,我们在刚创建的场景下再添加一个节点,右击刚创建的ChracterBody2D
节点,点击添加子节点
,然后搜索Sprite2D
,因为我们的角色是有动画的,所以选择AnimatedSprite2D
节点并点击创建
。 点击刚创建的AnimatedSprite2D
节点,Godot的右侧的检查器(Inspector)会显示该节点的属性,可以直接在检查器中进行修改。如果选择另一个节点,检查器就中会显示另一个节点的属性。 接下来,为刚创建的AnimatedSprite2D
节点,添加一些动画,在检查器中展开Animation
选项,展开后在Sprite Frames
中给它分配一些精灵帧,这些单个帧将组成动画,点击Sprite Frames
的下拉框,再点击新建Sprite Frames
。 新建后,单击选中新建的Sprite Frames
,会在Godot的底部打开精灵帧窗口。 在这个窗口中点击从精灵表中添加帧
,选择assets/sprites/knight.png
文件,knight.png
文件已经将玩家角色的动画所有不同的精灵帧打包到了一张图像中,这称为精灵表(Sprite Sheet)。 在处理许多精灵时,如制作动画,这是一种非常高效的工作方式,否则将不得不为每一帧创建一个图像,这样很快就会有很多难以管理的大量文件,所以将它们都放到一起,再到Godot中进行裁切,这样会更方便。 那如何裁切呢?需要配置网格,默认是4 * 4
的格子,上面的图中也能看到它是4 * 4
的格子,分成了16块,但默认值切的太大了,所以调整网格,改为8 * 8
就刚好符合啦,每一帧都有自己的网格, 先从添加闲置动画开始,按照想要的顺序点击帧即可,点击后每一帧的左上角都有数字,0
就是第一帧,播放帧动画时,从0
开始播放。再次点击选中的帧可以移除,如果一个一个帧点击太麻烦,也可以直接拖动,只要是你想要的顺序即可。点击添加帧
,将选择的闲置动画帧添加。 添加后,Godot中按F
键可以让角色在屏幕上居中,使用鼠标滚轮将窗口进行放大,也可以按下鼠标滚轮键拖动。 这个角色看起来比较模糊,默认情况下,Godot会尝试进行一些纹理平滑处理使纹理看起来更好,但我们这个是像素角色,就显得没有那么平滑而是很模糊了,所以需要禁用这个处理。点击菜单:项目 -> 项目设置 -> 渲染 -> 纹理,将默认的纹理过滤器从Linear(线性)改为Nearest(最近),这样我们的像素角色就会变的清晰了。 接下来,点击底部精灵帧窗口中的播放,就可以播放动画了,但播放后我觉得播放的速度有点慢,将fps
更改为10,让动画播放器来加点速。 可以为这个动画起个名字,这是闲置动画,所以命名为idle
,并将这个动画启用自动播放
,确保游戏开始时就立即播放。 闲置动画到这里就制作完毕了,但角色的位置现在是居中的,按住鼠标左键向上拖动,让角色的脚站立在紫色的线上。 位置调整好了,在左侧场景栏中,有一个黄色三角警告,如果将鼠标悬浮在这个小图标上面,它会提示该节点没有形状,因此无法与其他物体产生物理碰撞或互动。 这是因为CharacterBody2D
是一个物理节点,每当处理物理效果时,都需要定义一个形状,以便物理引擎进行计算。那么来添加一个新的节点,点击场景栏中的+
或右击CharacterBody2D
后点击添加子节点,搜索collision
,选择CollisionShape2D
,点击创建
。 创建后在检查器
中,可以定义一个形状,这里将添加一个圆形形状。这个圆形形状就是我们角色用于碰撞检测的,啥是碰撞检测?比如你玩超级玛丽的时候,碰到怪物会Game Over,这就是角色和怪物之间发生碰撞检测后的结果,角色和怪物都是个物体,都有自己的形状,当角色和怪物发生碰撞后,会触发Game Over的结果,当然这个结果是你自定义的,那如果是角色和金币呢,当角色和金币发生碰撞时,就不会触发Game Over了,而是触发金币消失、积分增加的结果。 将添加的圆形形状缩小一些,并向上拖动,使形状与角色稍微的匹配一些。 你可能有些疑问,这个形状离角色图形相差很远,但这完全没有问题,碰撞器很少需要非常精确,让圆形形状比角色图形小一点是个非常不错的选择,碰撞器过大在游戏中只会让人感到沮丧,因为在无形中增加了游戏的难度。添加形状后,黄色警告消除了,现在重命名顶层节点为
Player
,然后保存场景,还是保存到scenes
目录中。 现在切换tab
页到game
主场景,在左侧文件系统
中按住player
场景拖拽到game
主场景中。 我们还需要创建一个摄像机
,以便控制当前显示的内容。摄像机就是游戏运行后摄像机范围内的画面就是你能看到的画面。在Game
节点下添加新节点,搜索camera
,选择Camera2D
,点击创建
。 按下F
键使画面居中,并缩小窗口,可以看到这个巨大的摄像机视口。 在检查器
中,将摄像机缩放Zoom
设置为4 * 4
,然后点击并拖动摄像机,使其位于玩家上方。 保存后,就可以运行游戏了,运行后就会出现一个播放闲置动画的角色。但什么都不会发生,我们需要添加一个脚本来允许角色四处移动,tab
页中切换到player
场景,选中Player
节点,单击为选中节点创建或设置脚本
。 添加脚本时,可以选择一个模板,这是Godot自带的,因为编写角色移动的代码很快就会变得有点繁琐,所以目前将使用Godot提供的基本移动模板,然后稍作修改即可,脚本将保存到scripts
目录中,点击创建。 创建完脚本后,会发现顶部自动切换到Script
,这里是可以相互切换的。 此时运行游戏,会发现角色瞬间掉落,这是因为角色是一个物体,它的脚下没有另一个物体让它站立,所以需要给他一个碰撞体以便站立,切换到game
场景,在Game
节点下添加子节点,搜索static
,选择StaticBody2D
,它用于不需要移动的物体,这就是为什么它被称为静态的,所以它非常适合用来创建地面。 创建后,依然会收到黄色警告,说它需要一个形状,还记得前面添加的CharacterBody2D
节点,它是一个物理节点,在刚创建的StaticBody2D
下添加CharacterBody2D
子节点。 然后给它添加形状,但不再是添加圆形形状了,而是添加WoldBoundaryShape2D
形状。这是一种适合像世界边界这类事物的碰撞器,它会在水平轴上无线延伸。 它目前是朝上的,会在横向无限延伸,如果你旋转它,也可以使它纵向无限延伸,但这里我们需要它横向无限延伸。选中StaticBody2D
节点,并选择移动工具
,移动StaticBody2D
到角色的下方。 移动后可以点击选择工具,切换回选择工具,或者按Q
键。虽然StaticBody2D
没有看到任何图形,它是隐形的,但现在可以开始游戏了,可以使用方向键移动角色,使用空格键跳跃。 玩家的移动速度有点快,跳的也有点高,所以修改脚本来调整一下,在player的脚本顶部有两个可以修改的常量,即速度和跳跃速度,我将SPEED修改成了130,JUMP_VELOCITY修改成了-300,修改后再次运行游戏尝试,会发现好多了。世界构建1.0版
之前创建的StaticBody2D
,现在可以删除了,右击StaticBody2D
节点,点击删除节点
并确定,因为接下来将建造一个真正的地面以供站立。
Game
节点下添加子节点,这次添加的是TileMap
节点,添加节点的操作不再赘述。在2D游戏中创建关卡最常用的方法就是使用瓦片(Tiles),瓦片通俗的说就是在网格上绘制不同的瓦片来构建游戏世界,只需几个瓦片就能创造出多变的关卡。 我们用来绘制的瓦片资源通常被打包成一个大图像,就像角色那样(角色的资源也是放到了一张png图像中),这被称为TileSet
(瓦片集),瓦片集就是一堆瓦片的集合。 我们刚刚创建的TileMap
(瓦片地图)节点,就是将这些瓦片绘制到游戏世界中所使用的,为了开始在瓦片地图上绘画,需要添加一个瓦片集,所以在TileMap
的检查器中,点击Tile Set
属性新建一个瓦片集。 添加瓦片集后,点击新添加的瓦片集,就能看到瓦片集和设置,默认的瓦片像素是16 * 16
,我们资源中的瓦片也是16 * 16
,因此保持不变。在下方有两个标签页,分别是TileSet(瓦片集)和TileMap(瓦片地图)。 在对瓦片地图绘画之前,先点击TileSet
标签页,先对其进行配置,首先要做的就是拖入瓦片集资源,瓦片集资源在assets/sprites/world_tileset.png
,按住拖拽到TileSet
中,它会询问是否希望在图集中自动创建瓦片,点击是
。 添加后可以把下方的资源放大看看,它已经自动检测到包含瓦片的网格单元格了,如果你觉得检测的有问题,那么可以进入擦除模式,将检测不准的瓦片擦除,再退出擦除模式,然后按住shift
键+鼠标左键拖动选择,就比如下图这颗树,把这棵树分成了多个小瓦片,但实际它应该是一个大瓦片: 设置好后,可以切换到TileMap
标签页开始绘制了,切换到game
场景,确保场景使用的是选择工具,以及TileMap
已启用绘制工具。 在TimeMap
中用到哪个图块,就单击选择哪个图片,然后在场景中绘制,也可以一次选择多个图块。如果绘制错了,可以右击场景中的图片进行移除。在TileMap中绘制工具
左侧是选择工具
,可以在场景中框选一堆图块并移动它们。那么就按照个人喜好开始绘制吧! 绘制好以后,给TileMap
添加物理层级,不然角色会直接掉下去。在TileMap
检查器中,点击Tile Set
,找到Physics Layers
,添加一个新的层级。 添加后,进入TileSet
标签页,需要选择哪些图块属于物理层级,因为不是所有的图块都需要发生碰撞,所以只选择需要发生碰撞的图块即可。比如:树木可以直接穿过就不需要发生碰撞。 点击物理层0
后,点击右侧的图块进行选择,所选择的图块就会添加物理碰撞。 我将物理层及应用于所有的实心图块上,如果你选错了,想移除某个图块,可以选择清除
。 清除之后,想继续选择,就选择清除
上边的重置为默认图块形状
继续选择。选择和清除的快捷键分别是C
(清除)和F
(选择)。选择了一些实心图块后,还有一些需要具有物理效果的图块,但是碰撞体不是一个方块,而是方块内的一小部分,比如:桥梁。桥梁只需要一小部分碰撞体,而不是整个方块。按F
快捷键继续选择,选择桥梁,在左侧可以调整碰撞体,以符合我们的需求。 有四个点可以拖动,还可以通过鼠标左键和右键来添加和删除点,目前四个点足够了。绘制完一个以后,再点击另外两个类似的图块,因为刚调整完所以点击另外两个类似的图块,它们也会生效。依次将桥梁的中间和尾部也调整好吧。需要注意的是,当图块与图块是挨着的,就需要精确一些,防止角色卡住。 将TileMap
节点移动到Game
节点下的第一的位置,方便随时能够找到它,然后运行游戏看看效果。 但角色移动时,屏幕并不会跟着移动,这是因为摄像机没有跟随角色造成的。我们将Camera2D
摄像机节点直接拖动到Player
角色节点下,使其称为Player
角色节点的子节点,这意味着它会自动跟随Player
节点。还可以在摄像机上启用位置平滑
,在Camera2D
节点的检查器中,启用位置平滑,以默认的5像素为平滑速度。 再次运行游戏,角色移动后屏幕也会跟着移动了。