我目前正在使用Roblox(使用Lua)进行游戏。它基本上由几个小游戏组成。在每轮开始时,游戏中的所有玩家都被放入桌子并被传送到一个区域。这是协程开始发挥作用的地方。随着回合的进行,我想要一个协程开始。协程每一秒检查玩家的健康状况是否低于零,并将其从currentPlayer表中移除(如果是)。
很抱歉,如果我没有正确描述问题,但协程将不会产生。我之前没有使用过协同程序,所以我可能试图以错误的方式使用它。我知道你们大多数人都不熟悉Roblox,但是Lua的语法是一样的。
有人可以举个例子说明我将如何结束循环协程吗?
currentPlayers = {}
roundTime = 60
local lookForWinners = coroutine.create(function()
while coroutine.running do
wait(1)
for i, v in pairs(currentPlayers) do
if v.Character.Humanoid.Health <= 0 then
table.remove(currentPlayers, v)
end
end
end
end)
while wait() do
repeat display("Two or more players need to be in the game.", 1) until #_G.plrs > 1 --Ignore, just checks if two+ players are in game.
display("Picking a map...", 3) pickMap()
teleport(0, 500, 0)
coroutine.resume(lookForWinners)
wait(roundTime)
print("Round over")
coroutine.yield(lookForWinners)
end
答案 0 :(得分:4)
Lua是一种单线程语言。协同程序不会导致函数并行执行。
协程实际上只是一种创建一个可以暂停自己执行的函数的方法(使用coroutine.yield
),可以从外部恢复(使用coroutine.resume
)。 There is no "coroutine.running":在任何给定时间只有一条线“正在运行”。
如果Roblox意味着您使用wait()
跳出Lua线程,您可以将其写为一系列循环来检查其状况,然后调用wait()
:
local currentPlayers={}
local roundTime = 60
while #_G.plrs > 1 do
display("Two or more players need to be in the game.", 1)
wait()
end
display("Picking a map...", 3) pickMap()
teleport(0, 500, 0)
for i=0, roundTime do
for i, v in pairs(currentPlayers) do
if v.Character.Humanoid.Health <= 0 then
table.remove(currentPlayers, v)
end
end
wait(1)
end
print("Round over")
然而,这是错误的代码。 (每当你编写代码时,让其中带有“wait”函数的循环用于指示某些内容正在被错误地完成。)你应该使用Roblox的Events来处理游戏的逻辑。
事件在繁忙的循环中具有许多优势;最明显的一点就是你的检查发生 他们正在检查的事情发生时,而不是以后。
答案 1 :(得分:3)
我建议你按照斯图尔特的建议来使用事件;这主要是为了提供有关协程正确使用它们的其他信息。
将coroutines视为可以返回值的函数,但有一个扭曲:当一个“普通”函数执行return
时完成,当你从一个协程yield
时,它会保存它的状态,这样resume
就可以从你屈服的地方继续,好像什么都没发生一样。请注意,您只有{/ 1}} 来自一个协程,并且只到该协程yield
的位置(这与调用函数并从中返回没有什么不同;控件返回到您调用函数的位置。
除此之外,resume
和resume
调用允许您将值传递给协同程序并从协程返回(中间)值。有关如何使用此示例的详细信息,请参阅此SO answer。
一个人仍然可以从一个协程yield
,它与从函数返回没有什么不同,这完成了它的执行。如果你当时检查协同程序的状态(return
),它应该是“死的”。
所以,回答你的问题如何结束一个循环协程:你可以coroutine.status
从它,你可以return
从它(而不再yield()
再次),或者你可以调用resume
,然后您可以在error()
调用的结果中捕获并检查。话虽如此,我同意斯图尔特的说法,这可能是解决问题的错误方法。