LUA: избегать прохождения по ссылке
Я только начинаю изучать LUA, и у меня есть проблема, которую я не уверен, какой способ "правильно" решить. Когда я прохожу дефолд vmath.vector3
к моей функции это, кажется, передается по ссылке и, следовательно, изменяется.
Если я умножу это на что-нибудь, это решается, однако.
Есть ли другой, более правильный способ решить эту проблему? Я не хочу изменять исходный вектор, который я передаю в качестве аргумента.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
3 ответа
Так как ты возвращаешься x
а также y
в качестве двух значений вы можете реализовать обе ветви одинаково, не изменяя таблицы:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
Defold предоставляет ряд специальных структур данных, которые очень полезны при разработке игр:
- vector3 - vmath.vector3 (x, y, z), полезный для описания позиций или направления в трехмерной системе координат
- vector4 - vmath.vector4(x,y,z,w), используется для цвета, оттенка и т. д. (красный, зеленый, синий, альфа)
- quat - vmath.quat () кватернион, описывающий вращение
- matrix4 - vmath.matrix4() матрица значений 4x4. Полезно для просмотра и проекции матриц между прочим
Все вышеперечисленное используется игровым движком Defold, но такие же структуры данных вы найдете и в других игровых движках.
Приведенные выше структуры данных имеют одну общую черту: они относятся к типу Lua userdata
print(type(vmath.vector3())) -- "userdata"
Пользовательские данные всегда передаются по ссылке, поэтому вы видите поведение, которое вы описываете. Defold предоставляет способы сделать копии, хотя:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
У вас уже есть решение в вашем else
ветвь: вам придется создать копию ваших векторов, прежде чем применять к ним "модифицирующие" операции.
Что касается других опций, может быть возможно придумать способ использования прокси-таблиц, но это будет намного сложнее, чем просто создание копии.