Skip to content

素材和剧本

This content is not available in your language yet.

在本章节中,你将了解如何在项目中放置素材文件,以及如何编写剧本。

所有素材文件都应该放置在项目根目录下的 assets/ 文件夹中。引擎会自动识别并按需加载该文件夹内的所有资源。 除剧本目录外,assets/ 下并没有固定的目录结构,你可以自由创建子文件夹来组织素材,但建议按照以下结构来放置常见的素材类型:

  • Directoryassets/
    • Directorybg/ # 背景图片
      • classroom.png
      • street.png
    • Directorycharacters/ # 角色立绘
      • Directoryalice/
        • normal.png
        • smile.png
      • Directorykei/
        • normal.png
    • Directoryaudio/ # 音频文件
      • …
    • Directorybgm/ # 背景音乐
      • …
    • Directorysfx/ # 音效
      • …
    • Directoryvoice/ # 语音
      • …
    • Directoryui/ # 界面素材(文字框、按钮等)
      • …
    • Directoryfonts/ # 字体文件
      • …
    • Directoryscenario/ # 剧本文件
      • start.sixu

在剧本命令中,素材路径相对于 assets/ 文件夹:

::entry{
@bg src="bg/classroom.png"
@charEnter name="Alice" src="characters/alice/normal.png"
@bgm src="bgm/theme.opus"
}

同一张图片可以准备多个像素倍率的版本,用于适配高分屏。变体文件与基础图放在同一目录,文件名在扩展名前加上 @<倍率>x:

引用时只写基础图路径:

@bg src="bg/classroom.png"

倍率可以是任意正数,推荐提供 1.5 和 2 两档。变体文件与基础图的格式和扩展名应保持一致。建议保留基础图作为回退,变体可以只提供其中一档。引擎会按候选顺序尝试文件,直到找到可用的素材。

倍率表示图片像素尺寸与逻辑尺寸的关系。例如,button.png 是 316×86 像素,[email protected] 应导出为 632×172 像素,两者的逻辑显示尺寸都是 316×86。换用高清版本不会让按钮变大,也不需要修改坐标。

请从高清原稿导出不同倍率,并保持各版本的构图、透明留白和逻辑尺寸一致。把低清图片放大后命名为 @2x,不会增加原本没有的细节。选择设计尺寸的说明见设计尺寸与高清显示。

这项特性默认关闭,需要在 index.json 中开启:

{
"multiResAssets": "auto"
}

开启后,引擎按显示倍率从全局设置的 multiResAssetScales(默认 [1.5, 2])中逐档查找变体。只有出现在该列表里的倍率会被使用,需要其他倍率(例如 1.25 或 3)时要一并声明。

如果你希望减少导出和维护工作,可以只提供一套最高分辨率的素材。以保留 1920x1080 舞台、只导出 2× 图片为例:

  1. 从高清原稿导出 bg/[email protected],像素尺寸为 3840×2160;按钮等局部素材也按各自逻辑宽高的 2 倍导出。
  2. 剧本和 UI 中继续引用 bg/classroom.png 等不带倍率的逻辑路径,即使这个基础文件没有打包。
  3. 在 index.json 中优先指定使用 2× 素材:
index.json 中的相关配置
{
"stageSize": "1920x1080",
"multiResAssets": 2
}

这时引擎优先加载 [email protected],逻辑尺寸仍为 1920×1080。指定倍率的文件缺失时,会尝试基础图;两者都不可用时加载失败。数字模式不受 multiResAssetScales 和 multiResAssetPolicy 影响。

自动模式也可以加载仅有的 2× 素材,只要候选列表包含 2;固定为 2 可以避免尝试其他档位。multiResAssets 为 off 时,不带倍率的路径只会查找基础图。

高清素材会在小窗口中缩小显示,但仍需加载、解码并保存高清图片的全部像素。以单张 RGBA 图片的像素数据为例:

图片像素尺寸 像素数据大小
1920×1080 约 7.9 MiB
3840×2160 约 31.6 MiB

宽高各翻倍,像素数量和这部分占用就增加到 4 倍。实际内存与显存开销还受缓存、副本、mipmap 和转场等影响。WebP 或 PNG 文件压缩得很小,也不代表解码后的图片占用小。只提供高清素材适合能接受这些开销的项目;需要照顾低配置设备时,建议提供基础图和高清变体,并启用自动选择。

