大家好~我是灰(微博@天外灰仙儿,gitee@overpara),今天来讲解如何用Godot4引擎做一个简单的桌面宠物,包括Godot4从下载到入门的过程,目的是能让大家做完这个桌宠的同时也可以上手Godot4引擎,从此开启自己的游戏制作大门~后续我也会继续完善这个桌宠,丰富它的功能再把后续的教程更新给大家。

首先让大家看看本期内容最终实现的效果,如图所示:透明背景,可以实现按住右键进行拖拽,点击左键会触发随机对话,并且有报告当地天气的功能~天气的功能实现稍微有点复杂,属于额外的扩展内容,做不完也不要紧!

再来给大家介绍一下Godot4引擎:Godot是一款免费、开源的游戏引擎,目前更新到了第四代,引擎本体非常轻量级,适合小项目和独立开发。

在教程正式开始之前先叠个甲:本人是工科出身,不是做学术的,一切操作都以结果为准,即便过程中有理论错误,只要最后结果是好的就算成功!另外Godot4需要写代码,但是即便你从来没写过代码,我也尽量让你学会,给我和你自己一个机会!

那下面让我们开始吧,如果已经安装过godot4的朋友可以跳转到第二页,如果已经很熟悉godot界面的朋友可以跳转到第三页!

一、下载:

Godot4有两种下载方式,一种是从Steam上直接下载,这种方式的好处是可以一直保持最新版本,还可以记录使用时长。坏处就是Godot的每次小版本更新都会修改一些代码的逻辑,让老版本的代码出现bug。

第二种是直接到godot的官网https://godotengine.org/ 下载,这样就可以稳定在一个版本。

不论哪种形式下载都不需要安装,从steam下载就从steam里直接打开,从官网下载的就直接打开下载的exe程序。

本教程使用的是steam上下载的4.2.1版本,如果你是在我发布这个教程的很久以后才开始学,可以从官网上下载一下和我一样的版本。

二、界面:

当你首次打开godot时,应该是一个项目都没有的(或者有一些范例项目),不论如何,先点击左上角的“新建”。

然后点击“浏览”给你的这个项目选一个空的文件夹,这里我选择的是DeskPetLearn,项目名称会自动命名为文件夹的名字(尽量使用英文,包括后续的文件名和代码里都用英文)。渲染器选择Forward+,版本控制单元不用管。选择好后点击“创建并编辑”。

首先映入眼帘的是3D的编辑场景,我们先点击最上面的“2D”

切换成2D的游戏视图。

先简单带大家过一下界面都有什么东西:

1.菜单栏

2.场景节点管理

3. 项目文件管理

4. 视图管理,最常用的就是2D和Script,分别用来布置场景和写代码。

5. 想让游戏运行的时候点这里

6. 检查器,选中任何一个节点会显示这个节点的属性

下面就让我们正式开始啦,剩下的操作就在正式教程里学!

三、正式开始:创建节点、导入资源

首先点击用户界面,创建一个UI根节点。

会出一个叫Conrtol的东西,这个就是用来布置UI的节点,我们可以用它来担任整个游戏的根节点。

这里说一下节点是什么东西,节点就是挂载在场景里面的一个个元素,这些元素可以是可视化的(比如图片、UI、文字、光照等),也可以是不可视的(比如计时器、动画播放器等)。

节点之间可以存在父子关系,当你移动父节点的时候,所有子节点也会跟着一起移动,类似于绘图软件中的图层关系。

而在godot中,任何一个场景中只能且必须存在一个根节点,其余所有的节点都是其的子节点或者子节点的子节点。

我们现在把根节点改个名字,可以右键选择“重命名”,我就起名字叫“MainWindow”了。

再按ctrl+S保存,我在这里新建一个Scene文件夹用来存场景。

保存好可以在左下角文件系统中看到:

接下来既然要做桌宠,我们肯定要有图片才行,我在这里选择了两张图,一个是闭嘴的时候,一个是张嘴的时候,这里我为了最简单的演示,所以只用了两个图,实际上你用的图越多动画也越丰富。这里用的是我们工作室的OC爱斯(亲妈b站@辉鸦-)。

在文件系统中新建一个Assets文件夹,用来放图片资源。

然后把两张图片拖进去(这个过程在电脑本地文件夹里也可以完成)。

