前段时间和一位前辈吃饭,然后前辈鼓励我,可以写游戏开发教程。出于想练一练自己的文字功底,以及实践自己在 渐构 学到的知识,于是便开始写吧。之前没有写过完整的教程,出现纰漏或者写的不好的地方希望大家多多担待。
我呢,目前是一位研究生,马上毕业,通信相关的。从小比较喜欢游戏,然后自己喜欢做游戏,这是我的个人网站 www.calculuscat.cn,会在里面发一些自己的所思所想,感兴趣的可以去逛一逛。
最终,我会教你实现一个这样的场景,场景里面有一个可以交互的物品,交互后是一个音乐播放器界面。



本教程的前置知识需求不是很多,只需要接触过编程语言,最好是有面向对象语言的基础,例如Python(这个是最好的,因为他和我们需要用的语言很像),C++等。如果你之前只接触过C语言,也没关系,你可以在学习的过程中学习面向对象的知识。
本教程在Win11上进行开发,因此需要你会使用Windows操作系统,具体而言呢,可能需要一些美术素材的编辑还有对于整个项目工程的管理。
虽然说可能需要这样那样的前置条件,但是在大模型如此唾手可得的时代,我们不应该被这些东西所束缚,学习过程中最忌讳的就是概念不清楚,所以有什么不懂请即使跟大模型交流并搞懂你的疑惑。最好的学习方式边学边做,不要害怕困难。
游戏开发你可以理解为指挥游戏引擎中的组件来演一场戏。
比如在游戏中的人物进行移动的时候,以 Godot 这个游戏引擎为例,就是指挥 CharacterBody2D 这个组件来移动。下图是这个组件的具体样子。

对于游戏引擎,你可以这样理解,它是整个游戏的组织者。所有的组件都需要在它的特定规则下行事。
可以将游戏引擎比作拍电影的导演,所有的组件(演员)都要听从它的指引,最终共同来演完游戏这场大戏。
游戏引擎中的组件就是被组织的对象,它有自己的行事规则,但是同时它也得遵循游戏引擎的组织。
可以将组件想想为拍电影的演员,它有自己的知识,比如如何表演喜怒哀来,但是也要听导演的话,导演处于整个表演比较高层。
那你会有疑问,那我写的代码在哪里?怎么用代码控制游戏中的组件?
游戏引擎中一般都会给组件来提供一个脚本附着点,你可以把自己的脚本附着在上面,然后通过你脚本中的逻辑会被游戏引擎替换或者扩展该节点的行为。
比如下图中的 Node 部分对应有个 Script,通过给这个赋值就可以将自己写的逻辑附着在这个组件中。

通常附着一个新的脚本,游戏引擎会给你自动填充一些内容,然后你通过修改这个附着的脚本便可以达到对引擎中组件的操控。
下面是 CharacterBody2D 这个组件附着的默认脚本,其中内容是引擎自动帮你填充的。有代码基础的同学可能大概能看出来这是个从输入中获取内容,然后控制这个组件来移动的代码。

上部分的内容是让你以组件视角来理解一个游戏是怎么样跑起来的,也就是游戏引擎指挥组件来表演游戏这场大戏。
如果你用C语言写过贪吃蛇的话,那么你大概会有这样一种感觉,游戏就是一个巨大的循环,每次循环就是让你处理一些信息,然后在此基础上来生成下一次循环的内容。
#include <stdio.h>
#include <stdbool.h>
int main() {
while (true) {
get_input();
do_something();
render();
}
}当然,游戏引擎做的游戏也一样,是一个大循环,和上面的贪吃蛇游戏做着同样的事情。
下面这个脚本是绑定在 Node2D 这个组件上的,你可以简单理解为就是2D世界中的一个组件。可以看到有两个函数,第一个是 _ready 第二个是 _process,前者会在游戏刚开始的时候跑一遍(当然并不严谨,但是你可以先这样理解),后者会在在游戏的每一帧画面来调用(如果你不懂游戏帧这个概念,你可以先理解为这个 _process 就是上面的 while 大循环)。
extends Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass我们在本次教程中使用的游戏引擎是 Godot , 这是个开源引擎(MIT协议)。
这也就意味着你使用该引擎制作的游戏所得的盈利完全归你所有,当然如果你的游戏上架游戏商城,比如Steam,商店需要向你收取部分费用(Steam为30%)。