列表是以特定顺序存储一些值的集合
列表是以某种顺序添加并存储信息的一种数据结构(类似一元数组)。这是一种十分灵活的数据结构,允许你在尾部或列表中间指定插入一个值,而且你还可以对列表内的值随机、升序或降序等多种方式进行排序。
当访问一个列表数据结构时,你应该使用整数值的索引值来获取其中的值,如果你提供的不是整数索引,则GameMaker Studio 2会自动向下取整(如10.5会变成10)。如果这种自动取整不是你想要的效果,请务必检查你传递的索引参数以避免这种情况发生。
注意:跟所有动态资源相同,数据结构会占用设备内存,因此在不再使用时应当将其销毁以释放内存,否则可能会造成内存泄漏,从而影响游戏运行速度和效率,最后导致游戏报错奔溃。
在使用列表时有以下一些方法可以使用:
ds_list_create——创建
语法:
ds_list_create();
返回:
Real
描述:
这个方法将新建一个列表数据结构,并返回这个列表的索引值,这个索引值应当存储到变量中,以便与其它函数来调用这个列表。
示例:
list = ds_list_create();
这行代码会创建一个新的列表,并将这个列表的索引值赋予名为“list”的变量。
ds_list_destroy——销毁
语法:
ds_list_destroy(id);
参数 | 描述 |
---|---|
id | 需要销毁的数据结构的索引值 |
返回:
N/A
描述:
这个方法用于从内存中清理所指定的列表数据结构,释放其占用的资源并删除其包含的所有值。这个方法可以防止内存泄漏,避免游戏运行速度减慢甚至奔溃,应当注意尽量使用该方法确保游戏性能。
示例:
if lives = 0
{
ds_list_destroy(AI_list) ;
room_goto(rm_Menu) ;
}
以上代码首先判断了内置的全局变量“lives”是否等于0,一旦条件达成则销毁“AI_list”所对应的列表数据内容并切换游戏场景(指定跳转去到rm_Menu)。
ds_list_clear——清除
语法:
ds_list_clear(id);
参数 | 描述 |
---|---|
id | 需要清除的数据结构的索引值 |
返回:
N/A
描述:
这个方法用于清除指定列表中的所有数据,这个方法并不会销毁该列表(你需要使用ds_list_destroy()方法来进行销毁操作)而仅仅是清除列表中的所有数据然后返回一个空的列表
示例:
if count = 15 && !ds_list_empty(command_list)
{
ds_list_clear(command_list);
alarm[0] = room_speed;
ai_count = 0;
}
以上代码首先判断了count这个值是不是等于15同时判断了command_list是否有内容,如果两个条件同时满足就会执行清除command_list列表中所有的内容的操作,同时会设置一个倒计时并把ai_count的值设为0。
ds_list_empty——判断是否为空
语法:
ds_list_empty(id);
参数 | 描述 |
---|---|
id | 需要判断是否为空的列表数据结构的索引值 |
返回:
Boolean
描述:
这个方法用于检验给出的列表是否是个空列表,是则返回true,否则返回false
示例:
if count == 15 && !ds_list_empty(command_list)
{
ds_list_clear(command_list);
alarm[0] = room_speed;
count = 0;
}
以上代码首先判断了count这个值是不是等于15同时判断了command_list是否有内容,如果两个条件同时满足就会执行清除command_list列表中所有的内容的操作,同时会设置一个倒计时并把ai_count的值设为0。
ds_list_size——获取列表内容数量
语法:
ds_list_size(id);
参数 | 描述 |
---|---|
id | 指定的列表数据结构索引值 |
返回:
Real
描述:
这个方法用于获取列表的长度,即列表中当前包含多少项内容的数量。
示例:
if !ds_list_empty(control_list)
{
num = ds_list_size(control_list);
}
以上代码首先判断了control_list这个列表是否为空,如果不是空列表则获取列表的项目数然后把值存储到变量num中。
ds_list_add——添加数据
语法:
ds_list_add(id, val1 [, val2, ... max_val]);
参数 | 描述 |
---|---|
id | 需要添加数据的列表索引值 |
val | 需要添加到列表中的值 |
[val2,...max_val] | 可选项,复数添加值时的其它待添加内容 |
返回:
N/A
描述:
这个方法用于给现有列表添加内容(字符串或实数),新添加的数据默认在列表尾部。这个方法还有可选参数(数量不限),可以用这个可选参数依次添加多个数据到列表中。
示例:
ds_list_add(sc_list, score);
以上代码向"sc_list"尾部添加了一个值,这个值是变量"score"中所存储的值。
ds_list_set——指定位置修改内容
语法:
ds_list_set(id, pos, val);
参数 | 描述 |
---|---|
id | 需要修改列表索引值 |
pos | 列表中需要修改内容的位置 |
val | 最终修改的内容值 |
返回:
N/A
描述:
这个方法可以修改列表中指定的位置的内容,你需要提供列表的ID(创建列表时会返回这个ID)以及需要修改的内容位置,你要求修改的内容就会直接覆盖该位置的原来内容。要注意如果你给的位置超出了列表自身的范围(比如,你要求插入到第20位,而列表本身只有10项内容),则列表会自动用“0”来填充前面的内容项直至列表满足你所给出的坐标位置。
示例:
for (var i = 0; i < ds_list_size(list); i++;)
{
ds_list_set(list, i, -1);
}
以上代码会依次把"list"这个列表中所有的内容都修改为"-1"这个值(官方文档此处的描述和示例代码不符啊混蛋,上面的参数部分也写错了,写这一页文档的同学也太马虎了)
ds_list_delete——删除内容
语法:
ds_list_delete(id, pos);
参数 | 描述 |
---|---|
id | 需要删除内容的列表索引值 |
pos | 需要被删除内容的列表坐标位置 |
返回:
N/A
描述:
这个方法用于删除列表中指定位置的数据内容。
示例:
if ds_list_size(sc_list)>10
{
while (ds_list_size(sc_list) > 10)
{
ds_list_delete(sc_list, 0);
}
}
以上代码首先判断"sc_list"这个列表的内容项是否超过10个,如果是则依次删除位置0(即列表中头部第一个数据)的内容,直至列表中只剩下10项内容为止。
ds_list_find_index——获取内容坐标位置
语法:
ds_list_find_index(id, val);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
val | 需要寻找位置的内容值 |
返回:
Real
描述:
你可以给这个方法传递一个具体的内容值,如果这个内容在你给出的列表中,则这个方法会把这个内容在列表中的位置返回给你。要注意,如果列表中有不止一个值与你给出的内容相同,则会随机给你其中一个的位置,如果你给出的内容不存在则会返回"-1",要注意这个值也可以是数组,你可以用"is_array"方法来判断这个值是不是数组。
示例:
pos = ds_list_find_index(list, "Player1");
以上代码在"list"这个列表中寻找是否有一个叫"Player1"的值,如果有则把其所在的位置返回并存储到一个
叫"pos"的变量中。
ds_list_find_value——获取指定位置的值
语法:
ds_list_find_value(id, pos);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
pos | 需要获取内容的坐标位置值,列表的位置以0开始,因此最后一个位置坐标是 ds_list_size(id)-1,即列表长度减1 |
返回:
Real, String or Undefined
描述:
用这个方法你可以获取指定列表中指定位置的内容值。
注意:如果你要求的位置超出列表的长度范围(比如列表只有10项内容而你指定要第11位的内容),此时这个方法会返回(未定义)。你可以用"is_undefined()"这个方法来检验这个返回值。
示例:
val = ds_list_find_value(list, ds_list_size(list) - 1);
以上方法会去获取"list"列表中最末位置的内容然后将返回的内容存储到"val"这个变量中。
ds_list_insert——插入内容
语法:
ds_list_insert(id, pos, val);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
pos | 需要插入内容的坐标位置值,列表的位置以0开始,因此最后一个位置坐标是 ds_list_size(id)-1,即列表长度减1 |
val | 需要插入的内容 |
返回:
N/A
描述:
这个方法可以在列表中指定位置插入新的内容,如果该位置后面有其他内容,则其后所有内容的坐标值都会自动+1
示例:
ds_list_insert(list, 9, score);
以上代码会在"list"列表的第10位插入一个值,这个值是存储在变量"score"中的。(因为列表的开头坐标是0,因此坐标9是第10位)
ds_list_replace——替换列表中的值
语法:
ds_list_replace(id, pos, val);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
pos | 需要替换内容的坐标位置值,列表的位置以0开始,因此最后一个位置坐标是 ds_list_size(id)-1,即列表长度减1 |
val | 即将被替换的新内容 |
返回:
N/A
描述:
这个方法将会把列表中指定位置的内容替换位参数中提供的新内容
示例:
ds_list_replace(n_list, 3, name);
以上代码会将"n_list"列表中第三位的内容替换为变量"name"中存储的内容。
ds_list_shuffle——随机排序
语法:
ds_list_shuffle(id);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
返回:
N/A
描述:
这个方法将把指定的列表中的内容随机排序,这将完全打乱原先添加的顺序随机生成新的排序。
注意:为了让调试更方便,GameMaker Studio 2在调试模式下会采用完全相同的随机种子,因此在调试时每次运行游戏这个随机都会得到完全相同的结果。如果你想避免这种情况最好在游戏启动时调用用"randomize"方法来每次获得随机的随机种子,最终打包的游戏不会有这个问题每次游戏都会是完全随机的。
示例:
if restart
{
ds_list_shuffle(card_list);
}
以上代码首先判断了"restart"值是否为true,如果是则将"card_list"中的内容随机打乱重新排序。
ds_list_sort——升降序排序
语法:
ds_list_sort(id, ascend);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
ascend | 排序的类型——升序为true,降序为false |
返回:
N/A
描述:
使用这个方法可以按升序或降序来重排列表中所有的值,如果列表中包含字符串,则会按照26个英文字母顺序来以首字母重排。
示例:
if newgame
{
ds_list_sort(name_list, true);
}
以上代码首先判断变量"newgame"是否为true,如果是则将"name_list"按照升序重排。
ds_list_copy——复制列表
语法:
ds_list_copy( id, source );
参数 | 描述 |
---|---|
id | 复制后的列表索引值 |
source | 被复制的原列表索引值 |
返回:
N/A
描述:
这个方法会将一个列表中的内容完整复制到另一个列表中,两个列表必须提前创建好,如果复制后的列表原先有内容则会在复制前自动清空。复制完成后两个列表中的内容将完全一致。
示例:
if !ds_list_empty(main_list)
{
old_list = ds_list_create();
ds_list_copy(old_list, main_list);
ds_list_clear(main_list);
}
以上代码首先判断"main_list"列表是否不为空,如果不为空则新建一个"old_list"的列表,然后把"main_list"中的内容完整复制到"old_list"中,最后清空"main_list"。
ds_list_read——加载字符串
语法:
ds_list_read(id, str [, legacy]);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
str | 需要读取的字符串 |
legacy(可选) | 可以设置为true或false,也可以忽略不用该参数 |
返回:
N/A
描述:
使用这个方法你可以重新加载一个使用"ds_list_write"方法导出的字符串内容。这个方法在给游戏添加保存/读取功能时至关重要。要注意如果数据结构是用老版本的GameMaker生成的,你需要使用可选参数"legacy"来标记一下,因为这个版本中字符串的格式略有变动。
示例:
list = ds_list_create();
ini_open("save.ini");
var str = ini_read_string("Lists", "0", "");
if str != ""
{
ds_list_read(list, str);
}
ini_close();
以上代码首先创建了叫作"list"的列表,然后打开了一个叫"save.ini"的ini配置文件,并从中获取了一段字符串内容存储到了一个叫"str"的变量中,然后判断"str"变量是否为空,如果不为空则将其中的内容读取到刚刚新建的"list"列表中,最后关闭那个ini配置文件。
ds_list_write——导出字符串
语法:
ds_list_write(id);
参数 | 描述 |
---|---|
id | 需要处理的列表索引值 |
返回:
String
描述:
这个方法会返回一串字符串,这个字符串可以用"ds_list_read"方法存储到另一个数据结构中去。
注意:返回的字符串是无法直接阅读的字符串,而是数据结构内容转存的一种特殊格式。
示例:
var str;
ini_open("save.ini");
str =ds_list_write(list);
ini_write_string("Lists", "0", str);
ds_list_clear(list);
ini_close();
以上代码首先打开了一个叫作"save.ini"的ini配置文件,然后把"list"列表中的内容变为字符串转存进"str"变量,并把所有内容写入这个配置文件,最后清楚了"list"中的内容,并关闭保存了配置文件。
列表也能用于存储其它列表或映射表,但只能与json_encode方法联合使用。这需要你首先“标记(flag/mark)”出列表中的条目,以便与确保可以进行正确的编码来使用以下方法:
ds_list_mark_as_list——标记子列表
语法:
ds_list_mark_as_list(id, pos);
参数 | 描述 |
---|---|
id | 需要处理的父列表索引值 |
pos | 被标记为子列表的项的坐标位置值 |
返回:
N/A
描述:
这个方法会将一个已经存在的列表中的某个位置的内容“标记”为另一个列表。这个方法是为了配合JSON字符串编码而使用的(你可以用"json_encode"方法来编码)。
注意:一旦某个列表中的某个值被标记为列表或映射表,销毁这个列表时也会将其中的子列表和映射表一并销毁。
示例:
var j_list = ds_list_create();
var sub_list = ds_list_create();
ds_list_add(sub_list, health);
ds_list_add(sub_list, lives);
ds_list_add(sub_list, score);
ds_list_add(j_list, sub_list);
ds_list_mark_as_list(j_list, 0);
以上代码首先声明了两个列表"j_list"和"sub_list",然后给"sub_list"添加了"health"、"lives"、"score"三个项,然后把"sub_list"作为一个内容单独添加进了"j_list"中,最后把其所在的位置标记成了一个新的列表,这样在后面进行编码时就能正确处理了。
ds_list_mark_as_map——标记子映射表
语法:
ds_list_mark_as_map(id, pos);
参数 | 描述 |
---|---|
id | 需要标记为父列表的索引值 |
pos | 将被标记为子映射表的内容项的坐标位置 |
返回:
N/A
描述:
这个方法将把列表中给出的位置的内容标记为映射表,这个方法是为了配合JSON字符串编码而使用的(你可以用"json_encode"方法来编码)
注意:一旦某个列表中的某个值被标记为列表或映射表,销毁这个列表时也会将其中的子列表和映射表一并销毁。
示例:
var sub_map = ds_map_create();
ds_map_add(sub_map, "player", player_array);
ds_map_add(sub_map, "enemy", enemy_array);
ds_list_add(j_list, sub_map);
ds_list_mark_as_map(j_list, 0);
以上代码先创建了一个映射表"sub_map",然后在其中添加了两对内容"player"和"enemy",并在这两组内容中各自存入了一个数组,然后将这个映射表作为一个单独的内容项存进了"j_list"中,最后将这个内容项所在的位置标记成了一个子映射表,以便与后续进行编码操作。
除了这些特定功能以外,你还可以使用通配符(或叫访问器)来添加或修改列表中的内容,通配符语法类似一元数组中的方法:
list_index[| index]
注意:如果你想确认数据结构是否存在,你可以使用"ds_exists()"方法来判断。
暂无关于此日志的评论。