游戏Lua脚本-使用例程还是轮询?

游戏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

我开始学习如何在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_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论坛进行了一些研究之后,我的脚本似乎有问题

  • 脚本执行循环序列时,不能将标志用作/检测为参数
  • IsMouseButonPressed(读取windows按键)可用于就地或参数
  • Windows仅检测MB1-5,因此无法绑定到G6(注册为第6个按钮)
  • 我了解到,可以使用coutroutine.yield()或轮询来停止循环中的重复脚本。但是我在网上找不到适合初学者的教程


    对不起,我的问题太离谱了

    我对罗技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步骤的高级代码一样