四、创建角色

下一步呢,我们就要捏一下我们的角色了,这个时候我们要新建一个场景。

对于Godot来说,场景(Scene)不只可以代表字面意义上的“场景”,它同样可以代表一个物体,比如我们可以把一个角色制作成一个场景,然后把游戏的背景制作成一个场景,再把角色场景丢到背景场景里,这样做就可以把游戏的每一个素材区分开来了。

在这里我们选择2D场景。

这个Node2D就是所有2d节点的根节点了,我经常把他当成场景里的“文件夹”用:p。

改个名字,保存一下,就存在Scene文件夹里就行。

右键根节点,选择添加子节点。

添加Sprite2D节点,在上面有搜索框可以搜索。可能之前做过游戏的朋友知道,Sprite(精灵)就是游戏里图片素材的意思啦。

点击Sprite2D节点,引擎最右边的检查器里就会出现这个节点的属性啦。

我们可以把准备好的图片拖到Texture这一栏里。

就变成了这样子(我还偷偷给节点改了一下名字,改成了“Portrait”,也就是立绘、肖像的意思)。

在这里我顺便介绍一下如何操作中间的2d视图。

按住鼠标中间可以拖动视图位置,最上面一条是一些基础功能。左边几个最常用,分别是鼠标(q)、平移(w)、旋转(e)、缩放(s)。后面的用到的时候再说,你感兴趣也可以把鼠标悬停在上面也会显示介绍和快捷键,Godot里几乎所有东西你悬停在上面都会有介绍。

接下来,我们希望玩家可以点到她!那我们需要给她添加一下碰撞区域,让我们的鼠标能够点击到她啦。

我们右键Portrait节点(也就是刚才创建的Sprite2D节点),选择添加子节点,再选择Area2D节点。

创建完毕后,右边有一个小感叹号,这是因为我们虽然给她创建了一个碰撞区域,但是还没有给这个区域划范围。

我们继续在Area2D节点上右键,添加一个子节点:CollisionPolygon2D。

这下发现感叹号并没有消失,只是转移了!

那我们只需要在视图里,用鼠标工具(q)来沿着图的边缘点一圈,围出一个图形就可以了。注意一定要首尾相连!如果你希望玩家点这个桌宠的时候容错大一些,那就把范围稍微画大一点,如果你希望玩家点的时候精准一些,那就把范围画小一点~如果你是一个强迫症,那就要把边缘画的跟图片边缘严丝合缝了!

最后画完是这样的。

如果你觉得自己选的范围不满意,那可以点右边检查器里的这个小圈箭头还原。如果你发现你的检查器里没有这个,那就重新选中一下CollisionPolygon2D节点,Godot经常有检查器刷新不及时的bug。

然后咱们来做一个说话的动画吧!

首先右键根节点,创建一个AnimationPlayer节点。

这个时候引擎下方会弹出一个调试面板。

我们点这里新建一个动画,就叫Speaking吧!

这个动画面板包含了所有动画需要的基础功能,大家感兴趣可以把鼠标悬停在每个按钮上看一下是干啥的,我接下来就只介绍我用到的功能。

这个是动画的总时长,我就默认1秒了。它右边的双箭头是开启循环模式的意思,我没有开启,这个按钮还可以设置成乒乓动画,就是来来回回的那种动画。

咱们把这个指针调到0的地方,也就是第零秒。

然后我们选择Portrait节点,点检查器的这里添加一个关键帧。

弹出的这个要勾选上,然后点创建。这个RESET轨道是用来设置动画没有播放的时候的默认值的,比如你做一个角色飞来飞去的动画,需要设置一下角色没做这个动画的时候处于什么位置之类的。

因为我们默认情况下本来就是闭嘴的,所以这一帧把闭嘴的图片同时放到了动画的第0秒和RESET状态了。

然后我们改一下吸附的单位,设成0.25秒,这样就可以把每一帧间隔0.25秒吸附喽。

接着我们把指针放在0.25秒的位置上。(ctrl加鼠标滚轮可以放大缩小轨道)

把张嘴的动画拖到Portrait节点的Texture里,再点击添加关键帧。

接着把指针调到0.5的地方,左键第一个关键帧,再右键一下第一个关键帧,选择复制关键帧,就会自动把第一帧复制到指针所在的位置上。

