惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
T
Threat Research - Cisco Blogs
Cloudbric
Cloudbric
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
Intezer
Attack and Defense Labs
Attack and Defense Labs
P
Privacy International News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
C
Cybersecurity and Infrastructure Security Agency CISA
V2EX - 技术
V2EX - 技术
AWS News Blog
AWS News Blog
O
OpenAI News
L
LINUX DO - 最新话题
N
News | PayPal Newsroom
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Latest news
Latest news
D
Darknet – Hacking Tools, Hacker News & Cyber Security
A
Arctic Wolf
Spread Privacy
Spread Privacy
G
GRAHAM CLULEY
T
Tor Project blog
博客园_首页
Know Your Adversary
Know Your Adversary
有赞技术团队
有赞技术团队
S
Secure Thoughts
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
T
Tailwind CSS Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
V
Visual Studio Blog
J
Java Code Geeks
Cisco Talos Blog
Cisco Talos Blog
Schneier on Security
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Security Affairs
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
宝玉的分享
宝玉的分享
量子位
Last Week in AI
Last Week in AI
月光博客
月光博客
罗磊的独立博客
S
SegmentFault 最新的问题

机核

游戏性能旗舰最强之选,一加 Ace 6 至尊版国补到手价2999元起 6元钱自己更换电动车刹车线 《生化危机9:安魂曲》编剧Haris Orkin专访 摸金游戏?音乐游戏!暗区新赛季这把能弹的琴有何来历? 好评国产武侠SRPG《息风谷战略》免费DLC现已推出 | 机核 GCORES 碎片 《生化危机:安魂曲》将于5月实装首个免费更新内容 | 机核 GCORES 新锐东方游戏,谱写世界新章! 沉浸式恋爱视觉小说游戏《心象演算》免费试玩版现已正式上线 | 机核 GCORES 互动影游《代号三国:龙起》上线!穿越三国与曹操并肩、与佳人同行、与权谋博弈! 《老头收集梦想生活》,游戏酒桌会6,录音笔VOL.689 | 机核 GCORES 破界·共生——《白日梦:无限世界》五大核心游戏特点解析 价格已到史低,锐龙5 9600X/锐龙7 9700X正适合抄底 时间循环之旅即刻启程!《归环》一周目测试今日开启 热门在线韩游变魂游,洛奇衍生作能否打破“花瓶”魔咒? LG UltraGear evo 全新高端显示器系列:当“5K”遇见“AI”,不止强大,更懂热爱 反套路三国互动影游《代号三国:龙起》今日上线! 愿望单登记人数突破10万!备受瞩目的“女儿养成游戏” 《梦幻魔法公主》今日于Steam平台上线!限时八折优惠中 《黑神话:悟空》全球音乐会2026巡演将于4月29日12时开票 | 机核 GCORES “Snowguelike”生存肉鸽挖矿新作《蛙穿雪境》公布发售日期,5月7日正式上线 | 机核 GCORES 重塑移动办公、AI创作新境!全新华硕灵耀Air系列、ProArt 骁龙版震撼首发,创芯未来 均分88:《Saros》媒体评分汇总 | 机核 GCORES 上海烛龙公布合作遗迹探险游戏《吉时已到》首支预告片 | 机核 GCORES 首个独立游戏《萝薇日记》已上线Steam! 烛龙新IP《吉时已到》首曝,打造国内首款中式合作遗迹探险游戏 喜加一:《暗黑破坏神Ⅳ》国服现已开启限时免费领取本体活动 | 机核 GCORES 新版《生化危机》电影定于9月18日上映,官方网站现已上线 | 机核 GCORES 《冲就完事模拟器2》“星球大战”联动DLC正式宣布 | 机核 GCORES SteamController将于5月4日发售,售价99美元 | 机核 GCORES 事已至此,内存这么用也算省钱了,“2+1”非对称双通道应用实测 505游戏母公司现已收购《明末:渊虚之羽》IP | 机核 GCORES 基石 手动杂谈12|格斗游戏也能讲好故事 | 机核 GCORES I Love You Mr Snowball 我的向日葵小姐 会比GTA6先发售吗?最硬核的生存游戏《DAYZ》要推新DLC了 周记02:在2026遇到新怪谈 什么硬件,能让游戏Loading界面快速消失? | 机核 GCORES GadioSpec《百年风云世界杯》免费试听集 | 机核 GCORES 百年风云世界杯Vol.1丨足球崛起 | 机核 GCORES 100年前,一群人提前替我们经历了AI恐惧 | 机核 GCORES 《呼啸山庄》2026 ——一辆当代艺术的大卡车冲撞了我的大脑 手游《天穗之咲稻姬:日之香巡灵传》宣布将于7月27日停服 | 机核 GCORES 集结梦之队,征战世界杯,《最佳球会ONLINE》上线Steam 山水绝景随心拼 休闲建造游戏《千里山河录》Steam商店页公开 巫师帽、法袍、魔杖,为什么它们是影视、游戏里的法师必备三件套? 《无鞘信使》-第一章 复古风自动战斗肉鸽《终结之终结》Steam商店页面现已上线 电脑里有一款不破不立的MMO,录音笔VOL.688 | 机核 GCORES 《生化危机》30周年纪念周边发售,这次是真的“保护伞” 可靠耐用+AI全能,惠普战66 2025锐龙版深度体验 《时之书:无尽终章》关卡“大航海时代”全球首次公开 经典名作《乌龙派出所》改编经营模拟游戏《乌龙派出所~阿两的商店街物语~》正式宣布支持简体中文 明日开冲,解锁反套路三国互动影游《代号三国:龙起》即将上线 独立游戏《这是我的宝藏!》已发售~ 降低难度不是唯一解,无压力死亡也是好体验 Netflix官宣新片《普通人》:讲述韩国现代史上的权力风暴 《生化危机:安魂曲》全球销量现已突破700万份 《绝地鸭卫》PC版5月15日正式发售 亡妻回忆录?女性向情感叙事游戏《S-mail》现已正式发售 全新酷黑风格,酷睿Ultra 200S PLUS的高性价比搭档!七彩虹BATTLE-AX B860M-PLUS S WIFI7 V20 超级黑刃主板测评 胖狗 索尼发布了港台地区PS5产品价格调整公告,将于5月1日起实施 二次元怪猎+性感美女!《碧蓝幻想:无尽黄昏》开启Beta公测 这款怪谈类型中式恐怖游戏居然更新了?! 《百日战纪 -最终防卫学园-》改编漫画将于今年冬季开启连载 《如被附身,请致电我们》:匈牙利黑色幽默恐怖小说 《竹屿山房杂部卷五》(译文) 大树 超越引擎 摄影分享丨四月 碎片杂记vol.72 当老式FPS与老式动画技术碰撞出新时代的火花—《神探杰克鼠》 想做独游,如何避免首个项目就褒姒? 在线多人动作游戏《OCTOPinbs》将于5月12日上线Steam! 《酒鬼女神的酒诡》确定将于2026年登陆Steam 《CRYMELIGHT》将于11月5日(周四)正式发售!4月25日开始预购! 钢铁国度MKI部落Evolution,蛮兵部分 【钢铁国度】部落-Primal MK I,蛮兵部分 这是一个高中生用ai跑出来的作品,我自称他为物理神话 钢铁国度MKI部落Metamorphosis,蛮兵部分上 钢铁国度MKI部落Metamorphosis,蛮兵部分下 INDIE Live Expo于4月25日举办:首发9款新作,超200款独立游戏亮相 暗黑卡牌策略新作《魔忌:穷鼠啮狸》发布全新中文试玩版和发售预告片,4月30日正式上线在即 战锤40K长篇小说:变节者・苦难主宰(三)(全书完) 战锤40K长篇小说:变节者・苦难主宰(二) 战锤40K长篇小说:变节者・苦难主宰(一) 英语语言学习丨短语专题1:短语的特点 唯一的EVE战争 【少前同人】【M200】战术人形会梦见音乐会吗 【昏迷3】即将发售,前作主角悉数到场!“恶灵”宋老师化身可操控角色 业内人士:游戏公司“十有八九”使用生成式AI,包括卡普空 欢庆一周年:《光与影:33号远征队》全新纪念艺术图、超值折扣与免费更新同步上线 才刚刚开始呢 【抽奖】《星际卡车司机》推出免费大型更新,四折平史低折扣进行中 四人合作FPS游戏《佣兵猎手》抢先体验重大更新 1 现已上线 Raw Fury新作《深馅地牢 Deep Dish Dungeon》将于今秋加入 XGP 塔防幸存者游戏《魔怪来袭》推出首个 DLC 《饿狼传说:群狼之城》1周年纪念!新DLC“沃尔夫冈·克劳萨”今日参战 猫狗相伴 欢乐闯关 双人合作平台跳跃游戏《猫狗同行》上线Steam商店页 《同行:月球逃脱》(Together: Moon Escape)上线将于明日上线Steam
Godot入门到弃坑:GDScript精要 拾遗
cameLcAsE · 2024-02-15 · via 机核

