Godot3游戏引擎入门之十:介绍一些常用的节点并开发一个小游戏
一、前言
时间飞快,我有一段时间没有发表博客了,这段时间并不忙,一方面我自己也在不断学习,另一方面暂时不知写哪方面的内容了,感觉 Godot 中一些基础的部分我都或多或少谈到了,所以我打算使用我们学习过的知识来做一个小游戏吧。
这个游戏非常简单,但是对于完全“门外汉”的初学者来时还算有一定难度,不过别急,我会把我制作这个小游戏的一些思路以及常用的技巧娓娓道来,而且源代码我于上周就已经上传到 Github 啦: https://github.com/spkingr/Godot-Demos ,另外这个游戏来源于一本书:《 Godot Engine Game Development Projects 》,官网也有这个 Demo(Coin Dash) 以及其他示例的代码,我的思路和代码和官方有点不同,也实现了一些其他功能比如游戏暂停、金币数量显示等,强烈建议大家去围观。 :smiley:
result_1.gif本文分上下两篇,第一篇,也就是在进入“金币”小游戏的开发制作讲解之前,我先把之前文章里没有遇到过的一些非常重要的节点介绍一下,还有一个提醒:最好的学习方法应该是先尝试一遍或者边思考边把代码浏览一下,然后再来看我的文章,这样效果会比较好。嗯,废话不多说,我们开始吧!
主要内容:认识一些新的节点和代码学习
阅读时间: 10 分钟
永久链接: http://liuqingwen.me/blog/2018/11/30/introduction-of-godot-3-part-10-introduce-some-node-types-and-make-a-new-game-part-1/
系列主页: http://liuqingwen.me/blog/tags/Godot/
二、正文
本篇目标
- 学习使用一些新的 Godot 节点
- 最基本的游戏开发规则
- 编写代码的规范
Godot 中常用节点
1. Timer 节点
看名字就知道这是一个“计时器”。在 Godot 中一切皆节点,所以看到这种纯功能性的节点不要觉得奇怪,同时,我们完全可以不使用节点,直接使用代码 Timer.new()
动态创建一个计时器也是没任何问题的;甚至我们完全可以通过设置变量,利用 _process(delta)
方法来计算时间,不过显然没有 Timer 节点来得方便简洁!
在我要讲解的这个小 Demo 中,我使用 Path2D 路径节点绘制了一些点来保存需要用到的位置,后续我会详述。 :smiley:
file_orgnization_unity_vs_godot.png godot_10_path2d_node.png godot_10_pause_mode.png godot_10_timer_node.png godot_10_tween_node.png2. 保持场景独立
嗯,我认为这是 Godot 中开发游戏最重要的一条原则了!它能明显地提升开发效率,提高团队合作,更利于 Debug 调试。因为 Godot 中一切基于场景,场景中可以包含多个子场景,子场景依然可以由多个其他子场景组成,而且每个子场景是可以单独运行的!打开子场景,按 <kbd>F6<kbd> 来单独运行、测试,及早发现问题,提高程序的健壮性。
如何保持场景独立?这就需要我们去仔细思考了,具有独立功能的部分我们都可以抽离出来作为一个单独的子场景,通用、具有类似功能的节点也可以抽离出来以继承关系实现,需要说明的是:独立并不意味着不与其他场景发生任何关系了,独立只是让它能单独运行,能单独测试一部分功能,这是很重要的。
3. 代码编写规范
代码构成了游戏的灵魂,代码编写不规范带来的直接后果就是:
- 自己看不懂,遇到 BUG 后越改越乱
- 团队里其他开发者看不懂,很难或者无法 DEBUG
- 不利于后续功能的开发、重构等
和文件组织管理方式一样,其实代码编写规范也会因人而异,在 Godot 中官方所推荐的方式如下:
# 枚举、常量等变量命名
enum State{INIT, IDLE, PLAYING, DEAD}
const CONST_GRAVITY = 98
# 普通变量、私有变量命名
var player_sprite = 1
var _walk_speed = 2
# 私有方法命名
func _private_method():
get_tree().paused = true
pass
# 公有方法命名
func public_method():
_private_method()
pass
注意,在 GDScript 中是没有 private/public/protected
等关键字来规范访问限制的,类似 Python ,这也正是我们需要保持一定的编码规范的原因之一。不过,你会发现我的命名方式会有所不同!我比较习惯 Java/C#/Dart 等语言的命名规则,采用驼峰式,同时利用 _
下横线来标记私有变量或者方法,而且调用内部方法的时候我都会显式使用 self
关键字:
# 枚举、常量等变量命名
enum State{INIT, IDLE, PLAYING, DEAD}
const CONST_GRAVITY = 98
var playerSprite = 1 # 公有变量
var _walkSpeed = 2 # 私有变量
# 私有方法命名
func _privateMethod():
self.get_tree().paused = true
pass
# 公有方法命名
func publicMethod():
_private_method()
pass
至于选哪种,我觉得只要保持规范,符合个人或者团队共识就好啦! :smiley:
三、总结
本篇文章算是一个经验小总结吧,也是为了更好地解释我们后面要出场的游戏项目,林林总总地列举了一些不成文的条条列列,不知道大家看后的感受是怎样的呢?
嗯,有两周没有写文章了,因为最近有其他的事情和同学在忙乎,不过我一定会坚持下去的,还是那句话,原创非常不易,希望大家喜欢! :smile:
我的博客地址: http://liuqingwen.me ,欢迎关注我的微信公众号:
IT自学不成才