再如法炮制,把第二个关键帧复制到0.75秒上。最后把第一帧复制到1秒上。

最后点击这个,看看是否能正常播放。

这样有关角色的地方就编辑完啦~接下来我们还需要获取玩家点击到她的这个事件!下一部分就开始写代码啦~

五、初识代码

先选择根节点,然后点这个来添加脚本(Script),脚本就是用来写代码的文件。

这个默认就好,我习惯把场景的脚本和场景放在一起啦。

现在我们就处于代码窗口了。

首先我们可以看到第一行,extends Node2D的意思是根节点本来就是个Node2D类的节点。

然后我们要再写一行,声明一下我现在要写的是Character类!

在判断玩家鼠标点击之前,我们需要先设定一下鼠标点击是什么。

选择最上面的项目-项目设置。

选择输入映射,在框内输入“ChatStart”,这个可以自己起名字,代表对话开始,然后点击添加。

然后点这个加号。

在框里点击一下鼠标左键,记录一下,然后点确定。

我们用同样的方法把p+alt退出的按键也加进去,毕竟桌宠没有窗口边框,想要退出用快捷键方便些啦。

在正式开始写代码之前,我想先给大家介绍一下代码的组成部分。总的来说,代码可以分为变量(var)和方法(func)。其中变量用来存储所需要的数据,方法用来对这些数据进行处理。

举个最简单的例子,我想计算1+2等于几,那我可以这样写:

var a = 1

var b = 2

func plus():

var c = a + b

那当我们执行plus()这个方法的时候,c的值就是3了。区分方法和变量不仅是声明的时候前缀var和func不一样,方法后面还会跟着一个括号。

为了让我们的代码编写更加方便,我们还需要打开一下代码补全,在编辑器-编辑器设置里。

在常规-文本编辑器-补全里,像我这样勾选就好啦。

接下来我们再讲一个概念(我保证是最后一个了!),那就是信号(signal),当一个节点被特定的操作时就会发出信号,这个信号可以被其他节点截获,或者可以自动执行编写好的方法。举个例子就是,假如场景中有一个退出游戏的按钮,当玩家点击这个按钮的时候,这个按钮就会发出“我被按啦”这个信号,那我们可以事先把这个信号和退出游戏的方法绑定在一起,这样玩家点击退出游戏的按钮时就可以真的退出游戏了。

那么现在,我希望先把玩家按住右键移动这个信号先拿到,所以我们先选中Area2D节点,这个时候在检查器里点击信号,就可以切换到这个节点的所有信号。那么下面这个input_event就代表了玩家的输入事件了。

我们双击一下这个input_event,引擎会问我们要把信号连接到哪里,我们就连接到我们的Character节点上的脚本,也就是我们刚刚新建好的脚本。默认就在当前场景的根节点上,我们直接点击连接就行啦。

这个时候引擎会自动帮我们写好了一个方法,当我们的Area2D节点检测到有输入时,这个方法就会被自动调用啦!现在方法里还只有一句pass,pass的意思是啥也不干,在这里就是用来占位置的。顺带一提,在Godot里,代码也存在着层级关系,比如这里pass是这个方法的一部分,那么pass前面就必须按tab进行一个缩进。

接下来我们需要获取到玩家鼠标移动这个输入,那我们要写一句如下的代码,这句话的意思其实稍微懂一点英语的人都可以直译一下啦,就是“如果事件时鼠标移动输入事件”,后面再跟个冒号,代表这个条件成果时要执行的代码。关于这个event是啥,大家可以在方法名字后面的括号里看到,event就是一个输入事件,我们只是判断一下这个event具体是属于哪种类型。

那光是鼠标移动也不够呀,我们还需要玩家按的是右键移动的,那我们再后面加上如下代码,这个and的意思就是要同时满足and前面和and后面的条件,才会执行下面的代码。而我们在and后面补上的内容也顾名思义,就是鼠标右键的意思。在代码中,==两个等于号代表着数值比较,=一个等于号代表把右边的值给左边。比如a=1,b=2,我令a=b,那这个时候a和b就都是2了。当判断的时候用a==b,只会判断这两个值是否相等,不会改变a的值!

