# 表达式 在节奏医生编辑器中,为了增加灵活性与可玩性,很多地方都支持使用表达式在游戏运行时动态决定实际的效果。这种表达式被称作 **RDCode**。 ## 数据类型 类似于其他编程语言,RDCode 中有且仅有一些预定义的数据类型。 ### 常量 表示一个确定的值,其值在关卡制作时就已经确立。 ### 变量 表示一个不定的值,其值可能会在关卡运行过程中被赋值语句更改。 - **访问权限** 为了保证关卡运行的稳定,一些变量会设置访问权限: - **只读** 此变量可以参与表达式求值(读),但不能被赋值(写)。 - **只写** 此变量仅允许被赋值(写)而不能参与表达式求值(读)。 - **可读写** 此变量既能够参与表达式求值(读)也能够被赋值(写)。 - #### 整形(Integer/int) 即整数。 整形可以自动参与浮点型数据的数学运算。 你可以直接使用整形常量并参加运算,例如 `2026`, `-308`, `999`, `0`。 - #### 浮点型(Single/Float/float) 可以带有小数部分的数字。 例如 `3.1415`, `200.1`, `-9.99`。 > 在将浮点型转换为整型的操作(如赋值操作)时,将遵循**向最近偶数舍入**的原则(与大多数编程语言中的**向下取整**原则不同),即若计算结果为 `0.5`,那么它对应的整数值为 `0`;而 `1.5` 将对应 `2`。 - #### 布尔型(Boolean/bool) 仅 `true` 或 `false` 以表示启用或禁用等。 > 在**自定义方法**中, - #### 字符串型(String/string) 一串字符。 不参与运算,仅在调用自定义方法时作为参数存在。 值得注意的是,不同于其他语言的双引号 `"STRING"` 等表示方式,RDCode 的字符串表示是 `str:STRING`,即在字符串的前面加上一个 `str:` 前缀。 一般而言,在 RDCode 内用到字符串型的地方都只能在一系列候选词中选择一个填入,例如在选择角色或缓速类型时。 例如 `str:Samurai`, `str:Linear` - #### 预定义变量 节奏医生为整数、浮点数、布尔类型各预定义了 10 个可读写变量,分别以 `i`, `f`, `b` 开头,即 `i0`~`i9`, `f0`~`f9`, `b0`~`b9`。 一些只读或只写的变量可在[自定义方法表](../pages/appendix_custommethods.md)查到。 ## 运算类型 - **数学运算符** `+` `-` `*` `/` `%` - **逻辑运算符** `And` `Or` `Not` > 在 `And` `Or` 的两侧、`Not` 的右侧只支持布尔型数据。 - **比较运算符** `>` `<` `>=` `<=` `==` `<>` - **函数调用** 如 `Rand`, `IIf`, `atLeastRank` > 所有的可用的自定义方法请查阅[自定义方法表](../pages/appendix_custommethods.md)。 > 表内标注的方法按照每个参数的含义及其类型表示, > 例如 `SetMistakeWeight(int RowID, float Weight)` 中,注明了此方法需要一个 int 类型(即整形)的值表示 RowID 和一个 float 类型(即浮点型)的值表示 Weight, > 你可以这样使用:`SetMistakeWeight(0, 2)`,表示将轨道 1 的错误权重设为 2。 ## 语句类型 只能在自定义方法中使用。 - **自增/自减** 在变量后面添加 `++` 或 `--` 使变量本身加 1 或减 1。 > 布尔变量不支持自增/自减。 例如 `i2++`。 - **赋值** 在变量和表达式之间使用 `=` 将变量的值设为表达式的值。 例如 `f3 = 20 * f5`。 - **调用** 调用[自定义方法](../pages/appendix_custommethods.md)。 ## 表达式的用途 ### 条件 - 在使用[条件](../pages/condition.md)的自定义条件模式时,可以定义一个自定义条件,用于决定赋予此条件的事件能否在播放关卡时启用。 - 在条件的表达式限制下我们难以直接写出用 `And` 或 `Or` 组合的形式;但是我们可以通过设立多个自定义条件并分别添加对应的表达式,应用于事件上,或是执行多次自定义表达式并赋值给预定变量,再在条件内组合。 - 在**条件**内无法使用 `>=` `<=`。~~怀疑是史山代码发力了~~ - 在**条件**内若有 `>` `<` 存在时不允许有括号嵌套。~~史山代码还在发力~~ - 逻辑运算符的优先级比比较运算符更高。 ### 自定义方法 - 自定义方法中的表达式仅在赋值和调用行为时才能使用,其中赋值时以 `[变量]=[表达式]` 形式将对应的变量设为计算后的值,调用时将表达式填入对应的参数的位置。 例如 `b0 = b1 Or Not b2 And 3 > f2`。 - 自增或自减运算的左值仅能使用变量名,不能使用表达式。 - 在将布尔型数据转换为整形或浮点型的操作(如参与数学运算)时,其值将退化为整形,其中 `true` 对应 `1`,`false` 对应 `0`。 - 在将整形或浮点型数据转换为布尔型的操作(如赋值操作)时,其值将遵循**非 `0` 即 `true`** 的原则,即若计算结果为 `0`,那么它对应的布尔值为 `false`,否则为 `true`。 - 实际上在**自定义方法**内进行数学运算时,所有数据都将转换为浮点型再参与运算。 - 比较运算符的优先级比逻辑运算符更高。 - `Rand` 方法既不能包含表达式形式的参数,也不能参与计算。 ### 自定义方法(注释) - 注释型自定义方法的参数不支持表达式,仅支持单独的值或变量。 ### 事件参数 - 部分事件的属性支持填入表达式,如移动轨道、移动精灵图的位置、轴点、尺寸、角度等。 - 需要用花括号 `{}` 将表达式括起来以表示这是一个表达式。 - 其他同**自定义方法**。 ### 内插字符串 - 部分事件的字符串类型属性支持将表达式插入字符串,如浮动文字、显示状态牌等。 - 需要用花括号 `{}` 将表达式括起来以表示游戏需要将表达式的值替换表达式插入原字符串中。 - 其他同**自定义方法**。