133 个可以直接在编辑器里打开的项目。每个都是纯 GDScript,自己构建场景,因此没有任何需要导入的资源。
一个球横穿屏幕并在边缘反弹。这是最小的循环:读取 delta,移动,取反速度。
两个形状追同一个目标,一个用 lerp,一个用 move_toward。两者之间的滞后差别就是全部要点。
三层嵌套的 Node2D 和两次旋转。子节点因为父节点在转而公转,孙节点又绕着子节点转。
逃跑者躲开鼠标,追逐者跟着逃跑者。两边都用 direction_to,只有符号不同。
一艘 Asteroids 风格的飞船和八块石头,从一边出去就从另一边回来。两次 wrapf 调用就够了。
一个 Line2D 在指针处添加新点,满了就丢掉最旧的。宽度曲线和渐变负责淡出。
按住左键绘制。每一笔都是一个新的 Line2D,右键清空画布。
逐点构建的 Curve2D,用 tessellate 绘制,由三个 PathFollow2D 沿着走。唯一变化的只有进度值。
临界阻尼弹簧和 lerp 跟随器追踪同一个移动目标。弹簧跟得上,lerp 总是落后。
一个循环移动的自由位置,以及同一个位置经过 snapped 之后的结果。蓝色方块只会停在网格点上。
九个形状共用同一条正弦波,每个都比前一个提前一个相位。不用 Tween,也不用 AnimationPlayer。
同一个速度常量分别在有和没有 delta 的情况下使用,每行都显示走过的距离。第二行的快慢完全取决于帧率。
用 CharacterBody2D 实现重力、跳跃和地面检测,平台由代码生成。
十六个箱子落在两堵墙之间。想看物理求解器干活时,第一个该试的例子。
十二个互相铰接的链节,末端挂着一个重物。点击推动链条,看它慢慢稳定下来。
三根静止长度相同、刚度和阻尼各异的弹簧并排放置。
一个统计有什么东西掉进来的区域,用的是 body_entered 和 body_exited 信号。
二十八条射线朝鼠标呈扇形展开。碰到墙的那条会变红,这就是最简单形式的视线判断。
一个方块在移动前先问自己会停在哪里。那个虚影就是投射返回的安全比例。
从下面可以穿过蓝色平台,从上面则能落在上面。一个属性就搞定了全部。
三个球从同一高度落下,配三种 PhysicsMaterial 设置。bounce 的取值就是全部差别。
两条一个像素都不动的传送带。constant_linear_velocity 会拖动接触它们的任何东西。
54 个箱子组成的墙,点击会把它们推开,力度随距离衰减。
点击就往地面丢一个 RigidBody3D,看它们堆起来。你生成的会在十秒后自行清除。
二十块骨牌排成曲线,只给第一块一个冲量。之后的一切都交给求解器。
一扇由带角度限制的合页固定的门。点击推动它,看限制在哪里挡住了摆动。
三个刚度不同的 SoftBody3D 方块落地。变形的是网格本身。
一个跟随鼠标的发射器,配上程序生成的圆点纹理和颜色渐变。用的是 CPU 粒子,也就是网页渲染器能画的那种。
一层 one_shot 火花叠在一层 one_shot 烟雾上,一起重启。点击可以移动爆点,或者等计时器再次触发。
一个沿路线行进的点,以及只在它移动时才工作的发射器。emitting 来自测得的速度,local_coords 让拖尾留在身后。
两个颜色渐变不同的叠加发射器,下面是加色的火焰,上面是混合的烟柱。点击可以往两者中吹一阵风。
雨滴的 lifetime 按落差设定,地面线上还有一组 one_shot 发射器负责溅起水花。点击可以自己加一朵。
两门炮发射带重力和旋转的纸条。恒定的 color_initial_ramp 给每一片分配一个纯色。
基础控件集中在一屏,每个都通过自己的信号向同一个标签汇报。
同样的四个方块交给四种容器。在 Godot 里做布局,就是选谁来安排子节点。
六个用布局预设固定的面板。调整游戏画面大小,每个都守住自己的角落。
同样的三个节点出现两次,差别只是几行 add_theme。
加粗、颜色、wave、shake 和 rainbow,全都是一个标签里的 BBCode 标签。完全不涉及动画节点。
一个 Timer 填充进度条,可以暂停和继续。进度条读的是 time_left,它自己并不计时。
筹码在插槽之间移动。三个方法完成全部工作:_get_drag_data、_can_drop_data 和 _drop_data。
一棵两列的场景树,由一个递归函数从嵌套字典构建而成。
支持多选的 ItemList,可以移除选中的行,也可以再放回去。
一个侧边面板和三个标签页共享宽度。拖动分隔条,两边一起变化。
四个带端口的节点,拖拽即可连线。GraphEdit 负责画曲线,是否接受连接由你决定。
完整的选择器连着实时预览、十六进制读数和一排保存的色块。
一个右键菜单和两个对话框,各自通过自己的信号回报结果。
九个按钮通过 focus_neighbor 连成环形,用 tab 和方向键遍历。这是一套不用鼠标也能操作的界面。
一个被限制在圆环内的摇杆,驱动一个圆点移动。在手机上同样的代码响应触摸。
网格中的六张卡片,视口变窄时从三列变成两列。
六种基础网格排在旋转的环上,每个都有自己的材质:金属、粗糙和自发光。
196 个立方体随正弦波起伏。搭建时两层嵌套循环,每帧一行数学。
WASD 驱动 CharacterBody3D 在柱子之间穿行,相机在后面跟随。不用鼠标转视角。
按住左键拖动可绕中心物体转动相机,滚轮缩放。偏航、俯仰和距离就是全部状态。
八个锥体对同一个移动的球体调用 look_at。每帧一次调用就替代了全部三角函数。
嵌套的 Node3D 支点各自以不同速率旋转。卫星绕着行星转,同时免费继承了行星的公转。
一个与球体保持相交的方块,被三个圆柱钻孔,而圆柱每两秒在相减、相并和相交之间切换。
两个 MultiMeshInstance3D 节点绘制出四千棵树,树冠使用逐实例颜色。
公告板模式的 Sprite3D 宝石,纹理由代码逐像素绘制,每个都由 Label3D 标注名字。中间那块牌子关闭了公告板以作对比。
同样的几何体和同样的白色材质出现三次。cull mask 让每盏灯各管场景的三分之一。
金属球在不使用屏幕空间反射的情况下映出一间彩色房间。三种粗糙度显示镜面变模糊的速度。
五个方块和五个手写的 Transform3D:单位矩阵、原点、旋转 Basis、缩放 Basis 以及三者的组合。一个虚影标出单位矩阵的位置。
由 TIME 驱动的全屏 canvas 着色器。改一个 uniform 并保存,项目就会重新加载。
精灵存的是调色板索引而不是颜色,所以轮换调色板就能重绘整幅画面。
在普通 2D 场景上叠加桶形畸变、扫描线和色差。整个效果只是一次全屏处理。
在 3D 场景上做去色、暗角和胶片颗粒,只用十一行读取屏幕纹理的代码。
一个顶点随波浪起伏、自发光同时脉动的球体,写在 spatial 着色器里。
用 GDScript 生成的噪声纹理配合着色器里的 discard,阈值处还有一圈燃烧的边缘。
法线与视线之间的夹角,取幂之后作为强度。三个形状,三种边缘光强度。
在着色器的 light 函数里把光照量化成色阶,再加一个硬边高光点。
带星星的程序化日落,写成 shader_type sky。太阳的圆盘跟随光照节点。
相机前的一个四边形读取 DEPTH_TEXTURE,因此雾知道每个像素有多远。
噪声推动屏幕 UV,并遮罩到画面下半部分,好让差别一眼看清。
波浪写在顶点着色器里,法线由导数重新计算,因此光照会跟着波浪走。
一个平面,没有任何纹理。fwidth 让每条线无论相机多远都保持一个像素宽。
四个没有 UV 的网格,从世界的三个轴向投影贴图,再按法线混合。
六种 FastNoiseLite 类型并排展示,同一个种子且不加分形,好让每种的特点显出来。
高度图通过 SurfaceTool 变成 ArrayMesh,再用顶点色按高度着色。
噪声乘以径向遮罩,再逐条绘制进 Image。点击生成另一座岛。
用回溯法挖出的完美迷宫。通道按挖掘顺序出现,颜色也按这个顺序区分。
互不重叠地摆放房间,再用随机游走在每一对之间挖出走廊。
一个字符串被两条规则重写四次,然后当作海龟绘图指令读取,每根树枝一个 Line2D。
噪声为屏幕上每个点给出一个角度。箭头显示这个场,粒子跟着它走。
噪声场的等值线,随着阈值扫过而重绘。场本身从不改变,改变的只是切面。
每帧清空并逐顶点重建的网格,包含一条线带和一个线面。
同一个实体用 SurfaceTool 提交两次,一个硬边一个平滑。区别只在平滑组。
运行时构建的 MeshLibrary 加上由高度图填充的 GridMap,每个格子一个立方体。
图集是逐像素绘制的 Image 的 TileSet,再一格一格摆到 TileMapLayer 上。
三次 Geometry2D 调用并把结果画出来:多边形求交、凸包和多边形偏移。
用代码烘焙的导航区域,以及一个绕着四个角走的代理。点击任意位置可以把它派到别处。
同样的思路搬到三维,NavigationMesh 在加载时由基础网格烘焙而来。点击地面选择目的地。
三个障碍物不断进出导航网格。每次切换都会重新烘焙区域,代理走的是当时还通着的那条路。
墙壁会封锁格子,黄色格子的通行代价是六倍。得到的是最省成本的路线,而不是最短的那条。
四十个点按距离相连,AStar2D 在其中两点之间寻路。这里没有网格,图就是你连出来的样子。
靠近和远离就是同样两行代码翻转一个符号。画出来的向量分别是期望速度、当前速度和两者之差。
每个代理瞄准的点只在身前的圆上微微滑动。正是这一点让游荡看起来像有意图,而不是噪声。
七十二个 boid 对小半径内的同伴执行分离、对齐和聚合。每个的颜色取决于它能看到多少邻居。
一个 enum 加一个 match 块驱动巡逻、追击和返回。底部那条显示的是最近几秒的状态。
带位置平滑和四个 limit 属性的 Camera2D。黄色十字是相机中心,可以看到它停在边界上而玩家继续往前走。
随时间衰减的 trauma,从 FastNoiseLite 采样后作用于相机的偏移和旋转。每 1.2 秒触发一次爆炸,滑块控制强度。
拖动平移,滚轮以指针为中心缩放而不是屏幕中心,这只是在 Camera2D.zoom 之上加两行数学。
一个 3D 场景在 SubViewport 里渲染,并作为 2D 画面中那台显示器的纹理呈现。
并排的两个 SubViewport 各带一台相机,同时看向同一个 World3D。每个画面跟随自己的立方体。
一台拉远的 Camera2D 放在共享游戏 World2D 的 SubViewport 里。HUD 不属于那个世界,所以不会出现在地图上。
三个 scroll_scale 不同的 Parallax2D 图层,用 repeat_size 重复,相机移动时山脊永远不会用完。
当墙挡在相机和角色之间时,SpringArm3D 会把相机拉近。读数对比了 spring_length 和摇臂实际得到的长度。
五个方块横穿屏幕,每个对应一种过渡曲线。这是看清每种缓动效果最快的方式。
一个 tween 连续跑四个步骤。tween_callback 让当前步骤在屏幕上亮起,parallel 则把两个属性放进同一个步骤。
启动时逐帧写入的位置轨道和颜色轨道,没有任何 .anim 文件。下方的时间轴显示的就是代码插入的那些关键帧。
逐点构建并用 sample(t) 读取的 Curve。图表由驱动方块的同一个资源绘制,旁边是一个只按时间移动的方块。
启动时在 Image 缓冲区里绘制的八帧行走循环,交给 AnimatedSprite2D 播放。底部那条就是 SpriteFrames 本身。
一条由单个 Polygon2D 蒙皮到两根骨骼上的关节手臂。旋转 Bone2D 会带动权重在它上面的顶点。
两边是节奏完全相同的同一个跳跃,只有右边对缩放做了 tween。多出的三行就是全部差别。
待机、蓄力、冲刺和恢复,每个状态都有自己的 tween。进入新状态会杀掉上一个的 tween,所以它们不会争抢同一个属性。
用代码创建的六节骨骼链,每帧通过 set_bone_pose_rotation 摆姿势。每个 BoneAttachment3D 都带着跟随自身骨骼的网格。
正弦波、方波和锯齿波被逐个采样写入 AudioStreamGenerator。Line2D 画出的正是缓冲区正在填充的那条波形。
一段生成的扫频被路由到独立总线,由 AudioEffectSpectrumAnalyzer 测量。标记是信号源频率,柱状图是分析器读到的结果。
一个可点击的音符网格循环播放。每个点亮的格子都会往同一个生成缓冲区里加入一个衰减的音。
物体穿过钉柱落下,撞击声由代码生成,并根据每个物体撞击时的速度用 pitch_scale 重新调音。
生成的拨弦声从 Voice 经 FX 送到 Master,混响和失真可以随时开关,每条总线的峰值电平都显示在屏幕上。
一个带 max_distance 和 attenuation 的移动音源,旁边的条形图显示 AudioStreamPlayer2D 对生成音施加的同一条衰减曲线。
启动时用 InputMap.add_action 创建的五个动作,全都没有写进项目设置。面板列出每个动作对应的按键,按下时会亮起。
摇杆、扳机和按键直接从 Input 读取并实时绘制。没插手柄时会提示,方向键依然能驱动 ui 向量。
四个按钮对应 Input.mouse_mode 的四个取值。圆点跟着 event.relative 移动,这正是指针被捕获后仍然有效的那个值。
单指拖动卡片,双指捏合缩放。同一套处理逻辑会回退到鼠标按键和滚轮,也就是桌面浏览器走的路径。
点一个按键,再按下另一个,动作就换到新键上。抢走别的动作的按键会让那个动作变成未绑定,这正是重映射界面必须处理的情况。
一个节点声明信号,却从不知道谁在监听。五个面板连上它,轮到自己时就亮起。
七十二个方块分成四组。一次 call_group 就能触达一整组成员,不需要任何引用。
把场景状态的字典以 JSON 写入 user://,文件内容就显示在实时数值旁边。
带 class_name 的 Resource 被当作类型化数据使用。六个条目共用同一个脚本,每张卡片都靠 changed 信号重绘。
两个喷泉以相同速率生成,一个每次都新建粒子,另一个从池里取回。让计数器来说明问题。
每帧采样帧率、静态内存和节点数量,画进三张实时图表,同时一波节点不断被创建和移除。
三个生成器产生三列数字。共用种子的那两个每次都给出相同结果,第三个不会。
六个操作以 Callable 的形式存在数组里,五个 lambda 加一个用 bind 的方法,每个都交给 Array.map 处理同一组数字。