然后我们换行,再打一个缩进,让下面的代码成为我们上一句的孩子,那满足条件后就会执行下面这一句了。如果不打缩进的话,下面这一句就会无视上面的条件,直接执行。我们加这一句的意思我也来解释一下,get_tree()是一个godot自带的方法,意思是获取当前正在运行场景的场景树,当我们做完游戏的时候,把哪个场景作为主要的游玩场景,玩家玩的时候正在运行的场景树就是哪个了。比如对我们这个游戏来说,我们一开始建的MainWindow场景就是了。后面的root是场景树的一个属性,代表着当前的窗口。position又是窗口的一个属性,代表着窗口所在的坐标。坐标在2d游戏里自然是一个二维向量(Vector2),代表着横坐标和纵坐标的值。event也有一个属性叫relative,代表着鼠标相当于前一帧所在的位置。

把这个值包裹起来转化为Vector2i类型,这里i的意思是整数(int),然后把这个相对值不断地加给窗口的坐标,就可以实现窗口跟随鼠标移动啦!+=的意思就是让坐标的值加上右边的值,再把结果覆盖左边的值。

接下来,我们需要把鼠标左键点击对话的事件也给加进去。但是我们这个场景只负责角色,不负责对话,那怎么把鼠标左键点击这个事件告诉给别的场景呢?很简单,我们也可以自定义一个信号!

在代码的上面,写一句如下代码,定义一个信号。我就起名叫chat了。

然后ctrl+s保存一下,然后选择我们的Character根节点,右边的节点里就会出现我们定义的新信号啦!

当然这个信号现在是没有发出的,我们需要给它设定一个发出的条件。那回到我们刚才的方法里,加一行,判断输入事件是不是我们设定的“ChatStart”,也就是我们之前设定的左键。is_action_pressed就是用来判断哪个输入映射的按钮被按下,括号里的输入名字要加英文双引号。注意我的缩进格式,两个if语句应该是同级别的,所以都是缩进一次,if包含的需要执行的语句是缩进了两次。

那我们再写一下,当鼠标左键按下的时候,发出chat的信号。emit()方法是信号自带的方法,就代表着发送的意思。

我们也可以按住ctrl键,点击一下emit,就能看到方法的介绍文档。

想要返回刚才写代码的地方,可以点代码视图右上角的左箭头,也可以按住alt点键盘上的←(如果一次没跳回去就多点几下)。或者可以直接点左边找我们之前脚本的名字。

别忘了,我们还有一个动画没有用呢。这里我们需要在节点列表里,把AnimationPlayer节点拖拽到代码里,当拖拽到代码视图里的时候别松手,按住ctrl再松开鼠标左键,当出现如图的代码时,也可以松开ctrl了。这句话的意思是游戏开始的时候就把我们的动画播放器的节点放到animation_player这个变量里。后续我们对这个变量操作,就相当于我们对节点操作。

那我们可以在点击鼠标左键的时候,播放说话的动画。play就是播放,括号里是动画的名字,记得加英文双引号!

好了,角色的代码我们都编写完了,记得保存一下!如果你怕自己过一会儿忘了自己代码写的是什么意思,可以在代码旁边打上备注,也就是“注释”。Godot注释的写法是#后面打字,#同一行后面的所有字符都不会执行,所以也可以用来屏蔽掉暂时不用的代码。快捷键是ctrl+k。

六、实现主要功能

做完角色后,我们先把角色放到主窗口里试试吧!回到刚才的MainWindow,记得点一下2D。

右键MainWindow节点,选择实例化子场景。

就选择Character就好啦,点打开。

虽然打开了,但是位置并不是我们想要的,场景里蓝色的这个框是游戏运行的时候的窗口。

那我们按w变成移动工具,把Character移动到蓝框内部。如果你觉得人物太大了,可以按e缩放工具把人缩小,按住shift缩放可以保持比例。

移动完之后感觉窗口太大了,我们需要把游戏窗口缩小一些。在这之前我们先量一下需要多大的窗口。可以用鼠标从边缘的标尺上拖拽出一个参考线,拖拽的过程中还能看到参考线上的值。

如果你对尺寸和位置有精确的需求,可以打开这个栅格吸附。

点击这里可以设置栅格的大小。

因为右边我还要留一些地方给对话,所以就空的多了一些。

如果想要取消参考线,可以在标尺上把参考线拉到边缘去。