这一篇文章是GDScript精要部分的最后一篇。这里主要讲一些前面没有讲到的、不方便归类的内容。但是其中一些特性是很常用、很方便的,因此依然建议阅读。

枚举

试想一下,你要用一个变量来表示一周的每一天(星期几)。

自然而然地可以想到用整数来表示。但是合法的星期几只能是1-7,而一个int类型的变量取值范围要大得多。我们无法限制取值范围。

这里可以通过定义枚举(enum)类型来提供更明确的约束。枚举类型定义了一组合法的值,一个枚举类型的变量应当取这些值中的一个(GDScript的枚举目前无法限制枚举类型的变量只取枚举中定义的值)。有时候枚举类型也被视作”有名字的常量“(named constants)。

在GDScript中,使用enum关键字定义一个枚举类型。enum后是枚举类型的名称,然后是一对花括号。括号中是枚举类型可用取值的列表,以逗号隔开:

定义枚举类型后,可以像这样使用枚举类型:

枚举可以作为类型在类型标注处出现,枚举的某个取值也用点语法获得。

你此时可能会说,诶,那我需要获得它对应的数字怎么办呢,你这没用数字表示啊。实际上枚举定义时已经暗含了这一点。前面已经提到枚举相当于一系列常量,定义枚举时如果不给他们指定值,默认就会从整数1开始按出现顺序给它们设置值。你可以试着print一下Monday和Sunday看它们是不是分别为1和7。

