Итак, у меня есть массив существ из игры, каждое из которых представляет собой просто имя в виде строки. Я хочу перебрать каждый из них и создать для каждого таблицу, содержащую все характеристики существ, здоровье, урон и т. д. Но я не могу найти способ создания новых таблиц Lua, например, присвоения новой переменной таблице. не копирует его.
На самом деле я мало что пробовал, так как я новичок в программировании и не нашел в Интернете почти никакой информации, касающейся моей конкретной проблемы.
вы никогда не ищете что-то о своей «конкретной проблеме». вам нужно абстрагировать свою проблему, разбить ее на атомарные этапы, прежде чем приступать к каким-либо исследованиям. Вы не найдете в Интернете точных планов строительства дома своей мечты, но вы найдете всю информацию о кирпиче, гвоздях, бетоне и т. д.
На самом деле плохой выбор слов, я много чего искал в таблицах Lua, определяя объекты, таблицы внутри таблиц. И затем я спросил здесь о моей конкретной проблеме.
Допустим, ваш массив выглядит следующим образом (и имейте в виду, что массивы Lua представляют собой таблицы с числовыми индексами):
monsters = {[1] = "orc", [2] = "troll", [3] = "ogre"}
да, у вас возникнут проблемы, если вы попытаетесь создать один шаблон таблицы «статистика» и присвоить его каждому имени монстра в массиве:
stats = {["strength"] = 15, ["health"] = 10}
monster_stats = {} -- initialize new table for stats
for k,v in ipairs(monsters) do
monster_stats[v] = stats
end
monster_stats["orc"].strength = 10 -- change strength
print(monster_stats["orc"].strength)
print(monster_stats["troll"].strength)
выход:
10
10
Мы хотим изменить только силу орка, но в конечном итоге мы изменяем силу каждого. Это потому, что и monster_stats["orc"] и monster_stats["troll"] указать на ту же таблицу в памяти. Вам нужен способ клонировать таблицу — и пример есть на lua.org[0].
Добавьте эту функцию в начало вашего скрипта, и теперь вы сможете вызывать clone() во время присваивания. На этот раз все идет так, как задумано, потому что переменная «статистика» каждого монстра указывает на отдельную таблицу в памяти.
function clone (t) -- t is a table
local new_t = {} -- create a new table
local i, v = next(t, nil) -- i is an index of t, v = t[i]
while i do
new_t[i] = v
i, v = next(t, i) -- get next index
end
return new_t
end
monsters = {[1] = "orc", [2] = "troll", [3] = "ogre"}
stats = {["strength"] = 15, ["health"] = 10}
monster_stats = {} -- initialize new table for stats
for k,v in ipairs(monsters) do
monster_stats[v] = clone(stats)
end
monster_stats["orc"].strength = 10 -- change strength
print(monster_stats["orc"].strength)
print(monster_stats["troll"].strength)
выход:
10
15
Вы можете увидеть, что все таблицы теперь разделены, распечатав значения самих таблиц:
print(monster_stats["orc"])
print(monster_stats["troll"])
print(monster_stats["ogre"])
выход:
table: 0x55be070536b0
table: 0x55be07053bc0
table: 0x55be07053c80
Ссылки:
[0] https://www.lua.org/manual/2.4/node31.html
Хорошо, это почти именно то, что я искал, мой единственный вопрос: не будет ли функция клонирования работать только один раз? Потому что после второго клонирования он просто использует ту же таблицу, которую вы определили как «new_t»? Я имею в виду, что если наша исходная таблица статистики называется «monster_stats», а наш клон — «new_t», не будет ли второй клон просто второй таблицей? Прошу прощения, если это глупый вопрос. Все еще ломаю голову над таблицами Lua.
@Габриэль - нет такой вещи, как глупый вопрос (en.wikipedia.org/wiki/No_ such_thing_as_a_stupid_question). Ответ — нет, функция клонирования продолжает создавать новые таблицы при каждом вызове благодаря ключевому слову «local». Я отредактировал свой ответ, чтобы продемонстрировать.
ваша функция клонирования не «клонирует» таблицу. он полностью игнорирует возможную метатаблицу.
Спасибо! Это проясняет то, что меня интересовало, спасибо за объяснение!
Вам следует уточнить, что вы подразумеваете под словами «Но я не могу найти способ создавать новые таблицы Lua, поскольку присвоение новой переменной таблице не копирует ее.», желательно с минимальным воспроизводимым примером (т. е. , некоторый код) для резервного копирования.