Developer:SMBX/Script/Basic/1

如果想阅览 SMBX 基础脚本教程的全部内容，请访问：SMBX 基础脚本合集

### TeaScript 简介

SMBX 38A 的作者 5438A38A 往编辑器里内置了强大的脚本功能，它不仅可以做到对关卡的美化/更好的游玩体验，而且还支持自定义HUD的出现，更是让 SMBX 38A 成为别的类同人游戏更是一座可能。它还有另外一个名字：TeaScript (中文叫茶脚本)。

Scintilla 为脚本系统提供了出色的编辑界面，因此如果 SciLexer.dll 丢失了，你也就没办法在关卡编辑器内编写脚本了，不过，如果真的出现了这样的状况，已经编写好且不存在错误的脚本仍可正常执行。

脚本系统可以让你操作游戏内几乎所有的变量和对象。你可以制作很高级的NPC、方块甚至是角色状态。

### 运行方式及特殊参数

一般来说，有以下运行方式可以运行脚本：

1. NPC参数里含有对应脚本名。
2. 由事件、流体或NPC事件赋予脚本名。

一些事件会传递给脚本特殊参数值，如下：Template:TeaScriptParamList

SMBX提供了3个系统内置特殊参数可供使用。

## 变量&赋值表达式

变量源于数学，是编程中最重要的组成，它可以用来存储运算结果，通常需要用变量名来访问他们。

为了方便梳理，我们分为两个变量种类：赋值变量和控制变量。

### 赋值变量

赋值变量是被定义出来的变量，他跟控制变量不同的是，这是真正意义上的变量类型。

赋值变量种类通常是：

```
Double Variable 双精度型变量
```

```
String Variable 字符串变量
```

某些系统功能使用了另一种变量类型 — Name。

Name 表示着某种东西的名字, 你不需要用引号来表示它的值。

变量名只能使用数字、字母以及它们的组合。变量名不区分大小写。变量名不能存在空格。

#### Double Variable 双精度浮点型变量

双精度浮点型变量是计算机使用的一种数据类型，使用 64 位（8字节） 来存储一个浮点数。 它可以表示十进制的15或16位有效数字，其可以表示的数字的绝对值范围大约是：-1.79E+308 ~ +1.79E+308。

一般情况下会定义成双精度浮点型变量。但事实上当你定义了一个局部/全局变量的同时,你也定义了一个同名的字符串型局部/全局变量。至于怎么用，我们稍后再谈。

#### String Variable 字符串变量

字符串变量是基于变量的另一种类型，一般由字符和数字组成。

例如：

```
str(Var1) = "Hello World!"
```

```
gstr(Var2) = "Hello World!"
```

### 控制变量

控制变量一般是指游戏里被控制的变量种类。

```
Local Variable 局部变量
Global Variable 全局变量
System Variable 系统变量
Dim Variable 内定义变量
Gamedata Variable 游戏数据变量

```

SMBX提供了好几种类控制变量。

其中，全局变量适用于大型地图需求非常多的变量，局部适用于自定义NPC以及其他操作（比如开关判断等等）。系统变量通常是游戏内置的特殊变量，部分无法修改，有的修改的话甚至会报错。游戏数据变量

#### Local Variable 局部变量

局部变量是关卡独有的变量，他只能作用到被定义的关卡，无法跨关卡使用。

你可以通过事件以及脚本来控制局部变量，值得注意的是，局部变量可以直接用于事件的Message(信息)中。

当然，可以定义成“String”字符串型。

它在脚本里的格式为：

```
val(Var1)
```

```
v(Var1)
```

#### Global Variable 全局变量

全局变量是影响整个世界关卡的变量，可以从世界编辑器里定义，可以跨关卡使用。同样跟局部变量一样默认是双精度浮点型。

你只能用脚本来控制全局变量，但你依旧可以用事件来获取它们的值。

同样，也可以定义成“String”字符串型。

它在脚本里的格式为：

```
gval(Var1)
```

```
gv(Var1)
```

#### Dim Variable 内定义变量

内定义变量是SMBX 1.4.5加入的新语句，它的作用是在一个单独的脚本里单独定义变量，无法跨脚本/关卡使用！并且不适用于一直循环执行的NPC脚本和Block脚本

你可以使用

```
dim VariableName as type

```

来定义。Type可以是：

```
Integer 长整型变量
Double 双精度浮点型变量
String 字符串变量
此外，还有另外3个种类，可以用作不同用途。
Byte
Long
Single
```

例如:

```
dim var1 as integer
dim var2 as double
dim var3 as string

```

需要注意的是：

str() and gstr()类型的字符串无法给通过此方法定义的字符串赋值。如果你这么干了，你也就只能看到个错误提示而已。

就像这样：

