Спасибо за комментарии @Vald и @ Egor. Кажется, проблема вызвана тем, что «слишком длинные сопрограммы» заканчиваются в цикле PICO-8. Таким образом, решение состоит в том, что я храню незаконченные сопрограммы в таблице и возобновляю их, если не закончил. Но каким-то образом движение меняется, вроде как «потерянный кадр».
Вот мой отредактированный код:
function _init()
-- code
cors={}
end
function _update()
for i=1,#boids do
local co=cocreate(move_boid)
local c=boids[i]
add(cors,co)
coresume(co,c)
end
for co in all(cors) do
if (co and costatus(co)!="dead") then
coresume(co)
else
del(cors,co)
end
end
end
А также измените функцию расчета, добавив новую строку посередине:
function move_boid(c)
-- code
yield()
-- code
end
Просто сдаться, пока не закончится.
Обновление: Еще один способ сделать это - повторно использовать сопрограммы.
function _init()
-- code
-- create coroutines
cors={}
for i=1,#boids do
local co=cocreate(move_boid)
local c=boids[i]
add(cors,co)
coresume(co,c)
end
end
function _update()
foreach(cors,coresume)
end
-- and wrap the move function with a loop
function move_boid(c)
while true do
-- code
yield()
-- code
yield()
end
end