├── .github └── workflows │ └── ic.yml ├── .gitignore ├── README.md ├── docs ├── index.md ├── resources │ └── images │ │ ├── bg.jpg │ │ ├── default_ide.jpg │ │ ├── launcher.png │ │ ├── platforms.jpg │ │ ├── renpy_extension.jpg │ │ └── vscode.jpg ├── 你好,Ren'Py。.md ├── 变量.md ├── 在开始之前.md ├── 对话.md └── 脚本标签.md └── mkdocs.yml /.github/workflows/ic.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - main 6 | permissions: 7 | contents: write 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-python@v4 14 | with: 15 | python-version: 3.x 16 | - run: pip install mkdocs-material 17 | - run: mkdocs gh-deploy --force 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /site 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ren'Py:从入门到入坟 2 | 3 | **[《Ren'Py:从入门到入坟》中文文档](https://zyksslm.github.io/RenPy-Tutorial)** 4 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | - [在开始之前](在开始之前.md) 4 | - [说明](在开始之前.md#说明) 5 | - [前言](在开始之前.md#前言) 6 | 7 | - [你好,Ren'Py。](你好,Ren'Py。.md) 8 | - [简介](你好,Ren'Py。.md#简介) 9 | - [Ren'Py能干什么](你好,Ren'Py。.md#renpy能干什么) 10 | - [Ren'Py支持的文件格式](你好,Ren'Py。.md#renpy支持的文件格式) 11 | - [竟然还不会配置开发环境吗?](你好,Ren'Py。.md#竟然还不会配置开发环境吗) 12 | - [安装SDK](你好,Ren'Py。.md#安装sdk) 13 | - [安装IDE](你好,Ren'Py。.md#安装ide) 14 | - [配置Ren'Py启动器](你好,Ren'Py。.md#配置renpy启动器) 15 | - [基本操作](你好,Ren'Py。.md#基本操作) 16 | - [学前准备](你好,Ren'Py。.md#学前准备) 17 | - [我不学Python了,Ren'Py!](你好,Ren'Py。.md#我不学python了renpy) 18 | - [Ren'Py项目结构](你好,Ren'Py。.md#renpy项目结构) 19 | - [rpy脚本文件](你好,Ren'Py。.md#rpy脚本文件) 20 | - [rpyc可执行程序](你好,Ren'Py。.md#rpyc可执行程序) 21 | - [关键字](你好,Ren'Py。.md#关键字) 22 | - [缩进](你好,Ren'Py。.md#缩进) 23 | - [注释](你好,Ren'Py。.md#注释) 24 | 25 | - [变量](变量.md) 26 | - [变量定义](变量.md#变量定义) 27 | - [define语句](变量.md#define语句) 28 | - [default语句](变量.md#default语句) 29 | - [单行Python语句](变量.md#单行python语句) 30 | - [多行Python语句](变量.md#多行python语句) 31 | - [init python语句](变量.md#init-python语句) 32 | - [存储区](变量.md#存储区) 33 | - [定义](变量.md#定义) 34 | - [常规定义](变量.md#常规定义) 35 | - [在python语句中定义](变量.md#在python语句中定义) 36 | - [使用](变量.md#使用) 37 | - [常规使用](变量.md#常规使用) 38 | - [在python语句中使用](变量.md#在python语句中使用) 39 | 40 | - [脚本标签](脚本标签.md) 41 | - [label语句](脚本标签.md#label语句) 42 | - [call语句](脚本标签.md#call语句) 43 | - [jump语句](脚本标签.md#jump语句) 44 | - [return语句](脚本标签.md#return语句) 45 | - [特殊标签名](脚本标签.md#特殊标签名) 46 | - [全局与局部脚本标签](脚本标签.md#全局与局部脚本标签) 47 | 48 | - [对话](对话.md) 49 | - [say语句](对话.md#say语句) 50 | - [角色对象](对话.md#角色对象) 51 | - [特殊文本样式](对话.md#特殊文本样式) 52 | - [转义符](对话.md#转义符) 53 | - [内插字符](对话.md#内插字符) 54 | - [文本标签](对话.md#文本标签) -------------------------------------------------------------------------------- /docs/resources/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/bg.jpg -------------------------------------------------------------------------------- /docs/resources/images/default_ide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/default_ide.jpg -------------------------------------------------------------------------------- /docs/resources/images/launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/launcher.png -------------------------------------------------------------------------------- /docs/resources/images/platforms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/platforms.jpg -------------------------------------------------------------------------------- /docs/resources/images/renpy_extension.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/renpy_extension.jpg -------------------------------------------------------------------------------- /docs/resources/images/vscode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZYKsslm/RenPy-Tutorial/1d9b872890b37bbcbd1fafb6333c5acc0b75981e/docs/resources/images/vscode.jpg -------------------------------------------------------------------------------- /docs/你好,Ren'Py。.md: -------------------------------------------------------------------------------- 1 | # 你好,Ren'Py。 2 | 3 | > 合抱之木,生于毫末;百丈之台,起于垒土;千里之行,始于足下。——《老子》 4 | 5 | ## 简介 6 | 7 | 可以说,Ren'Py天生就是为视觉小说类游戏而生的。 8 | 9 | Ren'Py视觉小说引擎是一款开源的自由软件引擎,用来创作通过电脑(也包含其他设备)叙述故事的视觉小说。Ren'Py之名是由 *Renai* 与 *Python* 两词混合而成。*Renai* 为日文罗马拼音,意指“恋爱”,而 *Python* 是Ren'Py所使用的语言环境。 10 | 11 | **而且Ren'Py使用超高自由度的MIT协议开源。** 12 | 13 | 这意味着你可以随意使用Ren'Py引擎,无需向任何人申请,但要承担可能带来的所有责任。 14 | 15 | ### Ren'Py能干什么 16 | 17 | Ren'Py几乎支持所有视觉小说所应该具有的功能,包括分支故事、存储和加载游戏、回退到之前故事的存储点、多样性的场景转换等。Ren'Py拥有类似电影剧本的语法,并且能够允许高级用户编写Python代码来增加新的功能。除此之外,游戏引擎内附的出版工具能够为脚本加密以及压缩游戏素材以防止盗版。 18 | 19 | 也就是说,我们不必再去从头开始搭建一个GUI游戏界面,或实现繁多的基础功能,而只需专注于游戏设计。 20 | 21 | 同时,Ren'Py具有跨平台性。跨平台意指只需写一次代码,程序就能在多个不同的环境(操作系统)中运行,这将大大节省我们的时间,提高开发效率。 22 | 23 | 基于Python的特性,目前Ren'Py支持的平台有: 24 | 25 | - `Windows` 26 | - `Linux` 27 | - *Mac OS X* 28 | - `Android` 29 | - *iOS* 30 | - *Web* 31 | - Raspberry Pi 32 | 33 | 对 ` ` 内的平台支持最为完善,*斜体* 其次。 34 | 35 | ![platforms](resources/images/platforms.jpg) 36 | 37 | ### Ren'Py支持的文件格式 38 | 39 | 一部游戏通常包括图片、音频、视频等元素。 40 | 41 | 我们可以在Ren'Py中加载这些资源文件,但是Ren'Py支持渲染的图像或播放的影片和音频的格式是有限制的,支持的文件格式具体如下(未经完全测试): 42 | 43 | ` ` 内的格式为常用推荐格式 44 | 45 | | 类别 | 格式 | 备注 | 46 | |:------------:|:------------------------:|:--------------------------:| 47 | | 图像 | `JPEG/JPG` | | 48 | | 图像 | `PNG` | | 49 | | 图像 | `WEBP` | | 50 | | 图像 | BMP | | 51 | | 图像 | GIF | 不支持动图 | 52 | | 音频 | OPUS | | 53 | | 音频 | `OGG` | | 54 | | 音频 | FLAC | | 55 | | 音频 | `WAV` | | 56 | | 音频 | `MP3` | | 57 | | 视频(容器) | `WEBM` | 支持VP9、VP8编解码器 | 58 | | 视频(容器) | `OGG` | 支持Theora编解码器 | 59 | | 视频(容器) | MKV | 支持多种编解码器 | 60 | | 视频(容器) | AVI | 支持多种编解码器 | 61 | | 视频(容器) | MPEG 4 part 2 | 包括Xvid和DivX | 62 | | 视频(容器) | MPEG 2 | 部分支持,取决于具体实现 | 63 | | 视频(容器) | MPEG 1 | 部分支持,取决于具体实现 | 64 | 65 | > - 图像文件推荐转换为 `WEBP` 格式(WEBP是一种高效的无损或有损图像格式,适合游戏资源) 66 | > - 视频文件推荐转换为 `WEBM` 格式(WEBM是Ren'Py支持的主要视频格式) 67 | 68 | ## 竟然还不会配置开发环境吗? 69 | 70 | 如果你已经配置好了开发环境,那么可以跳过这一章节。 71 | 72 | ### 安装SDK 73 | 74 | SDK即为 *Software Development Kit(软件开发工具包)*,用于给开发者提供开发工具,也就是Ren'Py的本体(其中包括一个Ren'Py Launcher)。安装完SDK我们就可以使用Ren'Py来运行我们编写的脚本代码。 75 | 76 | SDK可以在[Ren'Py官方网站](https://renpy.org/latest.html)下载最新版。 77 | 78 | ### 安装IDE 79 | 80 | IDE即为 *Integrated Development Environment(集成开发环境)*,是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。一款优秀的IDE可以让我们更高效地开发。 81 | 82 | 在支持Ren'Py开发的IDE中,我们选择微软的开源代码编辑器 `Visual Studio Code`,轻便、高效、舒适。 83 | 84 | 我们可以在[vscode官网](https://code.visualstudio.com/)中找到与自己操作系统对应的版本下载安装。 85 | 86 | ![vsocode](resources/images/vscode.jpg) 87 | 88 | 安装完成后,我们打开vscode,打开扩展商店搜索 `renpy` 并下载Ren'Py扩展插件 89 | 90 | ![renpy_extension](resources/images/renpy_extension.jpg) 91 | 92 | ### 配置Ren'Py启动器 93 | 94 | 打开Ren'Py启动器,进入设置,点击 `文本编辑器`,选择 `Visual Studio Code(操作系统)`,这样,刚才安装的vscode就成为了我们的默认文本编辑器了。 95 | 96 | ![default_ide](resources/images/default_ide.jpg) 97 | 98 | ### 基本操作 99 | 100 | 1. 点击 `创建新项目` 以创建一个新项目。 101 | 102 | 2. 点击 `启动项目` 以运行一个项目。 103 | 104 | 3. 点击 `打开项目` 以使用默认文本编辑器打开项目目录。 105 | 106 | 详细使用请参考官方文档。 107 | 108 | ![launcher](resources/images/launcher.png) 109 | 110 | ## 学前准备 111 | 112 | ### 我不学Python了,Ren'Py! 113 | 114 | 由于Ren'Py是基于Python的,所以有很多概念和语法都和Python相似甚至是一样。**你几乎可以在Ren'Py引擎中完全使用Python语句!** 115 | 116 | **因此我们强烈建议所有Ren'Py使用者都掌握Python基础**。 117 | 118 | 如果你已经熟练掌握Python,那么相信学习Ren'Py对你来说并不是什么难事,甚至只是相当于学习一个第三方库而已。所以,先熟悉Python将会使你的Ren'Py学习之路更加平坦。本教程会涉及一些Python内容。 119 | 120 | 如果你是零基础开发者,那么推荐你去一些视频网站(如 *Bilibili*)或是阅读相关书籍学习。 121 | 122 | 对于Python知识掌握的要求:掌握Python的基本数据类型、流程控制语句、常用的内建函数以及基本的面向对象编程思想。 123 | 124 | ### Ren'Py项目结构 125 | 126 | Ren'Py项目目录分为 *基础目录* 和 *游戏目录*。 127 | 128 | **基础目录**即为以创建项目时输入的项目名为名的目录,一般用于存放与游戏本体无关的文件如 *LICENSE* 和 *README* 等。 129 | 130 | **游戏目录**即为位于基础目录下的名为 *game* 的目录,用于存放游戏资源和脚本文件等。 131 | 132 | 一个标准的Ren'Py项目目录结构同时也是项目的初始目录结构应如下所示: 133 | 134 | - Project 135 | - log.txt 136 | - game 137 | - audio 138 | - ...... 139 | - fonts 140 | - ...... 141 | - gui 142 | - ...... 143 | - images 144 | - ...... 145 | - saves 146 | - navigation.json 147 | - persistent 148 | - tl 149 | - common.rpym 150 | - common.rpymc 151 | - ...... 152 | - gui.rpy 153 | - gui.rpyc 154 | - options.rpy 155 | - options.rpyc 156 | - screens.rpy 157 | - screens.rpyc 158 | - script.rpy 159 | - script.rpyc 160 | - SourceHanSansLite.ttf 161 | - ...... 162 | - ...... 163 | 164 | *Project* 即为你的项目目录也是基础目录,基础目录下的 *game* 目录即为你的游戏目录。 165 | 166 | - `log.txt` 文件为游戏日志,包含游戏版本,创建时间等信息。 167 | - `trackback.txt` 文件(若存在)为游戏报错信息。 168 | - `error.txt` 文件(若存在)为脚本报错信息(语法错误)。 169 | - `navigation.json` 文件为项目配置信息。 170 | - `persistent` 文件存储了游戏的持久化数据。 171 | - `.rpym` 文件为游戏翻译文件。 172 | - `.rpy` 文件为游戏脚本 173 | - `.rpyc` 和 `.rpymc` 文件为编译后的二进制文件,游戏真正运行于这些文件。 174 | 175 | 在游戏中我们使用 `config.gamedir` 和 `config.basedir` 来获取当前游戏的游戏目录和项目目录。 176 | 177 | ### rpy脚本文件 178 | 179 | 游戏目录中后缀名为 *rpy* 的文件就是Ren'Py的脚本文件,用于编写脚本代码。你可以直接在里面编写代码或是自己创建脚本文件。脚本文件可以有一个或多个。 180 | 181 | 一个rpy脚本文件的文件名应遵守如下命名规范: 182 | 183 | - 规范格式 184 | - 全小写并使用下划线,如:`this_is_an_example` 185 | - 使用驼峰命名法,如:`thisIsAnExample` 186 | 187 | - 具有意义 188 | 189 | - 开头不包含数字 190 | 191 | 另外,在游戏启动时,Ren'Py会读取游戏目录下(包括子目录)的所有脚本文件,它们都会被扫描并组合成整个游戏的脚本。 192 | 193 | 所以请注意: 194 | 195 | 1. 所有脚本文件中定义的变量都能够被“跨文件”访问。例如你在一个脚本文件中定义了全局变量 *var* ,那么在任意一个脚本文件中都能够访问该变量 *var*。 196 | 2. 所有脚本文件中的变量均不能重名。 197 | 198 | 因此,你既可以将所有代码都写进一个脚本文件中,也可以根据分类写成多个脚本文件,但要注意变量名不能冲突。 199 | 200 | ### rpyc可执行程序 201 | 202 | 后缀名为 *rpyc* 的文件是同名rpy脚本文件编译后的二进制可执行程序。 203 | 204 | 在我们每次编写完代码重启项目时,Ren'Py会自动生成或更新rpyc文件,再次运行时会直接运行rpyc文件而省去编译的过程(若脚本文件没有发生更改)。 205 | 206 | 所以在没有rpy文件而有rpyc文件的情况下,游戏依然能够运行其功能。但是除了发布版本之外不应删除rpy文件。 207 | 208 | **所以,当你更新了某个rpy脚本文件的文件名时,记得同时删除对应的rpyc文件,否则再次运行将造成脚本内容冲突(Ren'Py会根据新文件名生成新的rpyc文件)!** 209 | 210 | ### 关键字 211 | 212 | 关键字是一个英文单词,必须在游戏脚本中合法出现。这些关键字是保留字,不能用作变量名、标签名或任何其他标识符。 213 | 214 | Ren'Py中关键字的概念类似于Python中的关键字。 215 | 216 | 同时,Ren'Py中还有一些预留名同样不能作为变量名使用,否则将引发错误。 217 | 218 | 这是完整的预留名列表:[预留名](https://doc.renpy.cn/zh-CN/reserved.html#reserved-names) 219 | 220 | ### 缩进 221 | 222 | 如果你学过Python,那么你一定清楚地明白缩进的重要性。Ren'Py与Python一样,使用缩进来表示代码的逻辑。 223 | 224 | ~~这里就不再赘述了。~~ 225 | 226 | 才怪! 227 | 228 | 笔者见过太多人因缩进问题而导致逻辑不一、程序运行异常甚至报错的问题。缩进是Python语言的灵魂,直接关系到整个程序的运行,这就是缩进的重要性! 229 | 230 | 说到缩进,这里就不得不再提一下 *语句块 (block)* 了。简而言之,语句块通常由缩进来体现,**一个语句块就是一行或一组完整的代码**,且语句块可以嵌套。 231 | 232 | ```renpy 233 | "一个语句块" 234 | ``` 235 | 236 | ```renpy 237 | if True: 238 | "这是if语句块" 239 | "还是在if语句块中" 240 | ``` 241 | 242 | ```renpy 243 | image: 244 | block: 245 | "这是block语句块" 246 | "也在image语句块中" 247 | ``` 248 | 249 | ### 注释 250 | 251 | 对于程序员来说,写注释是一个重要的习惯。注释用于代码解释或功能提示等,且不会被执行。 252 | 253 | 好的注释能够让你的代码更加简洁易懂,让你的思路更加清晰,也可以让你日后或别人再看代码时不至于一头雾水。 254 | 255 | 和Python一样,在Ren'Py中我们以使用 `#` 放在一条语句的**开头**来表示一条注释。 256 | 257 | 注释可以放在任何位置,但不能插在一行代码的前面或中间,我们一般置于一行代码的上一行或末尾。 258 | 259 | 260 | ```renpy 261 | # 定义角色对象 262 | define s = Character("Sylvie") 263 | # init python: 264 | # s = Character("Sylvie") # Python等效语句 265 | 266 | label start: 267 | s "Hi, I'm Sylvie." # 希尔薇发言 268 | $ s("Hi, I'm Sylvie.") # Python等效语句 269 | $ renpy.say(s, "Hi, I'm Sylvie.") # Python等效语句 270 | 271 | return 272 | ``` 273 | 274 | 275 | 那么,在进行完所有的前置准备后,我们就要开始正式学习Ren'Py语法了。 276 | -------------------------------------------------------------------------------- /docs/变量.md: -------------------------------------------------------------------------------- 1 | # 变量 2 | 3 | ## 变量定义 4 | 5 | ### define语句 6 | 7 | define语句用于: 8 | 9 | 1. 在初始化阶段给一个**全局变量**赋值 10 | 2. 设定游戏配置项变量 11 | 12 | **用define语句定义的变量会被当作一个常量,在存档时不会被保存,不应被修改**。 13 | 14 | **define语句可以放在脚本文件的任何位置,但一般建议放在脚本文件的开头(顶级位置)。** 15 | 16 | ```renpy 17 | # 定义一个名为Sylvie的角色 18 | define s = Character("Sylvie") 19 | 20 | label start: 21 | s "Hello, world!" 22 | return 23 | ``` 24 | 25 | ### default语句 26 | 27 | default语句用于给一个在游戏初始化时未定义的**全局变量**赋值。 28 | 29 | **所有用default定义的变量在存档时都会被自动保存**。 30 | 31 | **default语句可以放在脚本文件的任何位置,但一般建议放在脚本文件的开头(顶级位置),界面变量除外。** 32 | 33 | ```renpy 34 | # 定义一个名为Sylvie的角色 35 | define s = Character("Sylvie") 36 | # 定义初始好感度为0 37 | default love = 0 38 | 39 | label start: 40 | s "Hello, world!" 41 | $ love += 10 # 好感度加10 42 | return 43 | ``` 44 | 45 | ### 单行Python语句 46 | 47 | 单行Python语句由一个 `$` 作为标志,后面可跟一条Python语句。 48 | 49 | 单行Python语句一般有三个作用: 50 | 51 | 1. 定义临时变量 52 | 2. 修改已经定义过的全局变量(如使用 `default` 语句定义的变量) 53 | 3. 调用函数或方法 54 | 55 | ```renpy 56 | default num = 0 57 | 58 | label start: 59 | $ a = 1 # 定义临时变量a,离开start标签就会被回收 60 | "num的初始值为[num]" 61 | $ num += 1 # 修改全局变量num,使其增加1 62 | "num的值为[num]" 63 | "a的值为[a]" 64 | return 65 | ``` 66 | 67 | ### 多行Python语句 68 | 69 | 多行Python语句与单行语句的作用一样,但是可包含一条或多条Python语句。 70 | 71 | ```renpy 72 | default num = 0 73 | 74 | label start: 75 | "num的初始值为[num]" 76 | python: 77 | a = 1 # 定义临时变量a,离开start标签就会被回收 78 | num += 1 # 修改全局变量num,使其增加1 79 | "num的值为[num]" 80 | "a的值为[a]" 81 | return 82 | ``` 83 | 84 | ### init python语句 85 | 86 | init python语句本质上是多行Python语句,但在初始化阶段运行。可以用于定义类和函数,或者初始化样式、配置变量、持久化数据。 87 | 88 | 与define语句类似,在init python语句中被赋值的变量不会用于存档、读档,且不接受回滚。因此,在初始化完成后,这些变量值(常量)就不该改动。 89 | 90 | ```renpy 91 | init python: 92 | # 定义一个名为Sylvie的角色 93 | s = Character("Sylvie") 94 | 95 | # 定义greet函数 96 | def greet(speaker, content="Ciallo~(∠・ω< )⌒★"): 97 | """让某位角色打招呼""" 98 | speaker(content) 99 | 100 | default num = 0 101 | 102 | label start: 103 | python: 104 | greet(s) # 让Sylvie打招呼 105 | s("num的初始值为[num]") 106 | a = 1 # 定义临时变量a,离开start标签就会被回收 107 | num += 1 # 修改全局变量num,使其增加1 108 | s("num的值为[num]") 109 | s("a的值为[a]") 110 | return 111 | ``` 112 | 113 | 在上面的代码中, 114 | 115 | ```renpy 116 | init python: 117 | s = Character("Sylvie") 118 | ``` 119 | 120 | 的作用等价于 121 | 122 | ```renpy 123 | define s = Character("Sylvie") 124 | ``` 125 | 126 | 但是不利于调试。所以定义常量建议使用define语句。 127 | 128 | init python语句支持设定运行优先级,可以在 `init` 和 `python` 之间可以放一个运行优先级数值。如果没有指定优先级,默认使用0。 129 | 130 | init python语句按照优先级数值从低到高的顺序运行。优先级相同的情况下,按照文件名的Unicode字符顺序。 131 | 132 | 为了避免与Ren'Py引擎产生冲突,最好选用 `[-999, 999]` 范围内的数作为优先级。原则上,负整数的优先级主要用在库和配置,普通的init python语句应该使用0或者正整数作为优先级。 133 | 134 | ```renpy 135 | init 1 python: 136 | a = 0 137 | 138 | init 2 python: 139 | a = 1 140 | 141 | label start: 142 | "a的值为[a]" 143 | return 144 | ``` 145 | 146 | * * * 147 | 148 | ## 存储区 149 | 150 | 在Ren'Py中,变量所处的命名空间称为存储区。**在同一存储区中,变量名不能重复,否则将产生冲突。** 默认的存储区为 `store`。 151 | 152 | ### 定义 153 | 154 | #### 常规定义 155 | 156 | 在定义变量时使用 `Namespace.var` 的方式可以在 `Namespace` 存储区下定义变量 `var`,若存储区不存在则创建一个,若位于默认存储区即 `store` 则省略。 157 | 158 | ```renpy 159 | # 变量默认定义于store存储区下 160 | define s = Character("Sylvie") 161 | # 在sylvie存储区中定义love变量 162 | default Sylvie.love = 0 163 | 164 | label start: 165 | "[s.name]的好感度为[Sylvie.love]" 166 | return 167 | ``` 168 | 169 | #### 在python语句中定义 170 | 171 | 使用 `in` 分句可在python语句中接入自定义的存储区 172 | 173 | ```renpy 174 | define s = Character("Sylvie") 175 | 176 | # 接入sylvie存储区 177 | init python in Sylvie: 178 | # 在sylvie存储区中定义love变量 179 | love = 0 180 | 181 | label start: 182 | "[s.name]的好感度为[Sylvie.love]" 183 | 184 | # 接入sylvie存储区 185 | python in Sylvie: 186 | love += 1 187 | 188 | "[s.name]的好感度为[Sylvie.love]" 189 | return 190 | ``` 191 | 192 | ### 使用 193 | 194 | #### 常规使用 195 | 196 | 使用 `namespace.var` 的方式可以访问位于 `namespace` 存储区下的变量 `var`,默认存储区即 `store` 则可省略。 197 | 198 | ```renpy 199 | # 变量默认定义于store存储区下 200 | define s = Character("Sylvie") 201 | default num = 0 202 | 203 | label start: 204 | # 下面两条语句等价 205 | s "Ciallo~(∠・ω< )⌒★" 206 | store.s "Ciallo~(∠・ω< )⌒★" 207 | 208 | # 下面两条语句等价 209 | s "[num]" 210 | s "[store.num]" 211 | 212 | return 213 | ``` 214 | 215 | #### 在python语句中使用 216 | 217 | 要在python语句中使用自定义的存储区但又不想接入该存储区(如需要同时使用多个不同的存储区)可以使用 `from import` 语句导入该存储区。 218 | 219 | ```renpy 220 | define s = Character("Sylvie") 221 | define a = Character("Alice") 222 | 223 | init python in Sylvie: 224 | # 在Sylvie存储区中定义love变量 225 | love = 0 226 | 227 | init python in Alice: 228 | # 在Alice存储区中定义love变量 229 | love = 0 230 | 231 | 232 | label start: 233 | "[s.name]的好感度为[Sylvie.love]" 234 | "[a.name]的好感度为[Alice.love]" 235 | 236 | # 默认接入存储区store 237 | python: 238 | from store import Sylvie # 导入sylvie存储区 239 | from store import Alice # 导入alice存储区 240 | 241 | Sylvie.love += 1 242 | Alice.love += 1 243 | 244 | "[s.name]的好感度为[Sylvie.love]" 245 | "[a.name]的好感度为[Alice.love]" 246 | return 247 | ``` 248 | 249 | 若只想单纯使用而不修改某个自定义存储区下的变量,也可以单独导入该变量。 250 | 251 | ```python 252 | # 导入alice存储区中的love变量 253 | from store.Alice import love 254 | ``` 255 | -------------------------------------------------------------------------------- /docs/在开始之前.md: -------------------------------------------------------------------------------- 1 | # 在开始之前 2 | 3 | ## 说明 4 | 5 | 作者:`ZYKsslm` 6 | 7 | E-mail:`3119964735@qq.com` 8 | 9 | 参考致谢: 10 | 11 | 1. [Ren'Py官方网站](https://renpy.org/) 12 | 2. [Ren'Py中文网](https://www.renpy.cn/) 13 | 3. [Ren'Py简体中文文档](https://www.renpy.cn/doc/) 14 | 4. [Ren'Py英文文档](https://renpy.org/doc/html/index.html) 15 | 5. [Ren'Py仓库](https://github.com/renpy/renpy) 16 | 17 | ## 前言 18 | 19 | 身为Python的忠坚用户兼开发者之一,Ren'Py于我而言毫无疑问是极具魅力的。在初识Ren'Py时,我就被其易于上手、跨平台性强等特点深深吸引,它无疑是我心目中最适合用以制作视觉小说或是Galgame的一个强大实用的开源游戏引擎。 20 | 21 | 同时我也是视觉小说一类游戏的忠实爱好者,很庆幸PyTom大佬能够开发出一个如此极具魅力的游戏引擎,这不仅让更多游戏开发者能够专注于游戏设计,也将促使更多优秀的作品问世。 22 | 23 | 但是,在学习并使用了Ren'Py一段时间以后,我就发现一个惨痛的事实——目前Ren'Py中文社区还并不完善,远远无法和其他游戏引擎相比。我相信各位都有这种经历:看不懂文档、出现问题后把文档或是论坛翻遍也没成功解决,最后疲于在茫茫网络中苦寻。我相信这对于绝大多数开发者来说可以是致命的。 24 | 25 | 所以,一个想法不由而生:制作一份更加详细、易懂、系统的教程来帮助更多初学者入门Ren'Py,最终能够自己独立完成一款视觉小说的程序部分,同时帮助更多Ren'Py开发者写出更加严谨、细致、高效的代码。这于我而言也是一个不小的挑战,在编写这份教程的同时,我也在与你们一起学习。 26 | 27 | 创作之路布满荆棘,错误在所难免。但是欢迎提出指正,定会裨补缺漏,为Ren'Py社区尽一份绵薄之力。同时也希望大家能够相互促进、共同学习,一起将Ren'Py社区建设得更加完善! 28 | 29 | ZYKsslm 30 | 31 | 2025/01/14 32 | -------------------------------------------------------------------------------- /docs/对话.md: -------------------------------------------------------------------------------- 1 | # 对话 2 | 3 | 文本剧情是视觉小说类游戏的根本,一切游戏形式都要建立在对话之上。Ren'Py为我们提供了简便快捷的say语句来方便演示对话。 4 | 5 | ## say语句 6 | 7 | `say` 语句一般有以下几种形式: 8 | 9 | 1. 一个单一字符串,表示显示的内容。一般用作旁白。 10 | 2. 由两个字符串组成,前面的字符串表示发言人的名字,后面的表示显示的内容。 11 | 3. 表示显示的内容的字符串用三引号引起,方便显示长段文本。 12 | 4. 由一个角色对象和一个字符串组成,角色对象控制发言展现的形式,字符串则是显示的内容。这种形式也是最为常用的。 13 | 14 | > 有些say语句会在原有基础上加上一个 `with` 从句,后跟上一个转场来实现一些演出效果。 15 | 16 | ```renpy 17 | label start: 18 | 19 | "我很紧张" 20 | 21 | "我" "我喜欢你!" 22 | 23 | "希尔薇" "这是真的吗?!" with vpunch 24 | 25 | return 26 | ``` 27 | 28 | > `vpunch` 是一个内置转场,可以达到让窗口抖动的效果。同时,Ren'Py还内置了很多如 *vpunch* 的转场,可以在[官方文档](https://www.renpy.cn/doc/transitions.html#pre-defined-transitions)中查看。 29 | 30 | ### 角色对象 31 | 32 | 我们一般使用 `Character` 函数构建一个角色对象。 33 | 34 | ```renpy 35 | define s = Character("Sylvie") 36 | ``` 37 | 38 | Character函数支持很多参数,常用的如下: 39 | 40 | - **name** 41 | - 角色的名字。如果该参数是一个字符串,则在对话中显示为角色名;如果为 `None`,则不显示名字,可用于旁白。 42 | 43 | - **kind** 44 | - 新建角色的基底角色类型。通常取值为 `adv` 或 `nvl`。 45 | - `adv`:文本显示在对话框中。 46 | - `nvl`:文本显示在屏幕中间。 47 | 48 | - **image** 49 | - 与角色关联的图像标签名,类型为字符串。 50 | 51 | - **who_color** 52 | - 角色名的颜色,通常为一个表示颜色的十六进制数的字符串。 53 | 54 | - **what_color** 55 | - 对话文本的颜色,通常为一个表示颜色的十六进制数的字符串。 56 | 57 | - **what_prefix** 58 | - 在显示对话内容之前添加的前缀字符串。 59 | 60 | - **what_suffix** 61 | - 在显示对话内容之后添加的后缀字符串。 62 | 63 | - **who_prefix** 64 | - 在显示角色名字之前添加的前缀字符串。 65 | 66 | - **who_suffix** 67 | - 在显示角色名字之后添加的后缀字符串。 68 | 69 | - **dynamic** 70 | - 如果为 `True`,则角色名 `name` 应是一个包含 Python 表达式的字符串。该表达式会在每行对话执行前进行计算,计算结果将作为角色名。 71 | 72 | - **condition** 73 | - 如果给定,该参数应是一个包含 Python 表达式的字符串。如果表达式结果为 `False`,则对话不会发生,即 `say` 语句不会执行。 74 | 75 | - **ctc** 76 | - 用于“点击继续”提示的可展现部件。如果使用了其他特殊提示,则可能不会显示。 77 | 78 | > 以 `who` 为前缀的参数表示人名的样式,以 `what` 为前缀的参数表示文本的样式。除了以上的样式参数,还支持更多样式,可查看[官方文档](https://doc.renpy.cn/zh-CN/style_properties.html#text-style-properties)。 79 | > 80 | > 使用 `who_style` 或 `what_style` 的格式(`style`为样式名)即可作为参数传入Character函数。 81 | 82 | ```renpy 83 | define s = Character( 84 | "Sylvie", 85 | who_color="#FFA500", 86 | what_color="#FFE4E1", 87 | what_prefix="『", 88 | what_suffix="』", 89 | ) 90 | 91 | label start: 92 | 93 | s "你好!" 94 | 95 | return 96 | ``` 97 | 98 | 下面是一个nvl角色样例 99 | 100 | ```renpy 101 | define s = Character( 102 | "Sylvie", 103 | kind=nvl 104 | ) 105 | 106 | label start: 107 | 108 | s """ 109 | 先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。 110 | 111 | 然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。 112 | 113 | 诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。 114 | """ 115 | 116 | nvl clear 117 | 118 | return 119 | ``` 120 | 121 | 由三引号引起来的文本,Ren'Py会根据内容中的空行自动分段。分段后的每一段内容,都会创建自身的say语句。 122 | 123 | ## 特殊文本样式 124 | 125 | 所有在Ren'Py中以字符串形式呈现的文本都可以使用特殊的样式,下面将介绍一些常用的特殊样式、使用方法以及注意事项。 126 | 127 | ### 转义符 128 | 129 | 如果你想在文本中呈现一些特殊字符需要转义来转义防止Ren'Py误解我们的意思。 130 | 131 | 在文本中,以下字符为转义以后的写法: 132 | 133 | - `\` -> `\\` 134 | - `'` -> `\'` 135 | - `"` -> `\"` 136 | - `%` -> `\%` 或 `%%` 137 | - `{` -> `{{` 138 | - `[` -> `[[` 139 | - `【` -> `【【` 140 | 141 | 如果你的字符串是以一对双引号表示的,那么如果你想在文本中显示双引号就需要使用转义符,如果你的字符串是以单引号表示,那么则反之。 142 | 143 | ```renpy 144 | label start: 145 | 146 | "\"你好。\"" 147 | '\'我是......\'' 148 | 149 | return 150 | ``` 151 | 152 | 同时,还能使用 `\n` 来表示换行: 153 | 154 | ```renpy 155 | label start: 156 | 157 | "1\n2\n3\n4" 158 | 159 | return 160 | ``` 161 | 162 | ### 内插字符 163 | 164 | Ren'Py支持在文本中插入一个表达式并计算表达式的值,我们叫做内插字符。在Python中也有类似的字符串格式化用法。 165 | 166 | 我们使用一对方括号来修饰我们的表达式。 167 | 168 | ```renpy 169 | define s = Character("Sylvie") 170 | default point = 1 171 | 172 | label start: 173 | s "我的名字是[s.name]" 174 | "当前好感度为[point]" 175 | 176 | return 177 | ``` 178 | 179 | 同时,内插字符还支持一些特殊转换标记。我们使用 `!` 来表示后面的字符为特殊转换标记。下面是一些比较常用的转换标记: 180 | 181 | - `!i` 表示在字符串中进行二次插值 182 | 183 | ```renpy 184 | define s = Character("Sylvie") 185 | default point = 1 186 | 187 | label start: 188 | $ introduction = "名字为[s.name],好感度为[point]" 189 | s "[introduction!i]" 190 | 191 | return 192 | ``` 193 | 194 | - `!u` 会强制把英文文本转换成大写。 195 | - `!l` 会强制把英文文本转换为小写。 196 | - `!c` 会强制把英文文本首字母转换为大写。 197 | 198 | 我们可以配合一起使用: 199 | 200 | ```renpy 201 | define s = Character("Sylvie") 202 | 203 | label start: 204 | 205 | $ content = "hello WORLD!" 206 | 207 | # 使用顺序不分先后 208 | s "[content!lc]" 209 | 210 | return 211 | ``` 212 | 213 | ### 文本标签 214 | 215 | 如果你使用过HTML,那么你一定对“标签”很熟悉!在Ren'Py中,我们采用文本标签来实现对文本的特殊效果。 216 | 217 | 文本标签由一对大括号和一个标签名以及相应参数组成,不同的标签名及参数有不同的效果。 218 | 219 | 所有文本标签都需要闭合,其中有些文本标签是自闭和的,而有些文本标签需要对应的闭合标签来闭合。标签闭合间的文本将会呈现特殊效果。一般来说,文本标签的格式为: 220 | 221 | ```renpy 222 | "{tag=arg}text{/tag}" 223 | ``` 224 | 225 | 其中 `tag` 为标签名,`arg` 为参数值,`{/tag}` 为闭合标签。 226 | 227 | 还有一些格式为: 228 | 229 | ```renpy 230 | "text{tag=arg}" 231 | ``` 232 | 233 | 让我们来看看有哪些常用的文本标签。 234 | 235 | #### `a` 236 | 237 | 没错,正如其名,锚点标签的作用就是“传送”,能够引导玩家进入不同的地方。它拥有多个参数,下面来一一介绍: 238 | 239 | - jump 240 | 241 | 当入参为 `jump` 时,会进入其冒号后指定的脚本标签。 242 | 243 | ```renpy 244 | label start: 245 | "点{a=jump:dianwo}我{/a}进入" 246 | return 247 | 248 | label dianwo: 249 | "已进入" 250 | return 251 | ``` 252 | - call 253 | 254 | 当入参为 `call` 时,会调用其冒号后指定的脚本标签。 255 | 256 | 257 | ```renpy 258 | label start: 259 | "点{a=call:dianwo}我{/a}进入" 260 | "出来了" 261 | return 262 | 263 | label dianwo: 264 | "已进入" 265 | return 266 | ``` 267 | 268 | - show 269 | 270 | 当入参为 `show` 时,会显示其冒号后指定的界面,这里涉及到一个新的概念“界面”,我们不展开讨论。 271 | 272 | - URL 273 | 274 | 当入参部分是一个URL(或者说网站链接)时,会自动启动浏览器打开链接。 275 | 276 | ```renpy 277 | label start: 278 | "{a=https://www.bilibili.com/video/BV1uT4y1P7CX/}点我涩涩{/a}" 279 | return 280 | ``` 281 | 282 | #### alpha 283 | 284 | alpha文本标签指定一个透明度,渲染范围为自身及其闭合标签内的文本。透明度是一个介于0.0和1.0之间的数值,分别对应完全透明和完全不透明。 285 | 286 | ```renpy 287 | label start: 288 | 289 | "{alpha=0.8}总觉得......{/alpha}" 290 | "{alpha=0.5}要消失了呢......{/alpha}" 291 | "{alpha=0.3}......{/alpha}" 292 | 293 | return 294 | ``` 295 | 296 | #### b 297 | 298 | 粗体标签,将自身及其闭合标签内的文本渲染为粗体。 299 | 300 | #### i 301 | 302 | 斜体标签将自身及其闭合标签之间的文本渲染为斜体。 303 | 304 | #### s 305 | 306 | 删除线标签在其自身及其闭合标签之间的文本上画一条删除线。 307 | 308 | #### u 309 | 310 | 下划线标签在其自身及其闭合标签之间的文本添加下划线。 311 | 312 | #### color 313 | 314 | 颜色文本标签将自身及其闭合标签内的文本渲染为特定的颜色值。颜色值使用 `#rgb` `#rgba` `#rrggbb` `#rrggbbaa` 格式之一。 315 | 316 | #### cps 317 | 318 | cps标签用于指定其闭合标签内的文本每秒钟显示的字符数,若带 `*`,则表示当前速度的倍数。 319 | 320 | ```renpy 321 | label start: 322 | "{cps=30}时间要开始加速了!{/cps}" 323 | return 324 | ``` 325 | 326 | #### font 327 | 328 | 字体标签将标签自身及其闭合区间之间的文本渲染为指定的字体。入参即使用的字体文件名或路径。 329 | 330 | #### image 331 | 332 | 图片标签会在文本中内插一个图像。(可以用于插入表情包) 333 | 334 | #### size 335 | 336 | 字号标签改变了其自己及其闭合标签内的文本字号。若参数为整数则表示文本大小,若为一个 `*` 加一个浮点数的形式则表示为当前文本大小的倍数大小。 337 | 338 | #### fast 339 | 340 | fast标签只能用于对话中(即say语句),改标签为自闭和标签,在该标签前面的文本内容会立即显示。 341 | 342 | ```renpy 343 | label start: 344 | "你说" 345 | "什么?!{fast}" 346 | return 347 | ``` 348 | 349 | #### nw 350 | 351 | nw标签同样只能用于对话中(即say语句),是一个自闭合标签,该标签前的那行文本内容在显示一次后会立刻消失,显示下一句话。 352 | 353 | ```renpy 354 | label start: 355 | "什么东西?{nw}" 356 | "?可恶" 357 | return 358 | ``` 359 | 360 | 若指定参数,则表示等待对应的秒数后再执行文本消失。 361 | 362 | ```renpy 363 | label start: 364 | "你好?{nw=2}" 365 | "怎么不说话呢?" 366 | return 367 | ``` -------------------------------------------------------------------------------- /docs/脚本标签.md: -------------------------------------------------------------------------------- 1 | # 脚本标签 2 | 3 | Ren'Py中所有的游戏流程代码都会分别写进数个脚本标签中。脚本标签类似于Python中的函数,用于跳转或调用。 4 | 5 | ## label语句 6 | 7 | 我们使用 `label` 语句来定义一个脚本标签,然后是标签名,后面可紧跟一对小括号以添加参数,若没有参数则括号可以省略。参数的写法、作用域等与Python函数相似。 8 | 9 | ```renpy 10 | label sample_label(content): 11 | 12 | "[content]" 13 | 14 | return 15 | ``` 16 | 17 | ## call语句 18 | 19 | `call` 语句用于让主控流程进入某一脚本标签中,并在执行完这次调用后,回到原本调用的位置。 20 | 21 | call语句后面接一个标签名,表示让主控流程进入指定的脚本标签中。若指定的脚本标签要传入参数,则在标签名后紧跟一对小括号以传参。传参方式与Python函数传参方式完全相同。 22 | 23 | ```renpy 24 | label start: 25 | 26 | "游戏开始" 27 | 28 | call sample_label("HelloWorld!") 29 | 30 | "游戏结束" 31 | 32 | return 33 | 34 | 35 | label sample_label(content): 36 | "[content]" 37 | return 38 | ``` 39 | 40 | ## jump语句 41 | 42 | `jump` 语句用于让主控流程进入某一脚本标签中,并顺势执行下去。后面接一个标签名,表示让主控流程进入指定的脚本标签中 43 | 44 | **jump语句中指定的脚本标签不能传参。** 45 | 46 | 但你可以给指定的脚本标签添加默认值参数: 47 | 48 | ```renpy 49 | label start: 50 | "游戏开始" 51 | 52 | jump sample_label 53 | 54 | "游戏结束" 55 | 56 | return 57 | 58 | # 添加默认参数 59 | label sample_label(content="HelloWorld!"): 60 | "[content]" 61 | return 62 | ``` 63 | 64 | ## return语句 65 | 66 | `return` 语句标志着一段标签代码块的结束。后面还可接一个返回值,返回值储存在变量 `_return` 中。 67 | 68 | ```renpy 69 | label start: 70 | 71 | "游戏开始" 72 | 73 | call sample_label(8) 74 | 75 | "[_return]" 76 | 77 | return 78 | 79 | 80 | label sample_label(content): 81 | $ content += 1 82 | return content 83 | ``` 84 | 85 | 在上面的代码中,我们调用 `sample_label` 标签并传入参数整数8,随后 `content` 参数也就是整数8自增变成9,然后返回 `start` 标签并携带返回值 `content`,此时 `content` 的值储存在变量 `_return` 中,在对话框中输出 `_return` 的值显示为9。 86 | 87 | Ren'Py特性:在一个脚本标签结束后如果没有添加return语句,且下面还有其它脚本标签,则主控流程将直接进入下面的脚本标签,一直到遇到return语句才结束。若下面所有的脚本标签都没有添加return语句则会一直进入到最后一个脚本标签才结束。另外这也可能会造成奇怪的错误。 88 | 89 | 笔者习惯将其称之为 *标签穿透*。 90 | 91 | 任何脚本标签结束后都应添加return语句,不然将造成标签穿透。 92 | 93 | ~~Ren'Py脚本标签结束不加return语句就像java中switch case不加break。~~ 94 | 95 | ```renpy 96 | label start: 97 | 98 | "游戏开始" 99 | 100 | call label_1 101 | 102 | "游戏结束" 103 | 104 | return 105 | 106 | label label_1: 107 | "label 1" 108 | 109 | label label_2: 110 | "label 2" 111 | 112 | label label_3: 113 | "label 3" 114 | ``` 115 | 116 | **可见,任何在脚本标签结束后不添加return语句的行为都是危险的!除非利它来达到一些特殊的效果。** 117 | 118 | ## 特殊标签名 119 | 120 | 一些标签名有特殊的作用,如控制主控流程。常见的特殊标签名有以下这些: 121 | 122 | - start 123 | - 默认情况下,Ren'Py在游戏启动后会跳转至这个标签。 124 | 125 | - quit 126 | - 若该标签存在,当用户退出游戏时该标签内容会被调用。 127 | 128 | - after_load 129 | - 若该标签存在,当游戏读档后会调用这个标签内容。其可能被用于游戏内容更新后的数据修复。 130 | 131 | - splashscreen 132 | - 若该标签存在,游戏首次运行时,在主菜单出现前,该标签内容会被调用。 133 | 134 | - before_main_menu 135 | - 若该标签存在,在主菜单出现前,该标签内容会被调用。 136 | 137 | ## 全局与局部脚本标签 138 | 139 | Ren'Py中共有两种脚本标签:**全局脚本标签** 与 **局部脚本标签**。我们一般用的就是全局脚本标签。 140 | 141 | 全局脚本标签在所有脚本文件中通用,不能重名;而局部脚本标签则可以重名,但是需要关联一个全局脚本标签。 142 | 143 | 在定义局部脚本标签时,我们只需要在标签名前添加一个 `.` 即可,表示这是一个局部脚本标签而非全局脚本标签,它会与上面最近的一个全局脚本标签自动关联。 144 | 145 | 全局脚本标签与局部脚本标签有以下关系: 146 | 147 | 1. 一个局部脚本标签只能关联一个全局脚本标签,而一个全局脚本标签可以关联多个局部脚本标签。 148 | 2. 在一个全局脚本标签中可以直接访问与之关联的局部脚本标签,而想要访问其它全局脚本标签关联的局部脚本标签则需要使用 `global.local` 的形式来访问。 149 | 3. 在一个局部脚本标签中可以直接访问与之关联同一个全局脚本标签的另一局部脚本标签,而想要访问其它全局脚本标签关联的局部脚本标签依然需要使用 `global.local` 的形式来访问。 150 | 151 | 它们的关系类似于类与属性 ~~主仆~~ 的关系。 152 | 153 | 154 | ```renpy 155 | label start: 156 | 157 | "这是全局脚本标签start,游戏从这里开始" 158 | 159 | call .local_label 160 | call global_label.local_label 161 | 162 | return 163 | 164 | label .local_label: 165 | "这是局部脚本标签.local_label,关联start全局脚本标签" 166 | return 167 | 168 | label global_label: 169 | "这是全局脚本标签global_label" 170 | call .local_label 171 | return 172 | 173 | label .local_label: 174 | "这是局部脚本标签.local_label,关联global_label全局脚本标签" 175 | return 176 | ``` 177 | 178 | 在上面的代码中,有 `start` 和 `globel_label` 全局脚本标签,其分别关联了一个 `.local_label` 局部脚本标签。 179 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Ren'Py:从入门到入坟 2 | site_url: https://ZYKsslm.github.io/RenPy-Tutorial 3 | repo_url: https://github.com/ZYKsslm/RenPy-Tutorial 4 | 5 | theme: 6 | name: material 7 | language: zh 8 | 9 | icon: 10 | logo: material/book-open-page-variant 11 | repo: fontawesome/brands/github 12 | 13 | features: 14 | - content.code.copy 15 | - navigation.tracking 16 | 17 | palette: 18 | - media: "(prefers-color-scheme: light)" 19 | scheme: default 20 | primary: blue # 浅色模式主色调 21 | accent: purple # 浅色模式强调色 22 | toggle: 23 | icon: material/brightness-7 24 | name: 切换到深色模式 25 | 26 | - media: "(prefers-color-scheme: dark)" 27 | scheme: slate 28 | primary: indigo # 深色模式主色调 29 | accent: pink # 深色模式强调色 30 | toggle: 31 | icon: material/brightness-4 32 | name: 切换到浅色模式 33 | 34 | markdown_extensions: 35 | - pymdownx.tilde 36 | - toc: 37 | permalink: true 38 | slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}} 39 | 40 | nav: 41 | - 在开始之前: 在开始之前.md 42 | - 你好,Ren'Py。: 你好,Ren'Py。.md 43 | - 变量: 变量.md 44 | - 脚本标签: 脚本标签.md 45 | - 对话: 对话.md 46 | 47 | extra: 48 | social: 49 | - icon: fontawesome/brands/github 50 | link: https://github.com/ZYKsslm 51 | - icon: fontawesome/brands/bilibili 52 | link: https://space.bilibili.com/590816142 53 | 54 | extra_javascript: 55 | - https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js 56 | - https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-renpy.min.js 57 | - https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js 58 | 59 | extra_css: 60 | - https://cdn.jsdelivr.net/npm/prism-themes/themes/prism-one-dark.css 61 | --------------------------------------------------------------------------------