04 · 分支与导航
本章讲解如何用 menu 制造选择,用 navigate / jump / call 控制剧情走向。
label 标签
label 是剧情的锚点,用 navigate 跳转:
dsl
label forest:
say "你来到了森林。" speaker="旁白"
navigate "town"label vs scene
- scene——含 UI 元素的完整画面
- label——纯脚本片段,不含 UI 元素
navigate 两者都能跳。引擎会在所有 .story 文件中查找匹配的名字。
navigate 跳转
dsl
navigate "chapter1" // 跳到场景或标签
navigate "forest_battle" // 跳到另一个标签navigate 是最常用的跳转方式。跳转后,当前标签的后续代码不再执行。
menu 菜单选择
dsl
menu "你要怎么做?"
"战斗" -> wolf_battle
"逃跑" -> wolf_flee- 第一行是提示文字(可选)
- 每行一个选项:
"显示文字" -> 目标标签
玩家选择后,跳转到对应标签。
无提示文字的 menu
dsl
menu
"选项一" -> option1
"选项二" -> option2完整分支结构
dsl
label encounter:
say "一只野狼挡住了去路!" speaker="系统"
menu "你要怎么做?"
"战斗" -> wolf_battle
"逃跑" -> wolf_flee
label wolf_battle:
say "你拔出武器!" speaker="旁白"
if {player.hp > 20}
say "你战胜了野狼!" speaker="系统"
set "player.exp" {player.exp + 30}
else
say "你太弱了,被野狼击退。" speaker="系统"
set "player.hp" 1
navigate "town"
label wolf_flee:
say "你转身跑开了。" speaker="旁白"
navigate "town"jump 跳转
jump 与 navigate 类似,但不创建回溯检查点:
dsl
jump "shared_ending" // 跳转,但回溯时跳过这一步jump vs navigate
navigate——创建检查点,可回溯jump——不创建检查点,回溯时跳过
大多数情况用 navigate。jump 适用于跳转到共用代码段(如结局判定),不需要单独回溯。
call / return 子过程调用
call 调用子过程,return 返回调用点:
dsl
label main:
say "开始" speaker="旁白"
call "heal_full" // 调用子过程
say "回到主线" speaker="旁白" // return 后继续执行
navigate "next"
label heal_full:
set "player.hp" {player.maxHp}
say "HP 完全恢复!" speaker="系统"
return // 返回调用点适用于重复的逻辑片段(如恢复 HP、显示系统提示)。
scene 切换
跳转到 scene 会重建画面:
dsl
// 文件 A
label go_to_town:
navigate "town_entrance" // 跳到另一个 .story 文件中的 scene
// 文件 B
scene "town_entrance"
image "Images/town.jpg" x=0 y=0 width=100% height=100%
text "小镇入口" x=50% y=10% size=32
button "进入酒馆" x=50% y=50% nav="tavern"场景堆栈:back / forward
引擎维护一个场景堆栈,支持后退 / 前进:
dsl
// 从 town 调用 tavern,tavern 可以 back 回 town
scene "town"
button "进入酒馆" x=50% y=50% nav="tavern"
scene "tavern"
button "返回" x=50% y=80% nav="back" // 回到上一个场景| 命令 | 说明 |
|---|---|
back | 回到上一个场景 |
forward | 前进到下一个场景(back 之后用) |
back 的用途
适用于 UI 面板层级(如 设置 → 音频设置 → 返回设置)。剧情分支中通常用 navigate 显式跳转。
call_screen 调用 UI 场景
call_screen 调用一个 UI 场景并等待返回值:
dsl
label main:
call_screen "save_panel" store="save_result"
if {save_result == "saved"}
say "存档成功!" speaker="系统"
navigate "next"store="key"——将 UI 场景的返回值存入变量with "k=v"——传参(可选)
跨文件导航
引擎自动在所有 .story 文件中查找场景名和标签名。你可以把不同章节放在不同文件中:
Stories/
├── title/
│ └── title_main.story # scene "title_main"
├── chapter1/
│ └── chapter1.story # scene "chapter1_intro"
├── chapter2/
│ └── chapter2.story # scene "chapter2_start"dsl
// title_main.story
button "开始游戏" nav="chapter1_intro"
// chapter1.story
scene "chapter1_intro"
...
navigate "chapter2_start" // 跨文件跳转动手练习
制作一个三选一的分支:
dsl
label crossroad:
say "你站在岔路口。" speaker="旁白"
menu "走哪条路?"
"森林小径" -> path_forest
"山间道路" -> path_mountain
"河边小路" -> path_river
label path_forest:
say "你走进了幽暗的森林。" speaker="旁白"
call "gain_exp"
navigate "town"
label path_mountain:
say "你攀登陡峭的山路。" speaker="旁白"
call "gain_exp"
navigate "town"
label path_river:
say "你沿着河边前行。" speaker="旁白"
call "gain_exp"
navigate "town"
label gain_exp:
set "player.exp" {player.exp + 10}
say "获得 10 经验值!" speaker="系统"
return下一步
分支掌握了!下一章学习变量与表达式——让游戏记住玩家的选择。