量好尺寸后,点击项目设置。

按照之前量的尺寸把窗口大小设置好,同时点右上角的高级设置,把我框出来的勾都勾选上。

下一步我们先选择MainWindow节点,看右边的检查器的这个属性。

我们需要把Filter改为Ignore,不然我们鼠标的输入事件都会被MainWindow节点截获,传不到Character那里去。

然后可以运行一下试试,点右上角的播放。

运行之后,左键点击播放说话动画,还有右键移动应该ok了,但是背景还没有透明,明明我们已经在前面设置了背景透明,这是为什么呢?

先点击这个停止按钮可以关闭游戏。

我们再回到刚才设置透明的地方,把鼠标悬停在透明那里,会出现提示。原来这个透明只是允许背景透明的功能可用,实际要设置透明需要设置一下transparent_background属性。

我们在MainWindow新建一个脚本。

新建一个_ready方法,如果你开了代码补全的话,打几个字母应该就有提示了。注意ready前面一定要有一个下划线。这个方法是Godot固定使用的方法,代表着这个节点进入场景树时首先执行的代码,也可以称为初始化方法。也就是说当我们启动游戏时它会被自动执行。

我们对root执行设置背景透明的方法就可以了,true和false分别代表了开启和关闭。

这个时候再运行一下游戏,背景就透明啦。

下面我们添加一个退出游戏的方法,还是在MainWindow脚本里编写。_unhandled_input方法也是监测玩家输入的,和之前我们写的那个不同的是之前那个监测的是跟Area2D互动的输入,现在是监测全局输入。unhandled意思是如果其他节点或者方法不要这个输入,那我就拿来用。聪明的你可能也已经发现了,这种Godot自带的方法前面都有一个下划线。不过到目前为止我们还没有写自己原创的方法呢!

在这里判断一下是不是我们之前设置的退出快捷键,如果是的话就调用场景树的quit()方法,退出游戏。这里写完也可以运行试一下。

接下来我们再新建一个场景,用来处理对话,这里我们可以选其他节点,然后找Label节点。

改个名字,保存一下。

在检查器的Text里可以输入文字来改变显示的内容。

在这里可以设置水平对齐和垂直对齐形式,因为我想把文字放在右边,所以水平设置的是右对齐,垂直设置的是居中对齐。

字体的样式可以在检查器的Control标签里的Theme Overrides里修改。

比如这里我勾上了文字阴影和轮廓。

这里我改了一下轮廓的大小。

这里我使用了得意黑字体(来自b站up主@oooooohmygosh的开源字体)。

这里我改了字体大小。

最后效果是这样的。大家也可以根据自己的喜好随意调整。

下面我希望让字可以一个字一个字蹦出来,但是每句话出现的总时间是一样的(你也可以设计成根据句子长度不一样,这里我图方便先弄成全都一样的了)。

先在场景里添加一个AnimationPlayer节点,然后新建一个动画,我就起名字叫ChatSpeaking了。

建好后,选中ChatText节点,在检查器里找到Visible Ratio,把它改成0,然后在动画0秒加一个关键帧。

再把数值改回1,在动画结尾加一个关键帧。然后播放一下就可以看到文字一个字一个字蹦出来啦!

下面给ChatText也加一个脚本,用来方便主场景调用它播放动画。

上来也是给一个类名,聪明的你一定发现了,MainWindow没有写类名,而Character和ChatText都加了类名。因为这两个场景都是被MainWindow所调用的,写个类名后续方便一些。

然后我们像之前一样,把AnimationPlayer拖进代码里,按住ctrl再松开鼠标左键。

然后我们定义一个专门用来播放动画的方法,叫什么名字都可以。这里的箭头就是一个横杠加一个大于号啦,void代表着它没有返回值(什么是返回值等用到的时候再说),括号里面什么都不写,代表着使用这个方法的时候不需要在括号里写参数。比如使用get_tree()的时候括号里空着就行,用animation_player.play的时候,括号里要写动画的名字。

写完后保存一下,我们回到MainWindow场景里,实例化一下子场景,选择ChatText。这里空空如也是因为我们的动画的RESET值就是把Visible ratio设的0,这个没有关系。

选中ChatText,在视图上面点击这个可以设置锚点,因为我想让对话框在右侧居中,就选这个了,你们可以选别的。