实际上GDScript中的枚举类型很难说是真正的枚举类型。在Godot 3.x中它甚至不能作为类型使用。定义枚举类型时enum后面的名字可以省略。此时它等价于一系列常量定义:

这样写有一个问题就是可能会造成命名冲突,因为我们直接就能访问到这些常量。而有名字的枚举需要通过枚举类型的名称来访问具体的选项。

不过不管那种方式定义枚举,有一个好处就是如果你要定义一系列连续编号常量,那么只需要指定枚举中某一个项目的取值,后续的取值都会自动加一:

如果像这样定义,星期三后面的取值会自动编号为4、5、6、7。但是要注意的是,星期三前面不会自动减一。此时Monday为0,Tuesday为1。当然你也可以分别为各个选项指定值而不按顺序。

GDScript的枚举类型的值只能是整数。

有名字的枚举类型,实际上就是一个字典。这就意味着字典的所有方法对于一个枚举类型来说也是可用的:

顺带一提,C#中星期几就是用一个枚举类型来表示的。不过由于习惯的不同,星期天对应的是0。

特别的字典语法

除了像之前那样提到的用花括号和冒号来写字典字面量,还有另一种语法来初始化字典:

这种写法是Lua式的——Godot文档中也是这样称呼这种写法的。Lua是另一门编程语言,它的设计很有特点,并且在历史的不同阶段也是游戏开发的热门语言之一。Lua提供了——且只提供了一种内置数据结构那就是表(table),它实际上就是类似于字典的一种数据结构。这种Lua式的写法也用花括号,但是各键值对的键和值用等号连接。此外这种写法中键必须是合法的变量名,也就是说不能以数字开头。

另一方面,字典可以直接用点语法来访问键和值:

当然这种语法糖并不局限于使用Lua式写法的字典。只要字典中有这样的字符串键,且这个字符串可以作为合法的变量名,那它就可以用这种语法访问。并且不要求字典中所有的键都满足这一约束。

格式化字符串

前面提到可以用加号和字符串提供的各种转换函数来根据某变量的值来构造字符串。实际上还有更方便的方法来往字符串中填入某些变量的值。

例如按照之前的方法,在需要根据名字来输出问候语时,我们需要这样:

这种写法单纯拼接两个字符串还好,如果要拼的字符串太多就很麻烦,尤其是变量出现在一串字符中间的时候,要多写几个加号。

利用GDScript中提供的格式化字符串来写,就是这样:

模板字符串中的%s相当于占位符。它可以被填入各种各样的值。在格式化字符串后面用%运算符加上具体的值来替换占位符后就可以得到具体的字符串。也可以写上多个占位符,然后在百分号后用数组来填充占位符:

格式化字符串中的占位符支持多种格式。%s里面的s代表simple,它会直接把传入的表达式转换为字符串。不过GDScript格式化字符串的其他格式主要是改变数字和向量的显示格式,因此并不算常用。有兴趣可以看文档