类型 推荐格式 说明
图片 WebP (.webp) 支持透明和动画,适合用于立绘和界面元素
图片 PNG / APNG (.png / .apng) 支持动画和透明,适合用于立绘和界面元素
图片 JPG / JPEG (.jpg / .jpeg) 体积小,不支持透明,可用于背景
图片 BMP (.bmp) 位图格式,体积很大,不推荐使用
音频 Opus (.opus / .ogg) 最新格式,同音质下体积最小,推荐首选
音频 Vorbis (.ogg) 当下广泛采用的格式
音频 FLAC (.flac) 无损压缩音频,适合高质量需求
音频 MP3 (.mp3) 体积较 opus 或 vorbis 略大,格式陈旧,不推荐
音频 PCM (.wav) 无压缩音频,文件较大,可用于音效
视频 封装:MP4 / MKV
编码:VP9 / AV1
(.mp4 / .mkv / .webm)
支持高效压缩和高质量视频播放
字体 TTF / OTF (.ttf / .otf) 常用字体格式
剧本 .sixu 末语引擎的剧本格式(思绪)

通常来说,我们推荐您使用 WebP 格式的图片和 Opus 格式的音频,以获得更好的性能和质量。对于视频素材,推荐使用 VP9 或 AV1 编码的 MP4/MKV/WebM 文件,以兼顾兼容性和压缩效率。

末语引擎使用 思绪(Sixu) 语言来编写剧本。剧本文件存放在 assets/scenario/ 目录下,扩展名为 .sixu。

如果你使用 VSCode 编写剧本,可以安装 思绪 VSCode 插件 来获得语法高亮和智能提示。

对于标准框架,你可以在这里查看完整命令列表。

剧本由一个或多个 段落(Paragraph) 组成,使用 ::段落名 声明,内容放在 { } 中。游戏从名为 entry 的段落开始执行:

::entry {
// 剧本内容写在这里
}
::chapter2 {
// 第二段落
}

对话文本是剧本最基本的元素,有以下两种写法:

// 无说话人的旁白
这是一段旁白文字,不会显示角色名称。
// 带说话人的对话
[Alice] "你好,这是 Alice 说的一句话。"
// 省略引号也是合法的
[Kei] 这也是一句对话,效果相同。

文本中支持 <...> 富文本标签:

[Alice] "这是<color=#E7931C>橙色文字</color>,这是<bold>加粗文字</bold>,这是<shadow color=#0008 offsetX=1 offsetY=2 blur=4>带阴影文字</shadow>。"

完整语法与可用状态见富文本。

以 @ 开头的行是命令,用于控制背景、角色、音频等:

// 切换背景,带渐变效果
@bg src="bg/classroom.png" fadeTime=500
// 设置背景色调
@bgTint tint="#ffcccc"
// 添加角色,使用预设位置
@charEnter name="Alice" src="characters/alice/normal.png" preset="left" fadeTime=500
// 添加角色,手动指定坐标和缩放
@charEnter name="Alice" src="characters/alice/normal.png" x=960 y=1080 scale=0.8 pivot=[0.5,1]
// 切换角色立绘或移动角色
@charAction name="Alice" src="characters/alice/smile.png" preset="right" fadeTime=300
// 移除角色
@charLeave name="Alice" fadeTime=300
// 清除所有角色
@charClear fadeTime=300
// 播放背景音乐(默认循环)
@bgm src="bgm/theme.opus" volume=0.8 fadeTime=1000
// 停止背景音乐
@bgmStop fadeTime=600
// 播放音效(不循环)
@sfx src="sfx/door.opus"
// 播放角色语音
@voice src="voice/alice_001.opus" name="Alice"
// 等待指定时间(毫秒),可跳过
@wait time=2000 skippable=true
// 等待玩家点击
@waitClick
// 跳转到其他剧本段落(如需要在 React 层处理结束)
@leaveStage gotoPage="title"

以 // 开头的行是注释,不会被执行:

// 这是一行注释
[Alice] "游戏开始了。"

以下是一个简单的剧本示例:

::entry {
// 显示背景
@bg src="bg/classroom.png" fadeTime=500
// 添加角色
@charEnter name="Alice" src="characters/alice/normal.png" preset="left" fadeTime=500
// 播放背景音乐
@bgm src="bgm/theme.opus"
// 旁白
"故事从这里开始……"
[Alice] "你好!我是Alice。"
// 切换立绘表情
@charAction name="Alice" src="characters/alice/smile.png" fadeTime=200
[Alice] "很高兴认识你!"
// 结束
@charClear fadeTime=500
@bgmStop
#replace(paragraph="entry")
}