学习空间/函数、条件与循环:把意图写清楚
强类型 GDScript / LESSON 10

函数、条件与循环:把意图写清楚

输入、返回值和副作用,比函数写得短更重要。

基础约 8 分钟阅读,实作另计7 节现在学
CONCEPT MAP先看一眼知识之间的联系
先看一眼知识之间的联系01输入状态02条件判断03提前返回04修改事实05返回结果
沿执行路径逐步推演,把打印反馈、状态变化与返回值分开记录。

01一件事对应一个清楚的动作

函数可以只计算结果,也可以改变状态。can_leave() 适合返回条件是否满足;leave_room() 才执行离开行为。把“问一个问题”和“改变世界”混在一起,容易导致 UI 只是刷新一下按钮,就误触发事件。函数名要让读者预测它会不会修改数据。

02条件为什么要完整

flow_practice.gd gdscript
extends Node

var input_locked: bool = false
var examined: bool = false

func can_interact() -> bool:
    return not input_locked

func try_examine() -> bool:
    if not can_interact():
        return false
    if examined:
        print("已经调查过;不重复推进")
        return true
    examined = true
    print("第一次调查")
    return true

func _ready() -> void:
    try_examine()
    try_examine()

第二次调用仍返回成功,但不会重复推进;这是一种练习语义,不是所有游戏都必须如此。你应能说明每条分支的返回值和状态变化。

03循环与提前退出

for 适合遍历有限列表,例如把所有目标 ID 打印出来。while 必须有明确结束条件;把“等待玩家按键”写成主线程里的无限 while,会堵住事件处理。需要跨帧等待时再学信号、计时器或 await,不要用忙等。

函数内片段.gd gdscript
var clue_ids: Array[String] = ["practice_a", "practice_b"]
for clue_id: String in clue_ids:
    print("检查:", clue_id)

04动手:更改一个规则

  1. 把 input_locked 设为 true,再预测两次调用会打印什么。
  2. 新增 reset_practice() -> void,只把 examined 恢复为 false。
  3. 调用一次 reset,再调查,确认它回到第一次路径。

05不启动游戏,也能沿着分支走一遍

阅读 try_examine 时,拿纸画三列:进入函数前的状态、走过的判断、退出后的状态。第一轮把输入锁打开,看看程序在哪里提前返回;第二轮解除输入锁并保持未调查,看看哪一行把状态改为已调查;第三轮保持已调查,再追一遍路径。不要跳过那些“看上去不重要”的 return,它决定了后面的代码有没有机会执行。

每一轮都写下返回值与输出文字,两者不是同一件事。函数打印了“无法操作”,不代表它自动返回 false;函数返回 true,也不代表画面已经替你显示成功。把这两项分开记录,就能发现一些没有报错的逻辑缺陷。遇到 AI 生成的多重条件时,先做这种桌面推演,再运行核对,比逐行猜意思更有效。

06把一个长动作拆成可以命名的阶段

设想“尝试离开练习区域”同时包含检查条件、更新状态、播放反馈和请求切换。先不要急着写一个巨大的函数,可以在纸上把它分成四个动作,并圈出哪些只是询问、哪些会改变世界。询问函数应尽量让人放心调用;修改函数则需要明确重复调用会发生什么。名字像 can_leave 却偷偷播放动画,会使界面刷新这种普通操作带来意外副作用。

拆分也不意味着每一行都创建一个新函数。判断一个边界是否值得拆开,可以问:这一段是否有清楚的职责名称?是否能独立说明输入、输出和失败?如果只能起名 step_one、step_two,而每段都需要知道全部内部变量,可能只是把长代码藏到了更多地方。初学练习先选择两三个真正有意义的阶段即可。

07用有限列表练循环,再谈等待玩家

准备三条中性的调查标识,例如 practice_a、practice_b、practice_c,用 for 依次输出。随后增加一个条件,只在匹配 practice_b 时输出“找到目标”,并解释是否需要继续遍历剩余元素。这样你能看清遍历次数、条件位置与提前退出之间的关系。再用空列表测试,确认程序不会因为没有内容就误报已经找到。

不要把“直到玩家按键才继续”写成不断检查的无限循环。玩家输入需要引擎继续处理帧与事件,而占住主线程的忙等会让程序没有机会接收你等待的操作。涉及跨帧等待时,应进入信号、计时器或 await 的学习范围。本课的完成证据可以是一张分支表:输入锁定、首次调查、重复调查、重置后调查各有什么输出和状态。四行都能解释清楚,比写出更长的循环更重要。

动手后,再勾选

不是“我看懂了”,而是你在独立练习里做出并检查过。

CHECK YOUR UNDERSTANDING

换一个情景,你会怎么判断?

can_leave() 最容易理解的职责是什么?

用自己的话,留一条笔记

可以写“我之前以为……,现在发现……”,或者记录还没解决的问题。

仅保存在此浏览器0 / 20000

回到资料核对

本课是解释与练习,不替代对应版本的官方手册。网页实验不运行 Godot;未标明实机验证的代码,仍需在独立工程中检查。

把这课收进你的理解里。

标记已读不会自动勾选实作,也不代表游戏功能已经完成。

输入一个你想弄明白的问题。

按 Esc 关闭 · 标题、关键词和正文一起搜索