当然还有一个问题就是,如果我就是要在字符串里包含百分号怎么办?比如我要输出一个百分数。这个时候需要给百分号转义(escape),用两个连续的百分号来表示百分号本身:

除了格式化字符串以外,还有一种格式化字符串的方法,那就是String.format实例方法。字符串模板中的占位符需要用花括号围起来,然后把对应的字典或者数组作为参数传递给format方法:

format的第二个参数(可选)用于指定占位符,默认是花括号。如果你的字符串中包含花括号就可以指定其他符号作为占位符。

注意format方法会返回一个新的字符串而不会就地修改字符串本身。

实现转换为字符串的方法

在print和格式化字符串中,Godot会利用某个方法来将对象转换为字符串。内置类型实际上都能够很好地转换为字符串。但是对于我们自定义的类型,如果不编写额外的代码print出来就是一些让人难懂的东西。比如之前的一个Item:

输出的是:

让人摸不着头脑。实际上这是它的基类和它的对象id——但是这对于一般的开发者和开发工作来说没啥用。

重写_to_string方法之后,它就可以按照我们指定的方法来将它转换为字符串。在Item的定义中定义如下函数:

实际上写这个函数的时候编辑器会自动补全,它是知道你可能在重写基类方法的。这样之后再print就能看到我们需要的信息了:

print的更多用法

前面的示例代码中只讲到直接用print输出单个值(表达式)。实际上print可以接受任意多个参数:

不过这种写法不是特别有用,因为它会直接把几个参数连在一起,上面这行代码输出的是11.5?。

另外目前GDScript不支持自己编写支持可变数量参数(vararg)的函数。但是C#支持。

prints和printt和print类似,也接受任意多个参数,但是它们会在输出时给个参数之间分别加上空格(space)和制表符(tab)。

print输出完毕后自带换行,如果你不需要换行,就可以用printraw函数来输出。

在字符串中还有一些特殊的以反斜杠加字母表示的转义字符。这些特殊字符是不可见的,所以要用转义字符来表示。最常用的\n表示换行:

输出:

push_error和printerr类似,都会输出红色的错误信息。但是只有push_error会在调试面板的错误页面中加入一个错误。并且这两者都不会中断游戏运行。类似的push_warning则是输出黄色的警告信息。

此外print_rich支持BBCode格式的富文本。

断言

前面的文章中我们在需要测试某个东西时往往都是直接用print输出来检查。在编程过程中可以用断言(assert)来验证某个布尔表达式是否为真,并在表达式为假时直接报错终端程序运行。

GDScript中用assert函数来进行断言。它可以接受两个参数,第一个参数是条件;第二个参数是可选的,它是断言失败时输出的错误信息。

这行代码在游戏运行到这里时会直接报错中断。

断言也是一种调试(debug)常用技巧。在后续文章中我会适时讲解更多有关调试的内容。

代码规范

在编写代码中我们必须要给很多不同的东西命名,因此有必要讲一下命名规范及其重要性。

在开发过程中,我们很可能需要和他人合作。符合规范的代码能够让大家更容易理解,能够让协作更顺畅。首要的一条是要尽可能使用有意义的名字来命名各种元素。如今很多开发工具都支持自动补全且能按首字母进行提示,因此应当尽量避免缩写,用完整的单词来命名。

当然,包括GDScript在内的很多编程语言都支持用英文字母以外的字符来作为代码符号的名称,因此我们也不一定要用英文命名。但是无论如何,你的代码在团队中应当有一以贯之的规范。顺带一提中文命名有一个小问题就是,很多开发工具支持英文首字母自动补全,但是不支持汉字的拼音首字母补全,所以频繁切换输入法有点麻烦。有一个通用的小窍门是在汉字名称前面加上拼音首字母缩写,这样就可以让编辑器识别到。当然这样一来就不好看了,因此究竟采用何种规范还需要开发者自行定夺。

由于GDScript和Python有很高的相似性,因此官方的规范也有很多地方和Python重合。

命名方面变量名、方法名采用snake_case。意味着所有字母都小写,多个单词用下划线连接。比如GDScript内置的二维向量类中的:

常量全部字母大写,单词用下划线连接(CONSTANT_CASE):

类型名首字母大写,多个单词不用符号连接(PascalCase):

对于枚举类型来说,枚举的类型名应该是PascalCase,但是枚举的可选值应当是CONSTANT_CASE。

此外文档在组织文件中的内容时,前后的空格、换行等格式上也有一些建议,完整的官方代码风格指南参见文档