点击这个进入MainWindow的脚本。

我们现在需要通过Character被点击这个事件,发出信号,告诉MainWindow,再让MainWindow调用一下ChatText的动画播放的方法。

所以选择Character节点,在右侧找到之前我们定好的信号,双击一下连接到MainWindow的脚本里。

然后我们把ChatText也拖到脚本里。忘记怎么拖的朋友可以看看前面,后面这种反复出现的操作我就不会再说啦。这里可以看到,变量冒号后面就是变量的类型,chat_text的类型已经是我们之前定义好的类名(class_name)了。

然后在信号连接的方法里,调用一下我们之前写好的方法。我们也可以看到输入play的时候代码就已经给提示可以补全了,这就是声明类名的好处!写完后就可以把pass删了。

现在运行一下试试,已经可以出现台词了,位置和大小可能还不太对劲儿,我们可以慢慢调整。

七、完善功能

现在只有一句话能显示,有点单调啊,我们可以多来几句话,这个时候就需要字符串(String)和数组(Array)了。

我们回到MainWindow的脚本里,在上面声明一个变量,凡是在方法外面声明的变量都叫全局变量,在方法内部声明的叫局部变量,局部变量的特点就是每次方法被调用的时候变量值都会被初始化,方法结束后变量就会消失。也就是说全局变量可以让数据保持上一次被使用的状态,局部变量不行但是可以节省内存。

我起名叫sentences,冒号后面是它的类型,Array[]代表数组,方括号里代表着数组里都存什么数据,String代表着字符串数据,也就是文字。

我们在_ready方法里可以初始化一下这个数组。数组的值初始化的时候用方括号括起来,里面每一个元素用逗号隔开,因为我们是字符串数组,每一个元素都要用双引号括起来(最后再重申一遍,都用英文的符号!),双引号内部都属于文字了,所以可以用中文的标点符号。

下面我们把之前跟chat信号连接的方法里加一句,大家还记得我们可以在ChatText的text属性里改文字吧,那我们每次调用播放文字方法的时候就改一个句子就好啦!pick_random()是数组自带的方法,意思是随机调用一个数组元素。这句代码要在动画调用的前面,以防显示错误。

现在运行试一下,每次点击都会随机出现一个句子啦。那我们有的句子可能太长了,怎么处理呢?

可以在字符串里面,把想要换行的地方加一个\r\n,注意斜杠的方向,别用错啦!用对了的话\r\n应该是蓝色的!

这个时候有聪明的朋友就会问啦,如果我真的想让句子里出现“\r\n”怎么办,那就在前面再加一个斜杠就好啦~

最后一个要解决的就是我希望过一段时间文字会消失。可以回到ChatText场景里,新建一个Timer子节点。

        

选择Timer,在右侧检查器里,设置wait time为10秒,选上oneshot。代表着进行一次10s的倒计时。

然后把Timer拖到ChatText的脚本里。

在之前写好的播放动画的地方后面加一句定时器的启动方法。这样每次有新对话出现都会重新计时。

选中Timer,在右侧找到第一个信号,双击连接到ChatText脚本里,这样在计时器每次结束的时候都会执行这个方法。

在连接的方法里,把visible_ratio改成0,因为我们现在就在Label上挂载的脚本里写代码,所以这里的属性不用带主语,visible_ratio默认就是自己的属性。

这样再运行一下,文字就会过十秒自己消失啦~

好啦,本期的正式内容就到此为止了,下面我们来教一下扩展包!如何显示天气,以及如何打包导出这个桌宠为exe程序。想要学打包的可以直接跳到后面。

扩展包、实时报告天气+打包成exe程序

首先我们需要在网上搜一个免费的天气Api,直接百度天气api,就会有很多大佬给你介绍哪种api好用。然后复制下来你的api接口链接,在你申请api的官网应该都会有配套的申请教程,如果没有那就换一个……

下面在MainWindow里添加一个HttpRequest子节点。

改个名字就叫WeatherApi。再给WeatherApi添加一个Timer子节点。因为免费的api一般都是限制每分钟最多访问次数的,而且频繁地访问天气又占流量又没必要,毕竟当地的天气变化不是那么快的。

给Timer也改个名字,就叫WeatherRequestTimer。

