零基础开发 era 游戏 #5 变量的声明 / 定义
唯二的变量类型:(整型)数值 / 字符串#
在 era basic
中只有两种变量类型:
- 数值:确切的说是「整型(整数类型)数值」。
是的,era 里面是不存在小数(浮点数)的。当然你可以自行实现。 - 字符串:就是字符串。
一般情况,若没有特别指定 S
后缀(
比如:
变量用途 | 数值类型 | 字符串类型 |
---|---|---|
通用返回值 | RESULT | RESULTS |
通用局部变量 | LOCAL | LOCALS |
通用形式参数 | ARG | ARGS |
…… |
当然,这是系统预设的内置变量的命名规范,你可以按自己的喜好来命名。
比如我就要定义变量 NUMS
为数值,CHAR
为字符串,谁能拦我?!谁也管不着你
数组变量#
Emuera 是支持数组的,当然也是分数值数组 / 字符串数组。
并且支持多维数组,不过最多到三维。
数组取指定下标的值使用英文半角冒号 :
,多维数组就继续套娃,如
ARRAY:(index_a):(index_b):(index_c) ; 最多三维 四维数组定义时就会报错 ARRAY:index_a:index_b:index_c ; 当下标不存在歧义时 括号可以省略 ARRAY:(idx + 1) ; 当下标需要先计算时 必须用括号包起来 ARRAY:idx + 1 ; 视为 (ARRAY:idx) + 1 ; 某种程度上可以认为 [: 运算符] 比 [其他运算符] 优先 ARRAY:0 ; 当下标为 0 时(取数组第一个值)可以直接省略 ARRAY == ARRAY:0 ; 实际上 RESULT / LOCAL / ARG 其实都是数组
系统内置变量#
LOCAL / LOCALS#
顾名思义,
@SYSTEM_TITLE LOCAL:10 = 123 ; SYSTEM_TITLE 函数里的 LOCAL:10 CALL TEST ; 调用 TEST ; 你改的是 TEST 里的 LOCAL:10 ; 跟我 SYSTEM_TITLE 里的 LOCAL:10 有什么关系? PRINTV LOCAL:10 ; 原样打印 123 QUIT @TEST LOCAL:10 = 999 ; 修改 TEST 函数里的 LOCAL:10 RETURN
由于和「函数」强相关,更多细节请到《函数》一章中了解。
ARG / ARGS#
顾名思义,
@SYSTEM_TITLE CALL TEST(11, 13, 777) PRINTV RESULT ; 打印 24(11 + 13) QUIT @TEST, ARG:0, ARG:1, ARG:1100 LOCAL = ARG:0 + ARG:1 RETURN LOCAL
本来
ARG
的大小默认只有 1000,但这里不会报错。
是因为使用了ARG:1100
,会自动将ARG
数组的大小扩张到 1101(0
~1100
)。
系统内置数组变量大小#
所有系统内置变量都可以用特殊的 csv 文件 VariableSize.csv
来设定变量大小。
编辑 ./csv/VariableSize.csv
,格式类似 变量名,变量数组大小
:
RESULT,100 COUNT,100 A,-1 B,-1 C,-1 D,-1 E,-1 F,-1 G,-1
- 一般来说,
VariableSize.csv
设置的数组大小最小为100
,再小会报警告。- 禁用某个变量必须将其设置为
-1
,而不是0
。
当值为 -1
时,即注销此变量。(想要使用需要自行定义该变量)
系统内置全局变量#
作用 | 配置项名 | 配置项类型 | 配置项变量名 |
---|---|---|---|
自定义标题栏 | ウィンドウタイトル | 字符串 | WINDOW_TITLE |
游戏制作者 | 作者 | 字符串 | GAMEBASE_AUTHOR |
游戏信息 | 追加情報 | 字符串 | GAMEBASE_INFO |
发布时间 | 製作年 | 字符串 | GAMEBASE_YEAR |
游戏名 | タイトル | 字符串 | GAMEBASE_TITLE |
游戏 ID | コード | 数值 | GAMEBASE_GAMECODE |
游戏版本号 | バージョン | 数值 | GAMEBASE_VERSION |
最低兼容版本 | バージョン違い認める | 数值 | GAMEBASE_ALLOWVERSION |
默认角色编号 | 最初からいるキャラ | 数值 | GAMEBASE_DEFAULTCHARA |
禁用物品系统 | アイテムなし | 数值 | GAMEBASE_NOITEM |
编辑 ./csv/GameBase.csv
,格式类似 配置项,配置值
:
;----------------------------------------------------------------
; 游戏基本信息 GameBase.csv
;----------------------------------------------------------------
; 自定义标题栏 [WINDOW_TITLE]
ウィンドウタイトル,游戏窗口标题栏显示的标题
; 游戏作者 [GAMEBASE_AUTHOR]
作者,作者名称
; 游戏 slogan [GAMEBASE_INFO]
追加情報,这是一条游戏相关信息
; 游戏发布时间,注意是字符串,即兼容类似「1886 ~ 至今」的格式 [GAMEBASE_YEAR]
製作年,1905 ~ 至今
; 游戏名 [GAMEBASE_TITLE]
タイトル,一个 era 游戏
; 游戏标识号码,相当于 era 的身份证,以保证别的 era 游戏的存档不能和你的混用 [GAMEBASE_GAMECODE]
コード,114514
; 游戏刚开始时就存在的角色编号 [GAMEBASE_DEFAULTCHARA]
最初からいるキャラ,1
; 游戏当前版本号,显示时会除以 1000(比如 0101 会变成 0.101) [GAMEBASE_VERSION]
バージョン,0001
; 游戏当前支持的最低版本,低于此版本的存档会拒绝读取 [GAMEBASE_ALLOWVERSION]
バージョン違い認める,0001
; 是否取消物品道具系统 [GAMEBASE_NOITEM]
アイテムなし,1
当 WINDOW_TITLE
为空时,自动由 GAMEBASE_TITLE
+ GAMEBASE_VERSION
组成。
此外,标题栏 WINDOW_TITLE
也是一个变量,也就是说你可以在游戏里动态改变标题。
@SYSTEM_TITLE WHILE 1 TWAIT 1000, 1 WINDOW_TITLE '= @"%GETTIMES()% 编程,很神奇吧?" WEND QUIT
另外还有两个有趣的系统内置常量(无法动态改变),分别是:
MONEYLABEL
:货币单位符号,默认为美元符号$
。DRAWLINESTR
:分隔线本体,DRAWLINE
其实就是把它打印出来。
(PRINTSL DRAWLINESTR
=DRAWLINE
)
说是无法改变,但启用
_Replace.csvを利用する:YES
设置项后可以事先在./csv/_replace.csv
文件编辑お金の単位
和DRAWLINE文字
两项来改变。
自行声明 / 定义一个变量#
一般来说,对于变量,声明 / 定义变量指的是同一件事:创建一个变量。
我们使用 #DIM
(定义数值)/ #DIMS
(定义字符串)关键字来实现。
参考上一节,#DIM
/ #DIMS
其实已经限定了变量的类型。
@TEST #DIM 一个数值变量 #DIMS 一个字符串变量 ; 你当然可以用中文作为变量名 但非常不推荐 ; 你可能会想: 很多 era 游戏本体就是大量使用日文变量名 这是事实 ; 但这是非常不好的习惯 这也是事实 不要学他们 #DIM num ; 没有设定初始值的数值 #DIMS word ; 没有设定初始值的字符串 #DIM a_num = 123 ; 设定初始值的数值 #DIMS words = "noot noot" ; 设定初始值的字符串 #DIMS many_words = "are", "you", "ok" ; 设定初始值的字符串数组
没有特别设定初始值的情况:
- 数值变量初始值为
0
- 字符串变量初始值为
""
(空字符串)
一般来说,不赋初始值,仅仅只是起个名,叫做「声明」。
赋初始值(准确地说是为其开辟内存空间)叫做「定义」。这个不考,稍作了解即可。
数值变量#
虽说只有整型数值,但也有很多不同写法。
@TEST #DIM num num = 32 ; 十进制 num = 0x20 ; 十六进制 hexadecimal num = 0b100000 ; 二进制 binary num = 1p5 ; 1 × 2 的 5 次方(即二进制的 1 后面 5 个 0) num = 1e5 ; 1 × 10 的 5 次方(即 1 后面 5 个 0)
上面四种表达方式都是「将 num
赋值为 32
」,最后一种是 100,000
。
定义数组变量#
@TEST ; 没有定义数组上限 自动取初始值的元素数量 #DIM three_num = 1, 2, 3 ; 定义的数组上限超过初始值的元素数量 没有指定初始值的其他项均为默认初始值 #DIM hundred_num, 100 = 4, 5, 6 ; hundred_num:99 == 0 ; 初始值元素数量超过定义的数组上限 ; 报错「初期値の数が配列のサイズを超えています」 #DIM error_num, 2 = 7, 8, 9 ; 字符串数组变量同理 #DIMS three_str = "A", "B", "C"
动态变量#
@SYSTEM_TITLE #DIM timer = 10 WHILE timer-- CALL TEST WEND QUIT @TEST #DIM DYNAMIC dynamic_cnt #DIM normal_cnt dynamic_cnt += 1 normal_cnt += 1 PRINTFORML dynamic={dynamic_cnt} normal={normal_cnt}
加上 DYNAMIC
关键字,每次调用时都会重新初始化一个该变量。
可以用来兼容循环 / 递归调用。
静态变量(常量)#
@TEST ; 没有定义数组上限 自动取初始值的元素数量 #DIM CONST const_array = 1, 2, 3 ; 初始值与定义的数组上限不符 ; 报错「定数の初期値の数が配列のサイズと一致しません」 #DIM CONST const_big_array, 100 = 4, 5, 6 ; 字符串数组变量同理 #DIMS CONST const_str_array = "A", "B", "C"
引用型变量#
@SYSTEM_TITLE #DIM num = 10 PRINTVL num ; 10 CALL TEST(num) ; 10 + 5 PRINTVL num ; 15 QUIT @TEST(argv) #DIM REF argv argv += 5
加上 REF
关键字之后,将传递的参数变为实参。
即直接将该变量所在内存地址的「引用」传递到调用的内部函数,在内部函数中处理时由于是直接处理的该值本身,无需返回,外部函数就能获得处理结果。
传递数组的引用
值得一提的是,由于 Emuera 所有的变量在语义上的本质都是「数组」——
因此,传递变量引用是可以将「整个数组」都传进函数内部的。(而且兼容数组下标)
不过无论传是哪个元素:array
(即 array:0
的简写)、array:1
、array:2
……其实都是将 array
的基址(或者说存储 array
的 容器,即 整个数组)传进函数。
@SYSTEM_TITLE #DIM array, 10 array = 10 array:1 = 20 array:2 = 30 CALL TEST(array:1) QUIT @TEST(list) #DIM REF list PRINTL 尽管你写的是传 array:1 PRINTL 其实传的还是 array 这一整个数组 PRINTFORML list={list} 其实是 list:0={list:0} PRINTFORML 其他元素也一起传进来了 list:1={list:1} list:2={list:2}
使用变量#
数值变量直接操作即可。
这里重点讲下字符串变量,字符串变量有两个赋值操作符:=
和 '=
。
@TEST #DIM CONST the_num = 123 #DIMS CONST the_str = "ABC" #DIMS temp = "第一个字符串变量", "第二个字符串变量" PRINTFORML temp:0=%temp:0% PRINTFORML temp:1=%temp:1% temp:0 = 右边的内容原封不动的赋值给左边 "包括引号和空格" {the_num} %the_str% temp:1 '= "右边的内容需要为一个完整的字符串 " + GETTIMES() + @" {the_num} %the_str%" PRINTFORML temp:0=%temp:0% PRINTFORML temp:1=%temp:1%
如果要类比的话:
=
类似(PRINT)FORM
'=
类似(PRINT)S