Lua 协程(Coroutine):游戏里的“伪多线程”利器

🧩 一、先说结论:协程解决什么问题?

在游戏开发中,你一定写过这种逻辑:

  • 技能释放 → 等1秒 → 再造成伤害
  • 播放动画 → 等动画结束 → 再执行下一步
  • 打字效果 → 一点一点显示

❌ 传统写法(回调地狱)

lua 复制代码
playAnimation(function()
    delay(1, function()
        doDamage()
    end)
end)

👉 问题:

  • 可读性差 ❌
  • 嵌套地狱 ❌
  • 难维护 ❌

✅ 协程写法(像同步一样写异步)

lua 复制代码
function skill()
    playAnimation()
    wait(1)
    doDamage()
end

👉 优点:

  • 逻辑直观 ✔
  • 易维护 ✔
  • 更像"线性流程" ✔

🧠 二、协程到底是什么?

你可以把协程理解为:

👉 "可以随时暂停 / 恢复的函数"


🚀 三、核心API(必须掌握)


🎯 1. 创建协程

lua 复制代码
co = coroutine.create(function()
    print("开始")
end)

🎯 2. 启动协程

lua 复制代码
coroutine.resume(co)

🎯 3. 暂停(关键)

lua 复制代码
coroutine.yield()

👉 流程是这样的:

复制代码
resume → 执行 → yield → 停住
再次 resume → 从停的位置继续

🔥 四、最经典例子(必须看懂)

lua 复制代码
co = coroutine.create(function()
    print("A")
    coroutine.yield()
    print("B")
end)

coroutine.resume(co)  -- 输出 A
coroutine.resume(co)  -- 输出 B

👉 执行过程:

复制代码
第一次 resume → A → yield(暂停)
第二次 resume → B

🎮 五、游戏实战:技能延迟释放


❌ 普通写法(很乱)

lua 复制代码
function castSkill()
    playAnim()

    delay(1, function()
        doDamage()
    end)
end

✅ 协程写法(推荐)

lua 复制代码
function castSkill()
    playAnim()
    coroutine.yield(1)  -- 等1秒
    doDamage()
end

👉 问题来了:

Lua原生 不支持"时间等待"

👉 所以我们要自己实现一个 👇


🔥 六、手写一个"协程调度器"(重点)

这是游戏开发中非常常见的设计👇


🧩 1. 调度器结构

lua 复制代码
Scheduler = {
    tasks = {}
}

🧩 2. 添加任务

lua 复制代码
function Scheduler:add(co)
    table.insert(self.tasks, {
        co = co,
        wait = 0
    })
end

🧩 3. 更新(每帧调用)

lua 复制代码
function Scheduler:update(dt)
    for i = #self.tasks, 1, -1 do
        local task = self.tasks[i]

        if task.wait > 0 then
            task.wait = task.wait - dt
        else
            local ok, waitTime = coroutine.resume(task.co)

            if not ok then
                table.remove(self.tasks, i)
            elseif waitTime then
                task.wait = waitTime
            else
                table.remove(self.tasks, i)
            end
        end
    end
end

👉 关键点:

lua 复制代码
coroutine.yield(1)

👉 相当于:

👉 "暂停1秒后再继续"


🎮 七、完整技能示例(真实项目级)

lua 复制代码
function skill()
    print("播放动画")
    coroutine.yield(1)

    print("造成伤害")
    coroutine.yield(0.5)

    print("播放特效")
end

local co = coroutine.create(skill)
Scheduler:add(co)

👉 游戏主循环:

lua 复制代码
function update(dt)
    Scheduler:update(dt)
end

👉 效果:

复制代码
0s: 播放动画
1s: 造成伤害
1.5s: 播放特效

🧠 八、协程在游戏中的真实用途


🎯 1. 技能系统

  • 延迟伤害
  • 连击技能
  • 持续效果

🎯 2. UI系统

  • 打字机效果
  • 渐显动画
  • loading流程

🎯 3. 剧情系统

  • 对话播放
  • 镜头切换
  • 事件串联

👉 一句话总结:

🔥 所有"有时间流程"的逻辑,都可以用协程写


⚠️ 九、常见坑(一定要知道)


❗ 1. 忘记 resume

👉 协程不会自动执行 ❌


❗ 2. yield 只能在协程里用

lua 复制代码
coroutine.yield()  -- 主线程会报错 ❌

❗ 3. 死循环卡死

lua 复制代码
while true do
    -- 没有 yield
end

👉 会直接卡死游戏 ❌


🔥 十、高手用法(进阶理解)


✅ 协程本质是"流程控制工具"

不是:

  • ❌ 真线程
  • ❌ 并发执行

而是:

👉 主动让出执行权


✅ 对比总结

方式 可读性 可维护性
回调 ❌ 差 ❌ 差
协程 ✅ 高 ✅ 高

📌 十一、本篇总结

🔥 协程让你用"同步写法"写出"异步逻辑"。


相关推荐
草木深雨纷纷1 小时前
星露谷物语整合包手机版下载2026最新版下载分享(里奇赛德村+东斯卡普|拖拉机|自动化+主题美化+功能+汉化+SVE)
游戏·智能手机·游戏程序
SmalBox8 小时前
【节点】[Arctangent节点]原理解析与实际应用
unity3d·游戏开发·图形学
笨鸟先飞的橘猫9 小时前
基于Skynet的分布式游戏场景题:大型MMO的跨服战场系统设计
分布式·学习·游戏·面试·lua
开开心心就好10 小时前
支持添加网址的资源快速打开工具
人工智能·学习·游戏·音视频·hbase·语音识别·storm
晓杰'19 小时前
从0到1实现 Balatro 游戏后端(2):NestJS框架搭建与项目结构设计
后端·websocket·typescript·node.js·游戏开发·项目实战·nestjs
aaaffaewrerewrwer20 小时前
免费在线 2048 游戏推荐|经典数字合并玩法 + 流畅浏览器体验
安全·游戏·个人开发
草木深雨纷纷1 天前
我的世界基岩版手机版(光影材质包大全)下载国际服集合下载分享
游戏·智能手机·游戏程序·材质
草木深雨纷纷1 天前
植物大战僵尸95版下载2026最新版及与原本区别介绍
游戏·游戏程序
郑寿昌1 天前
AI时代动画游戏教育新变革
人工智能·游戏
郑寿昌1 天前
NaniteLumen打造高精3D互动游戏
游戏·3d