选择WeatherRequestTimer,在右侧检查器里,设置wait time为60秒,autostart也选上。代表着定时不断进行60秒的倒计时。

把WeatherApi节点拖到MainWindow脚本里。

顺便声明两个变量用于存储天气和温度,都是String类型的。

在MainWindow脚本里写一个新的方法。

在里面调用一下自带的request方法,括号里就填你的api链接。在这里我以心知天气为例。

在_ready里直接调用一下,要在给句子赋值前面写,因为我会把查询到的天气放到句子里。

找到WeatherApi的第一个信号,连接到MainWindow脚本里,这个信号是请求到api数据后发出的,也就是我们收到天气信息后。

在连接的方法里写下面这两句,有点复杂,如果下面理解不了的话就直接照抄吧。这里我定义了一个叫json的变量,body是接收到的数据流,get_string_from_utf8是把数据流转化为utf8编码格式的文字,然后用JSON类的parse_string方法对文字进行解析,最后转化为字典(Dictionary)类型,赋值给json变量。最后再用print方法把这个字典打印出来。

这样我们运行的时候,视图下面就会输出json的数据。(里面的地址只是api的地址,不代表我本人居住的地址,在api的链接里可以随意切换城市地址)

我们分析一下这个数据,大括号{}括起来的就是字典,方括号[]括起来的是数组,冒号左边是字典的键(key),冒号右边是字典的值(val)。

我们只要调用字典的键,就可以获得字典的值。

比如我们可以看到第一个键,results,其余的所有东西都是results的值。它的值是用方括号括起来的,所以是一个数组,数组里只有一个元素,就是一个被大括号括起来的字典。这个字典里有三个键,分别是location、now和last_update,我们需要用的数据都在now的值里。now的值也是一个字典,这个字典里有三个键,分别是text、code和temperature。我们需要的就是text和temperature的值,分别就是天气和温度的值。

怎么样,是不是有一种从前有座山,山里有座庙……的感觉,不过只要你耐心分析,我相信你是可以看懂的!。

接下来我们不需要print了,把它删掉(你也可以留着,如果你没有调好的话),换成我们需要的值传到我们的theDay和temperature里。以theDay为例,就是用json里results键的值的第0个元素(计算机语言里都是从0开始计数的),再取这个元素的now键的值,再取这个值里的text键的值。最后as String一下代表取的是字符串。

然后我们需要再sentences里加一个空的字符串,直接打个双引号就好了,留着给天气用的。数组太长了不好看的话,可以像我一样排个版。

然后回到刚才的方法里,把sentences的第三个元素(还记得是从0开始算的吗)改成我们要写的关于天气的话。字符串直接可以用加号+连接。

最后,我希望可以每60秒调用一下这个api,那就找到刚才设置的定时器,有一个timeout信号,连接到我们的MainWindow脚本里。

写上我们的Request函数,就完成了!

最后再运行一下游戏,已经可以进行天气播报了。

最后的最后,我们来学一下怎么打包游戏,这样还可以发给别人玩!

首先你需要到github上搜一下rcedit,现在最新的是2.0.0版本。如果你是64位电脑就下x64,32位电脑就下x86(现在应该没人是32位电脑了吧)。

下这个releases里的。

选exe后缀的。

下载后记住这个程序的位置,不要放在你的游戏工程文件夹里,路径也不要有中文。

另外准备一个游戏的图标,要方形的,也放在游戏文件夹里。

老地方,编辑器-编辑器设置。

导出-windows-rcedit,把刚下好的软件选好。

项目-项目设置。

这个位置的图标是电脑任务栏的图标,可以改成和我们的icon一样的,或者你随意。

项目-导出。

添加-Windows Desktop。

导出路径和文件名选一下。不要导出到游戏工程文件夹里。最好找一个单独的空文件夹。

图标选一下。

然后点左下角的全部导出,选择发布。

然后在导出的地方就可以看到了,这两个文件一定要同时在一个文件夹里哦!

点击运行后还发现一点小问题,就是每一句话的间隔变得很大,应该是Godot和windows系统的换行逻辑不一样,我们把代码里的/r都删掉就好了。

然后重新发布一下就好啦。

不过如果你最后输出显示没有问题应该就不需要改了捏。

好了,全部内容都结束了,如果遇到任何问题或者想要我的源码,可以评论或私聊我。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