Lua 游戏开发,在每次迭代后似乎表格自行删除

我正在尝试做一个小的插件,让我知道在战斗期间施法的耗费时间百分比,

function()
local spell, _, _, _, _, endTime = UnitCastingInfo("player")
-- 从游戏本身获取信息,看我是否正在“施法”

localinCombat= UnitAffectingCombat("player")
-- 从游戏获取信息,判断战斗是否为真(1)或不为真(nil)

local casting = {}

local sum = 0
if inCombat == 1 then
    if spell then
        table.insert(casting, 1)
    else
        table.insert(casting, 0)
    end
else
    for k in pairs (casting) do
        casting [k] = nil
    end
end
for i=1, #casting, 1 do
    sum = sum + casting[i]

end
return( sum / #casting ) end

-- 创建一个列表,每一帧我都在施法并且处于战斗状态时添加 1,
-- 或者在我不在施法且不在战斗时添加 0。然后我将所有数字相加并除以输入次数来计算
-- 我有多少百分比时间是“施法”的。如果战斗条件为假,则删除列表。

出于某些原因,这些数字根本不相加,只有当两个条件都满足时才能看到“1”,或者如果战斗条件得到满足则为“0”。

肯定有一些更好的方法,但我还是相当新于 Lua 和编程。

点赞
用户4984564
用户4984564

你说你是新手 Lua ,所以我会尽可能详细地解释下面的问题,以及如何改进它,所以做好长时间阅读的准备。

我假设你的函数将在游戏的每一帧/步骤/时刻调用。由于你在函数开始时将 sum=0casting={} 设为下 ,这将在每次调用函数时都执行。这就是为什么你最终总是得到 0 或 1 的原因。

上值拯救!

Lua 有这个很好的东西叫做词法作用域。我不会详细说明,但基本思想是 : 如果一个变量在函数定义时是可访问的(在作用域内),那么该函数记住该变量,无论何时调用它。例如:

local foo
do
  local var = 10
  foo = function() return var end
end
print(bar) -- nil
print(foo()) -- 10

你也可以为变量分配新值,下次调用函数时它仍将拥有该新值。例如,这是一个简单的计数器函数:

local counter
do
  count = 0
  counter = function() count = count + 1; return count; end
end
print(counter()) -- 1
print(counter()) -- 2
-- etc.

将其应用于你的情况,需要持续从一个调用到下一个调用的值是什么?

  • 在战斗中花费的tick数
  • 花费的施法tick数

在函数外定义这两个值,并根据需要递增/读取/重置它们;它将在重复调用函数之间持续存在。

需要记住的一些事情:

  • 当玩家不再施法和/或处于战斗状态时,必须重置这些计数器,否则它们将在上次停止的地方继续。
  • casting 不需要是表。相对于整数,表速度较慢,即使您重用它们。如果您需要计数东西,则数字足够了。只需在不战斗时使 casting = 0,在战斗中将其增加 1 即可。
2018-08-17 08:37:00
用户10230087
用户10230087

感谢大家的反馈,经过你们的建议和一些研究,我的代码看起来像这样,而且运行得很好:

function()
local spell, _, _, _, startTime, endTime, _, _, _ = UnitCastingInfo("player")
local inCombat = UnitAffectingCombat("player")
local inLockdown = InCombatLockdown()
local _, duration, _, _ = GetSpellCooldown("Fireball")
casting = casting or  {}
local sum = 0
if inCombat == 1 or inLockdown == 1 then
    if spell or duration  ~= 0 then
        casting[#casting+1] = 1
    elseif spell == nil or duration == 0  then
        casting[#casting+1] = 0
    end
else
    local next = next
    local k = next(casting)
    while k ~= nil do
        casting[k] = nil
        k = next(casting, k)
    end
end
for i=1, #casting, 1 do
    sum = sum + casting[i]
end
return(("%.1f"):format( (sum / #casting)*100 ).. "%%") end

我注意到原始代码重置表的时候存在问题:

for k in pairs (casting) do
    casting [k] = nil

它似乎有一些零值还在那里,或者表的大小没有被“缩小”,我不知道。

也许整数比表更快,但老实说,即使表变得非常大(5分钟,60 fps,有18k个输入),我也没有看到任何性能问题,而且为了学习一门新语言,以我个人的看法,采用“困难”的方法更好。

问候

2018-08-18 10:20:34