GameMaker: Поиск ресурсов по имени

Порой может быть желаемым заполучить индекс ресурса по его имени,

instance_create(x, y, 'obj_item' + string(irandom_range(1, 3)));

Но, индексы ресурсов - не строки, так что это не сработало бы.

Можно добавить искомые ресурсы в массив, или же сделать небольшой switch блок, но это несколько больше работы.

Данная запись рассматривает возможные пути решения проблемы.

GameMaker ≤ 8.1

В старых версиях GameMaker многие люди искушались использовать execute_string:

execute_string('instance_create(x, y, obj_item' + string(irandom_range(1, 3)) + ');');
// [НЕ СТОИТ]

Но, это было довольно медленно, так как игра пересобирала кусок кода на каждом запуске.

Лучшим решением было использование ds_map - на запуске игры вы перебирали желаемые ресурсы и заполняли "словарь",

var i, n, m;
n = object_add(); // now holds max object index
object_delete(n);
m = ds_map_create();
for (i = 0; i < n; i += 1) {
    if (object_exists(i)) ds_map_add(m, object_get_name(i), i);
}
global.object_map = m;

потом добавляли скрипт (к примеру, object_find), что вытягивал оттуда значения,

/// object_find(name)
if (ds_map_exists(global.object_map, argument0)) {
    return ds_map_find_value(global.object_map, argument0);
} else return -1;

и потом это можно было использовать очевидным образом:

instance_create(x, y, object_find('obj_item' + string(irandom_range(1, 3))));

Так же есть пример с набором готовых скриптов такого рода:

Скачать GMK

GameMaker ≥ Studio

В GameMaker: Studio для таких задач была добавлена функция asset_get_index:

instance_create(x, y, asset_get_index('obj_item' + string(irandom_range(1, 3))));

Если поиск ресурсов производится очень часто, всё ещё можно построить словарь для них, но это делается чуть иначе, чем в старых версиях, так как индексы ресурсов теперь гарантированно идут "подряд" (0, 1, 2, ..) и больше нет функций для динамического добавления части из них,

var m = ds_map_create();
for (var i = 0; object_exists(i); i += 1) {
    m[?object_get_name(i)] = i;
}
global.object_map = m;

object_find тоже можно немного модернизировать:

/// object_find(name)
var q = global.object_map[?argument0];
if (q == undefined) return -1; else return q;

Похожие записи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.