游戏Lua脚本-使用例程还是轮询?
我开始学习如何在logitech软件中为不同的游戏配置文件使用Lua脚本 首先,我尝试使用OneEvent(我知道它不是很高级),并创建了这个攻击组合脚本游戏Lua脚本-使用例程还是轮询?,lua,logitech,logitech-gaming-software,Lua,Logitech,Logitech Gaming Software,我开始学习如何在logitech软件中为不同的游戏配置文件使用Lua脚本 首先,我尝试使用OneEvent(我知道它不是很高级),并创建了这个攻击组合脚本 function OnEvent(event, arg) if event == "MOUSE_BUTTON_PRESSED" and arg == 1 then --set flag for mb1 mb1_pressed = true elseif event == "MOUSE_BUTTON_RELEA
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 1 then --set flag for mb1
mb1_pressed = true
elseif event == "MOUSE_BUTTON_RELEASED" and arg == 1 then --set flag for mb1=false
mb1_pressed = false
end
end
if mb1_pressed then --using flags to determine whether to start attack or not
repeat
presskey("A")
Sleep(50)
releasekey("A")
Sleep(100)
--if MB1 is release, it will also break script. if i only tap mb1, this will only execute the first line of attack without the rest below
if not (**argument**, can be MB1/ismouse1) then break end
presskey("S")
Sleep(50)
releasekey("")
Sleep(120)
presskey("A")
Sleep(50)
releasekey("A")
Sleep(200)
if not (**argument**, can be MB1/ismouse1) then break end --if MB1 is release, it will also break script. this point will prevent script from looping from start if mb1 release
until not (**argument**, i use ismouse1) --end the loop of script
end
所以我尝试将它绑定到我的logiech鼠标的G6按钮(使用鼠标按钮按下==6)
使用MB6设置标志有效,但MB6无法触发结束循环/中断循环
在对logitech support的SDK/Lua论坛进行了一些研究之后,我的脚本似乎有问题
对不起,我的问题太离谱了 我对罗技mice一无所知,所以我将尝试用一个简化的、纯Lua的例子来解释。让我们将自动攻击脚本建模为交替打印“a”和“B”的循环。“A”对应于循环的第一部分(按下并释放A),而“B”代表第二部分(按下并释放S和A) 到目前为止,我们还可以,但循环显然将永远运行,我们需要添加一种方法来阻止它。我认为你想做的是:
local autoattacking = false
function autoattack()
autoattacking = true
while true do
print("A")
if not autoattacking then break end
print("B")
if not autoattacking then break end
end
end
function stop_autoattack()
autoattacking = false
end
autoattack()
stop_autoattack()
但是,由于自动攻击是一个无限循环,因此stop_autoattack永远不会运行,并且自动攻击标志永远不会更新。我们如何解决这个问题
投票
与其调用函数并设置标志来停止循环,不如调用一些代码来查看循环是否应该停止
function continue_autoattack()
print("continue autoattacking? y/n")
return (io.read("*l") == "y")
end
function autoattack()
while true do
print("A")
if not continue_autoattack() then break end
print("B")
if not continue_autoattack() then break end
end
end
autoattack()
在您的鼠标中,这可能意味着使用某种isKeyPressed函数,如果它在API中可用的话。同样重要的是要注意,自动攻击循环仍然是一个无限循环——只是我们改变了它,使它能够控制其停止条件
协同程序
如果我们想让代码停止循环之外的循环,我们需要一种方法一步一步地运行自动攻击循环。以下是一个例子:
local state = 1
function autoattack_step()
if state == 1 then
print("A")
state = 2
elseif state == 2
print("B")
state = 1
elseif state == 3
print("STOPPED")
--state remains as 3
else
error("bad state") -- defensive programming; I hate if/elseif without an else
end
end
function stop_autoattack()
state = 3
end
autoattack_step()
autoattack_step()
autoattack_step()
stop_autoattack()
autoattack_step()
由于我们打破了自动攻击循环,现在有机会在调用autoattack_step之间调用stop_autoattack。要在鼠标脚本中实现这一点,我认为stop\u autoattack可以放在“release button”处理程序中,但我不知道我将把autoattack\u步骤调用放在哪里。可能API在Javascript中包含类似于setTimeout或setInterval的内容
至于合作项目,它们来自哪里?您是否注意到我们需要进行一些实质性的代码重构,以将循环分解为自动攻击步骤的单步块?协同路由是一种Lua特性,它允许您使用循环编写代码,同时仍然能够“一次一步”运行它们。当一个协同路由到达一个coroutine.yield时,它返回给它的调用者。问题是,当您再次调用coroutine.resume时,coroutine将从停止的位置继续执行,而不是像正常函数那样返回到开始位置
local autoattacking = true
autoattack = coroutine.create(function()
while true do
print("A")
coroutine.yield()
if not autoattacking then break end
print("B")
coroutine.yield()
if not autoattacking then break end
end
end)
function stop_autoattack()
autoattacking = false
end
coroutine.resume(autoattack)
coroutine.resume(autoattack)
coroutine.resume(autoattack)
stop_autoattack()
coroutine.resume(autoattack)
coroutine.resume(autoattack)
通常情况下,协同程序使代码更具可读性,而无需使用大量显式“状态”变量将代码从内到外转换。我们仍然需要一些调用coroutine.resume的“高级”代码,就像我们需要一些调用autoattack\u步骤的高级代码一样。我对Logitech mice一无所知,所以我将尝试使用一个简单、纯Lua示例来解释。让我们将自动攻击脚本建模为交替打印“a”和“B”的循环。“A”对应于循环的第一部分(按下并释放A),而“B”代表第二部分(按下并释放S和A) 到目前为止,我们还可以,但循环显然将永远运行,我们需要添加一种方法来阻止它。我认为你想做的是:
local autoattacking = false
function autoattack()
autoattacking = true
while true do
print("A")
if not autoattacking then break end
print("B")
if not autoattacking then break end
end
end
function stop_autoattack()
autoattacking = false
end
autoattack()
stop_autoattack()
但是,由于自动攻击是一个无限循环,因此stop_autoattack永远不会运行,并且自动攻击标志永远不会更新。我们如何解决这个问题
投票
与其调用函数并设置标志来停止循环,不如调用一些代码来查看循环是否应该停止
function continue_autoattack()
print("continue autoattacking? y/n")
return (io.read("*l") == "y")
end
function autoattack()
while true do
print("A")
if not continue_autoattack() then break end
print("B")
if not continue_autoattack() then break end
end
end
autoattack()
在您的鼠标中,这可能意味着使用某种isKeyPressed函数,如果它在API中可用的话。同样重要的是要注意,自动攻击循环仍然是一个无限循环——只是我们改变了它,使它能够控制其停止条件
协同程序
如果我们想让代码停止循环之外的循环,我们需要一种方法一步一步地运行自动攻击循环。以下是一个例子:
local state = 1
function autoattack_step()
if state == 1 then
print("A")
state = 2
elseif state == 2
print("B")
state = 1
elseif state == 3
print("STOPPED")
--state remains as 3
else
error("bad state") -- defensive programming; I hate if/elseif without an else
end
end
function stop_autoattack()
state = 3
end
autoattack_step()
autoattack_step()
autoattack_step()
stop_autoattack()
autoattack_step()
由于我们打破了自动攻击循环,现在有机会在调用autoattack_step之间调用stop_autoattack。要在鼠标脚本中实现这一点,我认为stop\u autoattack可以放在“release button”处理程序中,但我不知道我将把autoattack\u步骤调用放在哪里。可能API在Javascript中包含类似于setTimeout或setInterval的内容
至于合作项目,它们来自哪里?您是否注意到我们需要进行一些实质性的代码重构,以将循环分解为自动攻击步骤的单步块?协同路由是一种Lua特性,它允许您使用循环编写代码,同时仍然能够“一次一步”运行它们。当一个协同路由到达一个coroutine.yield时,它返回给它的调用者。问题是,当您再次调用coroutine.resume时,coroutine将从停止的位置继续执行,而不是像正常函数那样返回到开始位置
local autoattacking = true
autoattack = coroutine.create(function()
while true do
print("A")
coroutine.yield()
if not autoattacking then break end
print("B")
coroutine.yield()
if not autoattacking then break end
end
end)
function stop_autoattack()
autoattacking = false
end
coroutine.resume(autoattack)
coroutine.resume(autoattack)
coroutine.resume(autoattack)
stop_autoattack()
coroutine.resume(autoattack)
coroutine.resume(autoattack)
通常情况下,协同程序使代码更具可读性,而无需使用大量显式“状态”变量将代码从内到外转换。我们仍然需要一些调用coroutine.resume的“高级”代码,就像我们需要一些调用autoattack\u步骤的高级代码一样