```
dim b as string
str(a)="111"
b=str(a)
call showmsg(b)

```

结果如下:

```
Can not assign due to type mismatch.
```

#### System Variable 系统变量

系统变量是系统内部调用的变量，一般无法修改其名字，但有一些是只读变量。

例如：

```
1UP (sysval(player1health)) 或 (sysval(player2health))
Coin (sysval(coincount))
Score (sysval(score))
NPCCount (sysval(NCount))

```

等等。

#### Gamedata Variable 游戏数据变量

游戏数据变量是一组只能通过脚本访问的复变量。存储在NPC、方块以及玩家内的数据就属于此类型。

游戏数据分为好几种，但一般的格式如下：

```
Block (Block(ID).Param)
Background Object (BGO(ID).Param)
NPC (NPC(ID).Param)
Character (Char(ID).Param)
Warp (Warp(ID).Param)

```

等等。

游戏数据一般由脚本控制，但在游戏中，玩家或对应的物体做出来的动作都会影响游戏数据变量。

比如，玩家char(1) 的 X坐标向右移动了 50 个像素，那么变量数据对应如下：

```
char(1).x = char(1).x + 50

```

## 赋值表达式

赋值表达式是SMBX中组成的最重要的单元，它的作用是用来计算数值，变量，或者对一些条件进行判断等。

这里为了分清楚情况，分为了：Math Expression 数学表达式 和 Logical Expression 逻辑表达式。

### Math Expression 数学表达式

数学表达式是由数学符号和函数组成的，它们经过计算后会返回一个数字。

常见的基础数学表达式如下：Template:TeaScriptBasicMathExpression

常见的复杂数学表达式如下：Template:TeaScriptAdvancedMathExpression

在C及C++语言中，数学计算对于复杂函数需要调用（math.h）才能进行函数计算，但在TeaScript则可以一步到位。

### Shifting Expression 移位表达式

关于移位（<< 或 >>），在 TeaScript 照样适用（本人于 2021.9.13 亲自验证）

同样，逻辑运算符也可以进行计算，具体原理可以参考：https://www.w3cschool.cn/vb\_net/bitshift.html

移位的用途，可以使用一个 Byte 类型的Dim变量来控制某样事件或决定那些事件需要触发。

举个例子：8 << 1 = 16 (在计算机中会这样处理： 8(1000) << 1(0001) = 16(00010000))

25(00011001) >> 2 = 6(00000110)，其余的0会被忽略。

### Logical Expression 逻辑表达式

逻辑表达式是用来表示参数满足的条件，在大多数语言里，大多是以布尔变量 (Boolean Variable) 表示，但在SMBX，则使用0或1代替。（不可将变量设置为布尔类型，因为不存在该类型变量。）

它们会告诉你表达式是否为真(True)。 经过运算后，结果将得到0(表示假，即False)或1(表示真，即True)。

逻辑表达式符号有两种类型：比较运算符和逻辑运算符。比较运算符的优先级要高于逻辑运算符。

同样，逻辑运算符也可以计算一个变量和另一个变量的二进制的关系。

常见的比较运算符如下: Template:TeaScriptCompareExpression

常见的逻辑运算符如下：Template:TeaScriptLogicalExpression

其中，

非(not)：将真假值互换，正如上面所提到的当a为0时，not a(即非a)为1；

与(and)：a、b同真运算结果为真；

或(or)：a、b有真运算结果为真；

异或(Xor)：当两个表达式的值不同时(即一个为True，另一个为Fasle)，其结果为True；当两个表达式的值相同(都为True或都为False)时，结果为False。也就是“异"则“真”，“同”则“假”；

逻辑相等(Eqv)：与“异或"运算是一对互逆运算符，即当两个表达式的值相同(都为True或都为False) ，其结果为True；当两个表达式的值不同(一个为True，另一个为False)时，其结果为False。只要表达式中有一个为Null，则结果为Null；

蕴含(Imp)：result=expressionl Imp expression2 只有当第一个表达式expressionl为True，第二个表达式expreesion2为False时，结果才为False，其他情况下结果均为True。

例子：
```
dim a as byte
dim b as byte
dim c as long 'This is Result Parameters

a = 60 '60 = 0011 1100
b = 13 '13 = 0000 1101
c = a and b 'Result: 0000 1100 = 12
c = a or b 'Result: 0011 1101 = 61
c = a xor b 'Result: 0011 0001 = 49
c = not a 'Result: 1100 0011 = -60
c = not b 'Result: 1111 0010 = -13
c = a eqv b 'Result: 1100 1110 = -49
c = a imp b 'Result: 1100 1111 = -48

```
如果想阅览 SMBX 基础脚本的语句的内容，请访问：SMBX 基础脚本 2 语句