当然,这些规范都是“君子协定”,它们并不属于GDScript语法要求的一部分(除了用来界定代码块的缩进),不遵循这些规范也不会报错。你也可以有自己团队认可的不同的规范。

函数也是对象

没错,函数也是对象。这就意味着函数也可以放在变量里、也可以作为函数参数传递:

函数的类型在GDScript中叫Callable(可调用对象)。不过GDScript中没法显式表明函数的签名,也没法在引用函数的变量上直接用常规语法调用引用的函数。这里需要用Callable的call方法来调用:

在call中传入引用的函数所需要的参数即可。

如果一定要说为什么要这么做,原因在于它能够分离函数调用者和函数实现者。比如送奶工给订户送牛奶。送牛奶的才知道什么时候送,送怎么样的牛奶,而需要牛奶的订户只关心消费牛奶而不知道什么时候送来。所以”送牛奶“这个函数要交给送奶的调用,而牛奶送到之后具体怎么做,是订户自己的事情。

我们会在后续的文章中见到这个特性的具体用例。

花式注释

注释除了单纯的笔记其实还有更多用处。

在注释开头写上特定的单词可以让注释以不同的颜色显示,让它更醒目:

有时候代码写得太多,而有的代码暂时又不需要管,很碍眼。可以用注释来定义一个区域,让编辑器可以把这部分代码收起来。

注释的井号后面跟上region(不能有空格)表示可收起区域的开头。region后面可以跟上任意内容,方便在收起之后依然能够明白这一段写的啥。在要结束区域的地方写上井号和endregion,这就算定义了一个可收起区域了。此时开头的地方左边会出现一个箭头表示可以收起。

限定类型的数组

前面提到GDScript的容器类型可以容纳不同类型的元素。但是如果你确实只需要在数组中保存某一种类型的元素,也可以给数组加上类型标注来提高安全性。要指定数组元素的类型,需要像这样写:

这样一来,GDScript就会对这个数组进行静态分析,在游戏运行前就会检测出任何违反类型约束的操作。也就是说你没法往里面加入其他类型的元素,也不能让这个变量引用其他类型的数组。

这种操作看起来有点像模板或者泛型。但是目前GDScript并没有这类特性。

match语句

如果你有其他编程语言的使用经验(特别是语法和C/C++接近的),可能会想GDScript怎么没有switch语句呢(当然Python也没有)。传统的switch语句主要是为了在某个表达式取不同的值时执行不同的代码。一方面,多个if语句确实可以替代switch,另一方面传统switch语句中的case只支持常量(字面量),这就限制了它的能力。比如我们没法用switch语句去测试一个对象中的各字段是否满足某个条件。

在相对现代的编程语言(以及一些语言的较新版本中)都衍生出了所谓”模式匹配“(pattern matching)的语法,它的作用之一就是解决switch的局限性。模式匹配可以检查表达式的值是否满足某种模式,而模式可以是多种多样的,可以是类型,可以是某个常量,也可以是对某类对象的各属性取值的要求。

match语句以match关键字开头,后面是一个表达式,然后是一个代码块。代码块中又有若干代码块,它们分别代表一种模式以及该模式能够匹配时执行的代码。match有多种模式可以出现在分支中:

字面量模式很简单,直接检查是否相等。字典和数组模式除了常规的检查各个元素,还支持一个通配符。这个通配符的意思就是只要匹配了明确给出的元素就行,其他的就不管了。

绑定模式(var n)实际上就是让一个变量绑定到整个模式或者模式中的某一个部分,这样在处理这个模式的代码中就可以直接用它而不用再通过match后面的表达式来访问。

还有一个终极的通配符,就是一个下划线。它是作为兜底的模式,正常情况下只应该作为最后一个模式出现在match中。它能够匹配任何的值,相当于switch中的default。C#的模式匹配语法中也有这个东西,给它的名字叫弃元(discard)。但要注意在数组模式中它和两点的区别。下划线只能任意匹配一个,而两点可以任意匹配多个元素。

when分句很好用。它可以在模式匹配之后进行额外的约束。when后面是一个布尔类型的表达式,when前面的模式匹配上之后,when后面的表达式必须为true才能视作整个模式匹配成功。例如我们可以先用绑定模式,然后再让确认它的某个属性是否为真。

match的语法看起来有点复杂,但是合理运用可以减少很多乱七八糟的if-else。在文档中可以看到更详细的例子。

撒花

好了GDScript精要部分就算结束了!下一篇文章开始就要运用前面所学的知识开始做些更像做游戏做的事了!