比特小队

《比特小队》:一场硬核又有趣的星际冒险

《比特小队》是一款由KunpoGames旗下bit工作室倾力打造的Roguelike+TPS(第三人称射击)独立游戏。它将玩家带入一个充满未知与挑战的随机宇宙,你需要探索各个星球,获取强力的道具和装备,战胜不同类型的敌人,最终拯救危在旦夕的星系。

📹 如果视频无法播放,点击这里直接观看

一款充满挑战的游戏

拯救星系是一项艰难的任务。游戏融合了高随机性的Roguelike元素和硬核的第三人称射击玩法。每一次冒险,你面对的关卡、敌人、道具都是全新的。你需要做好充分的准备,并拥有足够的耐心,才能在一次次的挑战中不断变强,收获游戏丰富有趣的核心内容。

一款停不下来的游戏

除了紧张刺激的战斗,星系中还隐藏着无数的秘密。那些细小的线索就散落在各个角落,每个角色、每个NPC都有着自己的背景故事。游戏拥有海量的武器、道具、成就等待你去收集和解锁。这不仅仅是一场战斗,更是一场发现之旅。

核心玩法与特色

  • 高度随机的Roguelike体验:平行宇宙空间,丰富的元素,无尽的循环,以及多样的结局……每一次游戏都是独一无二的旅程。
  • 爽快的双摇杆射击:流畅的360度自由射击操作,让你在枪林弹雨中尽情穿梭。
  • 海量的内容与深度:超过140种武器、200种道具、100多种怪物、16名特色各异的角色和160项成就,提供了无穷的搭配和玩法流派。
  • 独特的伪像素美术风格:复古而又精致的画面,搭配搞怪有趣的角色设计,构建了一个充满魅力的游戏世界。

玩家社区反响

自发布以来,《比特小队》在玩家社区中收获了大量积极的评价。更是获得了9.4分的高分评价,玩家们普遍称赞其为“国产良心之作”,对其“不逼氪金”的付费模式大加赞赏。丰富的游戏内容和极高的可玩性,让许多玩家沉迷其中,并乐于将其与《以撒的结合》等经典独立游戏进行比较。

研发历程:一段“好玩、耐玩”的探索之旅

《比特小队》的诞生并非一蹴而就,它凝聚了团队数年的心血与坚持。

  • 2015年11月: 游戏原型诞生,确立了Rougelike+TPS的核心玩法。
  • 2016年2月: 宏观设计与程序架构确定,以“平行宇宙”作为世界观载体。
  • 2016年3月: 项目正式立项,以“好玩、耐玩”为根本开发准则。
  • 2016年6月: Alpha1版本完成,首次进行小范围核心玩家测试。
  • 2016年7月: 美术风格重大革新,重制了大量游戏资源。
  • 2016年8月: Alpha2版本完成,进行了首次万人级玩家测试。
  • 2016年11月: Alpha3版本完成,游戏初具规模,包含三大主题关卡。
  • 2017年3月: Alpha4版本测试,新增数十种武器、道具及怪物。
  • 2017年6月: Alpha5版本开启了历时最长的一次玩家内测,共计23天。
  • 2017年11月: Alpha6版本时,游戏内容已接近首个上线版本。
  • 2018年1月: 进行了第7次玩家测试,为上线做最后打磨。
  • 2018年2月: 春节期间进行精英玩家测试,并根据反馈快速迭代,新增了大量内容。
  • 2018年4月26日: 《比特小队》iOS版正式上线!
  • 2018年6月-7月: 安卓版筹备不删档内测,并陆续新增角色、大量武器道具及全新地图“比蒙”。
  • 2018年11月-12月: 新增成员UMA,并发布首个节日主题版本“圣诞SP”。
  • 2019年1月: 新增成员埃米纳基,并发布春节SP版本。
  • 2019年4月26日: 《比特小队》上线一周年!
  • 2019年6月15日: TapTap版本上线一周年,新增皮肤、每日挑战等多个新系统。
  • 2019年12月6日: 新增支线星球——404实验室。

这段漫长而详细的研发历程,不仅记录了游戏的成长,也见证了开发团队与玩家社区之间的紧密互动。正是这种不断的打磨和优化,才最终铸就了《比特小队》这款深受玩家喜爱的优秀作品。

宫爆:老奶奶家族篇

《宫爆:老奶奶家族篇》:我们的十二年经典回归之路

12周年庆,宫爆老奶奶回来啦!作为《宫爆:老奶奶家族篇》的开发者,我想和大家分享一下我们这款承载着无数玩家青春回忆的全新力作,以及它以焕然一新的姿态重现江湖的故事。

📹 如果视频无法播放,点击这里直接观看

经典玩法的完美传承

还记得吗?那些让人热血沸腾的经典技能——北极冰封、磁暴电球、弹球飞鞋、旋风拐杖、暴动假牙……所有这些令人难忘的技能在《宫爆:老奶奶家族篇》中悉数登场!

躲避+技能球经典玩法回归

在设计《宫爆:老奶奶家族篇》时,我们坚持延续宫爆老奶奶系列最核心的玩法精髓:

  • 精准躲避机制:考验玩家的反应能力和操作技巧
  • 技能球系统:丰富多样的技能球提供战略选择
  • 连击系统:流畅的操作手感带来爽快体验
  • 难度递进:从新手友好到挑战极限的完美平衡

经典技能重现

每一个技能都承载着满满的回忆:

北极冰封 - 冰冻一切的绝对控制
磁暴电球 - 电光火石间的致命打击
弹球飞鞋 - 灵活多变的弹射攻击
旋风拐杖 - 席卷全场的旋风之力
暴动假牙 - 出其不意的搞笑攻击

📹 如果视频无法播放,点击这里直接观看

全新伙伴系统

老奶奶的新伙伴登场

在开发《宫爆:老奶奶家族篇》时,我们决定让老奶奶不再孤军奋战!我们全新设计的伙伴系统为游戏带来了更加丰富的策略玩法和情感体验:

经典伙伴阵容:

  • 鸡哥:忠诚可靠的老伙伴,拥有独特的攻击技能
  • 火龙宝宝:萌萌的火系伙伴,提供强力的火焰支援
  • 小精灵:灵活敏捷的魔法助手,擅长辅助和治疗

每个伙伴都有自己独特的技能和性格,玩家可以根据不同的关卡挑战选择最适合的伙伴组合,体验前所未有的团队合作乐趣!

📹 如果视频无法播放,点击这里直接观看

全新视觉体验

卡通地牢+怪物难缠

在美术设计上,我们采用了极简卡通地牢风格,希望营造出既温馨又充满挑战的游戏氛围。我们设计的场景中,老奶奶带着新伙伴们勇闯地下城,每一个场景都充满了冒险的乐趣。连怪物军团我们都重新设计了,在保持原有特色的同时,增添了更多的视觉趣味和挑战性。

美术风格特色:

  • 简约而不简单:极简设计语言传达最直接的游戏乐趣
  • 色彩丰富饱满:明亮的色彩搭配营造轻松愉快的游戏氛围
  • 角色生动有趣:老奶奶形象更加立体生动,充满个性
  • 场景设计巧妙:地牢环境既有挑战性又不失趣味性

我们的12周年心路历程

《宫爆:老奶奶家族篇》对我们来说不仅仅是一款游戏,更是对12年来陪伴我们成长的经典IP的致敬。从2012年最初的简单躲避游戏,到如今的精品力作,宫爆老奶奶系列见证了我们作为开发者的成长,也见证了无数玩家的游戏历程。

传承与创新的完美结合

  • 保留经典:核心玩法和标志性技能完美还原
  • 优化提升:画面、音效、操作手感全面升级
  • 新增内容:更多关卡、技能和挑战等你发现
  • 社交功能:与好友一起重温经典,分享快乐

我们的开发理念:匠心回归

不忘初心的游戏精神

作为KunpoGames的一员,我们始终坚持”游戏带来快乐”的核心理念。在《宫爆:老奶奶家族篇》的开发过程中,我特别注重:

玩家体验至上

  • 简单易上手的操作方式
  • 深度的策略玩法
  • 公平的游戏环境
  • 持续的内容更新

情怀与创新并重

  • 尊重经典,保留原味
  • 技术升级,体验优化
  • 内容扩充,玩法丰富
  • 社区互动,共同成长

我们重新设计的怪物军团

在设计地牢中的怪物时,我们决定不再让它们只是简单的敌人。我们重新设计了它们,让它们拥有更加丰富的行为模式和攻击方式:

我们设计的智能AI系统

  • 我们让怪物具备不同的移动模式和攻击策略
  • 系统会根据玩家行为调整攻击节奏
  • 我们设计的组合攻击带来更高挑战性
  • 每种怪物我们都给它们设计了独特的应对方法

多样化的敌人类型

  • 速度型:快速移动,考验反应能力
  • 力量型:攻击强劲,需要策略规避
  • 技巧型:攻击模式复杂,需要观察学习
  • Boss级:终极挑战,集各种能力于一身

社区与传承

玩家社区的力量

《宫爆:老奶奶家族篇》不仅是一款游戏,更是一个承载回忆和情感的社区平台:

  • 经验分享:老玩家传授技巧,新玩家快速成长
  • 竞技挑战:排行榜系统,展示高超技艺
  • 情感纽带:共同的回忆,深厚的友谊

文化传承的使命

作为一款具有12年历史的经典IP,宫爆老奶奶系列承担着独特的文化传承使命:

  • 游戏文化的传播:向新一代玩家传递经典游戏的魅力
  • 创新精神的延续:在传承中创新,在创新中发展
  • 快乐理念的坚持:始终以玩家的快乐为最高目标
  • 品质追求的执着:精益求精,打造精品游戏体验

未来展望

持续更新计划

  • 新技能解锁:更多创意技能等待发现
  • 新伙伴加入:更多可爱伙伴将陆续登场
  • 关卡扩展:持续增加新的挑战内容
  • 活动赛事:定期举办社区活动和竞技赛事
  • 伙伴培养:伙伴成长系统和装备系统
  • 玩法创新:在经典基础上探索新的游戏模式

开发者的真心话:十二年的成长与坚持

“从老奶奶第一个版本正式上线的2012年算起,今年是第十二个年头,马上又一个龙年。十二年前出生的小宝宝,如今也变成小升初的大孩子。对一个游戏公司来说也差不多,这十二年,经历着实不少,从含着金钥匙出生,到家道中落,再慢慢开始学着自力更生,艰难的过活。少了很多棱角,多了许多圆滑,也学会了拖延,并且还找了一个让自己舒服的理由,拖延是为了思虑更周全,做事更完美,但实际是,懒,怕自己没能力做好,惯性的逃避而已。”

这段来自开发者的真实告白,道出了一个游戏工作室十二年来的真实历程。从初出茅庐到历经沧桑,从意气风发到学会承担,这不仅是KunpoGames的故事,也是无数独立游戏开发者的共同写照。

成长的力量

十二年的时光,见证了太多的变化:

  • 从青涩到成熟:技术的积累,经验的沉淀
  • 从理想到现实:学会在梦想与现实之间找到平衡
  • 从完美主义到务实:明白行动比完美更重要
  • 从个人到团队:理解合作与坚持的意义

不变的初心

尽管经历了种种挫折和考验,但那份最初的热爱和坚持从未改变:

  • 对游戏品质的执着追求
  • 对玩家体验的用心关注
  • 对经典IP的珍视传承
  • 对创新突破的勇敢尝试

我的心声:致敬经典,拥抱未来

作为开发者,《宫爆:老奶奶家族篇》的回归,不仅是我们对12年经典的致敬,更是对我们成长和坚持的见证。在这个快节奏的时代,我希望能和大家一起放慢脚步,重新体验那份最纯真的游戏快乐。

还记得第一次使用北极冰封的震撼吗?还记得磁暴电球电光火石的刺激吗?还记得和朋友一起挑战高分的快乐时光吗?

现在,这一切都回来了。带着我们十二年的积淀,带着成长的智慧,带着对未来的憧憬。

宫爆老奶奶,永远的经典,永远的快乐!
我们十二年的坚持,只为那份最初的感动。


游戏平台:TapTap、App Store、华为、微信小游戏、抖音小游戏 开发团队:KunpoGames(蓝飞互娱)
运营团队:海南梦作坊科技有限公司 游戏类型:动作躲避 / 休闲竞技
支持平台:iOS / Android / HarmonyOS / Wechat / Bytedance
发布状态:现已上线

12周年,经典回归,邀您一起重温宫爆老奶奶的传奇之旅!

🌟 精选项目

KunpoLibrary

进行中
基于Cocos Creator 3.0+的游戏开发框架库,提供常用的游戏开发工具和组件。
TypeScript Cocos Creator 游戏开发

KunpoDemo

进行中
界面编辑器和实体编辑器的实例项目,展示如何使用KunpoLibrary进行游戏开发。
TypeScript Cocos Creator UI编辑器

Creator构建工具

进行中
Cocos Creator 3.8+自动化打包工具,简化游戏发布流程。
Node.js CLI 自动化

📚 开源库

Kunpo ECS

活跃
TypeScript实现的Entity-Component-System架构库,为游戏提供高性能的实体管理。
TypeScript ECS 架构设计

Kunpo Quadtree

活跃
高性能四叉树算法实现,用于游戏中的空间划分和碰撞检测优化。
TypeScript 算法 性能优化

🛠️ 开发工具

性能分析工具

开发中
游戏性能分析与优化工具集,帮助开发者识别和解决性能瓶颈。
TypeScript 性能分析 开发工具

资源优化工具

计划中
自动化的游戏资源优化工具,支持纹理压缩、音频压缩等功能。
Node.js 图像处理 自动化

Creator插件集合

游戏开发工具集合

这是我在游戏开发中积累的一系列常用工具,主要基于 Cocos Creator 开发。这些工具涵盖了ECS、行为树、界面属性绑定、EXCEL转JSON、调试工具、内存查看等多种可视化工具。

完整工具列表

1. 调试与内存分析插件

一个即插即用的 Cocos Creator 调试与性能分析工具,实时编辑属性、定位节点、分析资源内存占用。

商店地址: Cocos Store - 调试与内存分析插件
支持版本: Cocos Creator 2.4.0+ 演示视频: Cocos Creator 调试与内存分析插件演示 Cocos官方推荐: 微信公众号

2. 实体配置插件

一个专为 Cocos Creator 3.7+ 设计的实体配置管理插件,通过可视化编辑和数据驱动方案,彻底简化游戏实体配置流程,提升开发效率。

商店地址: Cocos Store - 实体配置插件
支持版本: Cocos Creator 3.7+

3. 行为树插件

一个专为 Cocos Creator 3.7+ 设计的可视化行为树编辑器,通过可视化编辑和数据驱动方案,彻底简化游戏行为树配置流程,提升开发效率。

商店地址: Cocos Store - 行为树插件
支持版本: Cocos Creator 3.7+

4. 界面属性绑定插件

一个为 Cocos Creator 3.7+ 和 FairyGUI 设计的界面属性绑定插件,通过可视化编辑绑定代码和UI组件。

商店地址: Cocos Store - 界面属性绑定插件
支持版本: Cocos Creator 3.7+

5. Excel转JSON插件

一个 Cocos Creator 3.7+ 的Excel转JSON插件。

商店地址: Cocos Store - Excel转JSON插件
支持版本: Cocos Creator 3.6+


这套工具集合致力于为 Cocos Creator 开发者提供高效、易用的游戏开发解决方案。无论是独立开发者还是团队项目,都能为您的游戏开发之旅提供强有力的支持。

项目持续优化中,敬请期待更多功能和改进!

调试与内存分析插件

面向 Cocos Creator 的运行时调试与内存分析插件。聚焦两件事:实时查看/编辑节点树,一键洞察资源内存占用。不改引擎、零依赖、即插即用。

🎯 核心功能:左手节点树,右手看内存

项目信息

👈 左手功能:实时节点树显示

✅ 运行时自动展示完整节点树(展开/收起) ✅ 点击节点 → 游戏画面高亮定位 ✅ 属性实时编辑(立即生效,无需编译)

支持的属性包括:

  • active:激活状态
  • name:节点名称
  • x, y:位置坐标
  • width, height:尺寸大小
  • anchorX, anchorY:锚点设置
  • scaleX, scaleY:缩放比例
  • rotation:旋转角度
  • opacity:透明度(0-255)
  • color.r/g/b:RGB颜色值

👉 右手功能:资源内存占用查看

✅ 按 Bundle / 资源类型 / 路径分组 ✅ 支持按大小与类型筛选(B/KB/MB/GB) ✅ 默认按占用降序,快速定位“大户”资源

💎 技术特色:真正的即插即用

🔥 兼容性强

  • Creator 2.x ✅ (测试版本:2.4.13)
  • Creator 3.x ✅ (测试版本:3.0.0、3.8.6)
  • 浏览器:Chrome(其他浏览器未测试)

⚡ 零依赖设计

  • TypeScript原生实现
  • 无任何外部框架依赖
  • 无需修改引擎,真正的即插即用

🎨 UI与交互

  • 深色主题,抽屉式面板,默认收起不遮挡画面

📱 性能友好

  • 收起几乎零开销;展开状态 100ms 更新一帧

🎮 实际应用场景

场景一:复杂 UI 调整

直接点击节点高亮定位,现场改位置/尺寸/透明度,省去反复编译验证。

场景二:性能优化分析 📊

项目运行时感觉卡顿,怀疑是资源加载过多导致的内存压力。传统方式下,你只能靠经验猜测或者写复杂的统计代码。

打开内存面板,按 Bundle/类型/路径盘点占用,优先处理 Top 资源包与贴图集。

场景三:新人培训协作 👥

新人看节点树结构,逐个点击即见高亮,十分钟熟悉主界面结构。

🎁 如何获取使用

Creator 2.x 集成

1) 下载 kunpo-inspector.min.js 2) 放入项目目录 3) 在编辑器设置为插件

Creator 3.x 集成

1) 推荐下载 kunpo-inspector.min.mjs(或 kunpo-inspector.min.ts) 2) 直接放入 assets/ 目录,无需插件配置

使用说明

  • 默认收起;左侧展开节点树,右侧展开内存面板
  • 建议仅在开发环境启用,发布前移除或通过宏屏蔽

如有建议与问题,欢迎在商店评论区留言,我会优先处理高频诉求并持续打磨体验。

窗口属性关联插件

kunpocc窗口属性关联插件 - kunpo-fgui

项目信息

🎯 简介

kunpo-fgui 是一个为 Cocos Creator 设计的插件,它提供了一个可视化的编辑器,用于配置和管理基于 FairyGUI 和 kunpo 库的 UI 界面组件属性。

本插件的核心目标是解决在 Cocos Creator 项目中手动管理 FairyGUI 组件引用的痛点,通过”拖拽绑定”和”配置导出”的方式,将 UI 制作与代码逻辑解耦,极大地提升开发效率和项目的可维护性。

✨ 主要功能

插件界面截图

🎨 可视化编辑器

在 Cocos Creator 中提供一个独立的面板,用于展示和操作 FairyGUI 项目。

📋 FairyGUI 项目解析

自动解析 FairyGUI 项目的 XML 文件,以树状视图清晰地展示包、组件和其层级关系。

🖱️ 拖拽属性绑定

支持通过拖拽的方式,将 FairyGUI 的组件与代码中的属性进行可视化绑定。

🔗 自动路径生成

自动生成并管理组件在界面层级中的唯一访问路径 (idPath),无需手动编写。

💾 配置导出

一键将所有 UI 绑定关系导出为 JSON 配置文件,供运行时使用。

🔧 深度集成

提供菜单栏入口和快捷键,无缝集成到 Cocos Creator 的开发流程中。

🚀 解决的痛点

下表对比了使用本插件前后的开发体验:

痛点 使用本插件前 使用本插件后
组件获取 手动编写 getChild、getChildByPath 等代码,繁琐且易错 在可视化面板中拖拽一次即可完成绑定,代码通过配置直接获取对象
代码维护 UI 路径、名称等字符串硬编码在业务代码中,难以维护 所有 UI 路径信息都保存在独立的配置文件中,代码与 UI 细节解耦
UI 变更 UI 设计师修改组件名或层级,开发者需在代码中全局搜索替换,工作量大且风险高 只需在面板中更新绑定并重新导出配置,业务代码无需任何改动
关系概览 难以直观地了解一个复杂界面中所有组件的引用情况 面板中清晰地展示了所有组件的绑定关系,一目了然

📖 如何使用

1️⃣ 打开面板

通过顶部菜单 kunpo/窗口编辑器 或快捷键 Cmd/Ctrl + Shift + F 打开插件主面板。

2️⃣ 选择 FGUI 包

在面板中,选择或导入你的 FairyGUI 项目及对应的包。

3️⃣ 拖拽绑定

从左侧的组件列表中,将需要绑定的组件拖拽到右侧的属性或回调区域。

4️⃣ 导出配置

完成所有绑定后,点击 导出UI配置,插件会自动生成最新的绑定配置文件。

5️⃣ 代码中使用

在你的代码中,加载该配置文件,并通过 kunpo 库的接口来获取和使用已绑定的 UI 组件。

💿 安装

  1. 将此插件文件夹 kunpo-fgui 放置到 Cocos Creator 项目的 extensions 目录下
  2. 重启 Cocos Creator 编辑器即可在 扩展 菜单中看到此插件

🎉 总结

kunpo-fgui 插件通过提供可视化的编辑器和拖拽绑定功能,彻底改变了传统 FairyGUI 组件管理的繁琐方式。无论是新手还是资深开发者,都能通过这个插件显著提升 UI 开发的效率和项目的可维护性。

让我们告别手写 UI 路径和硬编码的时代,拥抱更高效、更智能的 UI 开发方式!🚀

实体配置插件

kunpo-ec - Cocos Creator 实体配置插件

项目信息

🎯 你的游戏开发是否面临这些挑战?

🤔 以下场景是否似曾相识?

实体泛滥困扰:游戏中存在成百上千的对象或实体,管理维护成为噩梦
预制体配置地狱:每个预制体都需要手动挂载组件、逐一设置参数,重复劳动让人崩溃
ECS代码重复:每个实体的创建都需要编写代码添加组件,手动设置各种参数,代码冗余严重
硬编码维护难:通过代码配置实体组件及属性,一旦需要调整就要改代码重新编译
Excel配置混乱:使用Excel表格配置实体参数,数据结构复杂,团队协作困难,版本管理混乱

💡 如果上述任何一种情况让你深有感触…
那么接下来的内容将彻底改变你的开发方式!
准备好告别繁琐的配置流程,拥抱高效的开发体验了吗? 🚀

项目简介

目标:让实体配置变得简单高效!🚀

kunpo-ec 是一款专为 Cocos Creator 3.7+ 设计的编辑器扩展插件。

旨在解决游戏开发中实体配置管理的核心痛点。通过提供强大的可视化编辑界面和数据驱动的配置方案,帮助开发者快速、准确地配置游戏中的各种实体信息,如角色、道具、技能、怪物等实体配置。

极大的降低程序的工作量。

🎯 核心特性

  • 兼容性高:可适用于所有ECS或者EC架构配置(其他使用方式可自行探索)
  • 可视化编辑:提供直观的实体编辑器界面,无需在场景中手动配置
  • 数据驱动:通过装饰器自动暴露组件属性,实现代码即配置
  • 配置分离:支持一键导出 JSON 配置,实现配置与逻辑分离
  • 团队协作:程序定义结构,策划独立配置,提升开发效率
  • 类型安全:支持丰富的 Cocos Creator 数据类型,确保配置的准确性

为什么要使用此插件?

在标准的 Cocos Creator 开发流程中,当项目实体数量增多、组件和属性变得复杂时,开发者通常会面临各种痛点。本插件通过创新的解决方案,彻底改变了传统的实体配置方式。

📊 传统方式 vs KunpoEC插件 对比

方面 传统开发方式 Kunpo EC 插件 优势对比
配置效率 ❌ 场景编辑器中逐个节点配置 ✅ 可视化编辑器统一配置 🚀 效率提升 80%+
数据管理 ❌ 配置分散在.fire/.prefab文件中 ✅ 配置集中管理,独立存储 🔧 管理简化 90%+
团队协作 ❌ 程序需要修改代码配置 ✅ 程序定义结构,策划配置 👥 协作效率提升 85%+
维护性 ❌ 查找prefab困难 ✅ 打开面板,一目了然 🛠️ 维护性提升 90%+

🎯 核心解决方案

1. 集中化管理

  • 提供统一的实体编辑面板,所有需要配置的实体及其组件属性一目了然
  • 无需在节点树中来回寻找,操作更加直观高效

2. 数据驱动

  • 通过在代码中为组件添加装饰器(@ecsclass@ecsprop),即可自动将属性暴露到插件面板中
  • 实现了代码即配置,结构清晰,易于维护

3. 配置与场景分离

  • 支持一键将所有配置导出为独立的 JSON 文件
  • 游戏运行时直接读取 JSON 数据,使配置的归档、版本控制和迁移变得极其简单

4. 提升团队协作

  • 程序定义好数据结构后,策划可独立在插件中完成所有数值配置工作
  • 分工明确,并行开发,大幅提升开发效率

插件功能说明

3.1 可视化实体编辑器

打开方式:

  • 顶部菜单:Kunpo -> 实体编辑器
  • 快捷键:Cmd+Shift+N (Mac) / Ctrl+Shift+N (Windows)

核心功能:

  • 创建和管理实体:添加新的实体配置或删除不再需要的
  • 编辑组件属性:以表单的形式直观地查看和修改所有通过 @ecsprop 暴露的组件属性
  • 实时预览:修改后的数据会实时更新,所见即所得

3.2 一键导出配置

打开方式:

  • 顶部菜单:扩展 -> Kunpo -> 导出配置
  • 快捷键:Cmd+Shift+M (Mac) / Ctrl+Shift+M (Windows)

功能说明:

  • 将您在编辑器中配置的所有实体数据,导出为一个 JSON 文件
  • 自动刷新 Creator 中的资源,确保配置立即生效

3.3 框架支持与独立使用

本插件可作为通用工具独立使用,不强制绑定任何特定框架。您可以导出 JSON 数据,并在自己的项目框架中进行解析。

同时,为了获得更流畅的开发体验,插件也对以下开源框架提供了良好支持:

  • kunpocc-ec: 一种介于 ECS 和 OOP 之间的架构,易于上手
  • kunpocc-ecs: 经典的 ECS 架构,性能更优,灵活性更高

支持的数据类型

插件支持丰富的数据类型配置,满足绝大部分开发需求:

🔢 基础数据类型

  • string - 字符串类型
  • int - 整数类型
  • float - 浮点数类型
  • boolean - 布尔类型

🎮 Creator 核心类型

  • Vec2 - 二维向量
  • Vec3 - 三维向量
  • Color - 颜色类型
  • Size - 尺寸类型

📦 Creator 资源类型

  • Node - 节点引用
  • Prefab - 预制体资源
  • SpriteFrame - 精灵帧资源
  • AudioClip - 音频资源
  • Animation - 动画资源
  • JsonAsset - JSON 资源
  • Particle - 粒子资源
  • Skeleton - 骨骼资源
  • 以及所有 Asset 子类

🔧 高级类型

  • Enum - 枚举类型
  • Array - 数组类型(支持任意嵌套)
  • Object - 对象类型(支持复杂嵌套结构)

快速开始

5.1 安装插件

  1. 安装插件到你的项目:{Creator项目目录}/extensions/kunpo-ec/
  2. 重启 Cocos Creator,插件将自动加载
  3. 在顶部菜单中可以看到 kunpo 选项

5.2 基本使用流程

  1. 定义组件结构:使用装饰器定义需要配置的组件和属性
  2. 打开编辑器:通过菜单或快捷键打开实体编辑器
  3. 配置数据导出路径:在可视化界面中点击导出路径输入框后的放大镜按钮,选择文件夹
  4. 配置实体数据:在可视化界面中配置实体属性
  5. 导出配置:一键导出 JSON 配置文件
  6. 运行时加载:在游戏运行时加载配置数据

5.3 进阶使用流程

  • 实体分组:支持将实体按功能或类型进行分组管理
  • 双击分组改名:双击分组名称可以快速重命名分组
  • 双击实体改名:双击实体名称可以快速重命名实体
  • 拖拽实体分组:可以将实体拖拽到对应的分组中进行分类管理

使用示例

6.1 基础属性示例

import { Color, Enum, Size, Vec2, Vec3 } from 'cc';
import { _ecsdecorator } from 'db://kunpo-ec/ECSDecorator';

const { ecsclass, ecsprop } = _ecsdecorator;

/** 基础属性示例 */
@ecsclass("BaseComponent", { describe: "基础组件" })
export class BaseComponent {
    @ecsprop({ type: "int", defaultValue: 0, displayName: "血量" })
    hp: number = 0;

    @ecsprop({ type: 'float', defaultValue: 0, displayName: "最大血量" })
    maxHp: number = 0;

    @ecsprop({ type: 'string', defaultValue: "", displayName: "字符串" })
    string: string = "";

    @ecsprop({ type: 'boolean', defaultValue: false, displayName: "布尔值" })
    bool: boolean = true;
}

6.2 单层复合属性示例

import { _ecsdecorator } from 'db://kunpo-ec/ECSDecorator';

enum HealthType {
    One = 1,
    Two = 2,
    Three = 3
}

@ecsclass("CompositeComponent", { describe: "复合属性组件" })
export class CompositeComponent {
    @ecsprop({ type: "enum", format: Enum(HealthType), defaultValue: HealthType.One, displayName: "枚举" })
    hpeunm: HealthType = HealthType.One;

    @ecsprop({ type: "array", format: "entity", displayName: "单层数组" })
    list: string[] = [];

    @ecsprop({ type: "array", format: "int" })
    arr: number[];

    @ecsprop({ type: "vec2", displayName: "向量2" })
    vec2: Vec2;

    @ecsprop({ type: "vec3", displayName: "向量3" })
    vec3: Vec3;

    @ecsprop({ type: "color", defaultValue: Color.RED, displayName: "颜色" })
    color: Color;

    @ecsprop({ type: "size", displayName: "尺寸" })
    size: Size;
}

6.3 Creator资源属性示例

@ecsclass("AssetComponent", { describe: "资源组件" })
export class AssetComponent {
    // 编辑器中配置的实体 也可以拖拽引用,导出后是实体名
    @ecsprop({ type: "entity", defaultValue: "", displayName: "实体", tips: "实体" })
    entityName: string = "";

    // cc中的资源类型 导出后是资源的uuid
    @ecsprop({ type: "spriteframe", displayName: "精灵帧" })
    spriteFrame: string = "";

    @ecsprop({ type: "asset", displayName: "资源" })
    asset: string = "";

    @ecsprop({ type: "prefab", displayName: "预制体" })
    prefab: string = "";

    @ecsprop({ type: "skeleton", displayName: "骨骼动画" })
    skeleton: string = "";

    @ecsprop({ type: "particle", displayName: "粒子" })
    particle: string = "";

    @ecsprop({ type: "animation", displayName: "动画" })
    animation: string = "";

    @ecsprop({ type: "audio", displayName: "音频" })
    audio: string = "";

    @ecsprop({ type: "jsonAsset", displayName: "json资源" })
    jsonAsset: string = "";
}

注意事项

⚠️ 重要提醒:代码混淆兼容性

本插件使用到了类名和属性名,如果您的游戏上线时会进行代码混淆,请务必注意:

问题说明:

  • 开发阶段导出的配置文件使用原始的类名和属性名
  • 代码混淆会改变类名和属性名,导致运行时无法正确匹配配置数据

解决方案:

  • 后续可能支持抗混淆版本的装饰器
  • 或自行实现抗混淆版本的装饰器(装饰器的代码在ECSDecorator.ts中,只有100行左右,可以自行实现)

📝 其他注意事项

  • 本插件仅导出数据,数据使用需要自行解析
  • 资源类型导出后是资源的 uuid
  • 插件支持 Cocos Creator 3.7+ 版本

通过 Kunpo EC 插件,您可以彻底告别繁琐的实体配置流程,享受高效、直观的开发体验。无论是独立开发者还是团队项目,这款插件都能显著提升您的开发效率!

Excel转JSON

Excel 转 JSON 工具

这是一个用于将 Excel 文件转换为 JSON 格式的 Cocos Creator 扩展工具。支持多种数据类型和复杂的嵌套结构。

用过很多excel转json的工具,但是策划说都不太好用,所以按照策划的要求自己实现了一个。 可能有更强的工具,但是适合自己的才是最好的。

Excel转JSON 插件界面

项目信息

功能特点

  • 支持将 Excel 文件转换为 JSON 格式
  • 支持多个工作表的转换
  • 支持单文件和文件夹批量转换
  • 支持二进制格式输出
  • 支持多种数据类型:
    • 基本类型:int、float、string、bool
    • 复合类型:list、dict
    • 支持多层嵌套类型
  • 支持全部导出功能
  • 支持自定义配置和全局配置
  • 导出后自动刷新creator资源

使用方法

1. 图形界面操作

通过 Cocos Creator 菜单栏的 “kunpo” -> “ExcelToJSON” 打开工具面板,或使用快捷键:

  • Windows: Ctrl+Shift+K
  • Mac: Cmd+Shift+K

全局配置

  • 导出目录: 设置默认的导出目录
  • 二进制格式: 选择是否输出为二进制格式(.bin)而非JSON(.json)

单项配置

  • 文件/文件夹路径: 选择要转换的Excel文件或包含Excel文件的文件夹
  • 模式选择:
    • 文件模式:转换单个Excel文件
    • 文件夹模式:批量转换文件夹中的所有Excel文件
  • 自定义配置: 启用后可为当前项目设置独立的导出目录和二进制格式
  • 操作按钮:
    • 导出:转换当前项目的Excel文件
    • 删除:移除当前项目配置

批量操作

  • 添加配置: 添加新的Excel转换配置
  • 全部导出: 批量转换所有已配置的Excel文件或文件夹

使用建议

  1. 文件夹模式: 适用于需要批量处理多个Excel文件的场景
  2. 二进制格式: 用于游戏运行时的数据文件,体积更小,加载更快
  3. 路径管理: 建议使用相对路径,便于项目迁移

示例

表类型是数组

1. 基础类型

list          
  name age score type unlock
  string int float bool bool
  Alice 20 98.5 1 FALSE
  Bob 22 87.5 0 TRUE
[
    {
        "name": "Alice",
        "age": 20,
        "score": 98.5,
        "type": true,
        "unlick": false
    },
    {
        "name": "Bob",
        "age": 22,
        "score": 87.5,
        "type": false,
        "unlick": true
    }
]

2. 数组类型

list        
  name scores    
  string list<2> int float
  Alice   3 3.5
  Bob null 4 4.5
[
    {
        "name": "Alice",
        "scores": [
            3,
            3.5
        ]
    },
    {
        "name": "Bob",
        "scores": null
    }
]

3. 字典类型

list        
  name position    
  string dict<x,y> int int
  Alice   10 20
  Bob   30 40
[
    {
        "name": "Alice",
        "position": {
            "x": 10,
            "y": 20
        }
    },
    {
        "name": "Bob",
        "position": {
            "x": 30,
            "y": 40
        }
    }
]

4. 嵌套类型 (数组套字典)

list            
  name atts        
  string list<2|dict<en,ch» string string string string
  张三   one two
  李四   three four
[
    {
        "name": "Alice",
        "atts": [
            {
                "en": "one",
                "ch": "一"
            },
            {
                "en": "two",
                "ch": "二"
            }
        ]
    },
    {
        "name": "Bob",
        "atts": [
            {
                "en": "three",
                "ch": "三"
            },
            {
                "en": "four",
                "ch": "四"
            }
        ]
    }
]

5. 嵌套类型 (字典套数组)

list            
  name attr        
  string dict<en,cn|list<2» string string string string
  张三   one two null
  李四 null three four
[
    {
        "name": "Alice",
        "attr": {
            "en": [
                "one",
                "two"
            ],
            "cn": null
        }
    },
    {
        "name": "Bob",
        "attr": null
    }
]

6. 多层嵌套 (字典套数组套字典)

list                    
  name attr                
  string dict<type,value|list<2|dict<x,y»> int int int int int int int int
  张三   1 2 3 4 5 6 7 8
  李四   11 12 13 14 15 16 17 18
[
    {
        "name": "张三",
        "attr": {
            "type": [
                {
                    "x": 1,
                    "y": 2
                },
                {
                    "x": 3,
                    "y": 4
                }
            ],
            "value": [
                {
                    "x": 5,
                    "y": 6
                },
                {
                    "x": 7,
                    "y": 8
                }
            ]
        }
    },
    {
        "name": "李四",
        "attr": {
            "type": [
                {
                    "x": 11,
                    "y": 12
                },
                {
                    "x": 13,
                    "y": 14
                }
            ],
            "value": [
                {
                    "x": 15,
                    "y": 16
                },
                {
                    "x": 17,
                    "y": 18
                }
            ]
        }
    }
]

表类型是字典

1. 混合

dict 字段名 类型
  id int 1
  name string bob
  atts list<2>  
    int 50
    string as
  position dict<x,y>  
    int 12
    int 22
{
    "id": 1,
    "name": "bob",
    "atts": [
        50,
        "as"
    ],
    "position": {
        "x": 12,
        "y": 22
    }
}

Excel 格式说明

数据表格式

第一行第一列:指定整个sheet的格式(list或dict)

总格式是list

  1. 第二行:字段名
  2. 第三行:类型描述
  3. 第四行开始:实际数据

总格式是dict

  1. 第二列:字段名
  2. 第三列:类型描述
  3. 第四列:实际数据
  4. 只有四列

支持的数据类型

简单类型

  • int:整数
  • float:浮点数
  • string:字符串
  • bool:布尔值(不填、0、null、false 、FALSE为false,其他为true)

复合类型

  • list<n>:数组,n表示数组长度 表示向后(list) 或向下(dict)有n条配置内容
  • dict<a,b,c>:字典,a,b,c表示字典的key 表示向后(list) 或向下(dict)有3条配置内容

嵌套类型

  • list<n|list<m>>:数组嵌套数组
  • list<n|dict<a,b,c>>:数组嵌套字典
  • dict<a,b|dict<x,y>>:字典嵌套字典
  • dict<a,b|list<2>>:字典嵌套数组

转换说明

excel中的每个sheet作为一个json数据,按照sheet名,转换成对应的json文件

特殊规则

  • 如果sheet名中包含”ignore”(不区分大小写),则该sheet将被自动跳过,不会进行转换
  • 例如:”ignore_test”、”data_ignore”、”IGNORE”等都会被跳过

自动化打包工具架构设计

前言

说实话,写这个工具纯粹是被逼的。

发版那天晚上,对着10+个渠道的打包列表,我一遍遍地重复着:打开 Creator → 选平台 → 构建 → 等 → 开 Android Studio → 编译 → 签名 → 上传 → 发通知…

到第三个渠道我就开始怀疑人生了,到第七个渠道我开始思考为什么要做游戏开发。

那天晚上我就下定决心:这种重复劳动必须自动化

一条命令,所有渠道自动打包、自动上传、自动通知。我该干嘛干嘛去,等着收结束消息就行。

一、先聊聊我想解决什么问题

在动手之前,我先梳理了一下痛点:

  1. 渠道太多:Android 官方包、TapTap、抖音APP、微信小游戏、抖音小游戏、支付宝小游戏、华为快游戏、OPPO快游戏、小米快游戏、鸿蒙…

  2. 流程重复:每个渠道的打包流程大同小异,但手动操作每次都要从头来

  3. 容易出错:手动切换配置、手动签名,稍不注意就搞错

  4. 耗时太长:一个渠道打完要好几分钟,10个渠道就是半天起步

所以我的目标很明确:一条命令搞定所有事情

二、核心设计思路:Pipeline 模式

2.1 为什么选 Pipeline?

最开始我也想过用一个大函数把所有逻辑写进去,但很快就发现不行。

不同平台的打包流程差异很大:

  • Android:Creator 构建 → 修改配置 → Gradle 编译 → 签名 → 上传
  • 微信小游戏:Creator 构建 → 上传远程资源 → 调用微信CI上传
  • 鸿蒙:Creator 构建 → 修改配置 → hvigorw 编译 → 签名 → 上传

如果用一个大函数,代码里全是 if (platform === 'android') {...},维护起来简直是噩梦。

于是我想到了 Pipeline 模式:把构建流程拆解为独立的步骤(Step),通过 Pipeline 串联执行。

2.2 Pipeline 长什么样?

说白了就是把打包流程拆成一个个小步骤,然后按顺序执行:

// Android 打包流程
class BuilderAndroid {
    buildPipeline() {
        return [
            new ModifyVersionJsonStep(),      // 修改版本号
            new BuildCreatorStep(),           // Creator 构建
            new ModifyMainJsStep(),           // 修改 main.js(热更新用)
            new GenerateManifestStep(),       // 生成 manifest
            new ModifyNativeConfigAndroid(),  // 修改 Android 原生配置
            new CompileAndroid(),             // Gradle 编译
            new CopyArtifactStep('apk'),      // 拷贝 APK
            new SignApkStep(),                // 签名
            new UploadArtifactStep()          // 上传 CDN
        ];
    }
}
// 微信小游戏打包流程
class BuilderWechat {
    buildPipeline() {
        return [
            new ModifyVersionJsonStep(),   // 修改版本号
            new BuildCreatorStep(),        // Creator 构建
            new UploadRemoteResStep(),     // 上传远程资源到 CDN
            new CompileWechat()            // 调用微信CI上传到后台
        ];
    }
}

看到没?两个平台共用了 ModifyVersionJsonStepBuildCreatorStep,但后面的步骤完全不同。

这种设计的好处就是:

  • 步骤复用:相同的步骤在不同 Builder 中复用
  • 易于扩展:新增渠道 = 组装新 Pipeline,不用改已有代码
  • 流程清晰:看 Pipeline 就知道整个构建流程

三、核心组件设计

3.1 Context:数据容器

这是我从 Linus 那句话学来的:数据结构比代码重要

Context 就是一个数据容器,所有步骤共享同一个 Context,通过它传递数据:

class Context {
    #data = new Map();  // 用 Map 存储,性能更好
    
    constructor(params) {
        // 存储构建参数
        this.set('channel', params.channel);     // 渠道
        this.set('platform', params.platform);   // 平台
        this.set('version', params.version);     // 版本号
        this.set('mode', params.mode);           // debug/release
        this.set('build', params.build);         // 构建号
        // ...
    }
    
    // 基础操作
    get(key) { return this.#data.get(key); }
    set(key, value) { this.#data.set(key, value); }
    
    // 步骤结果管理
    setStepResult(stepName, result) { ... }
    getStepResult(stepName) { ... }
}

为啥要这么设计?

  1. 单一数据源:所有步骤共享同一个 Context,避免参数传递
  2. 解耦:Step 之间不直接依赖,只依赖 Context 中的数据
  3. 可追溯:Context 记录了整个构建过程的所有信息

举个例子,CompileAndroid 步骤编译完 APK 后,把产物路径写入 Context:

context.set('OUTPUT_NAME', 'app-release.apk');

后面的 SignApkStep 直接从 Context 读取:

const apkPath = context.get('OUTPUT_NAME');

Step 之间完全解耦,互不依赖。

3.2 Step:步骤基类

每个 Step 只做一件事,保持简单。我用了模板方法模式:

class Step {
    // 步骤名称(子类必须实现)
    get name() {
        throw new Error('子类必须实现 name');
    }
    
    // 判断是否可跳过(子类可选实现)
    canSkip(context) {
        return context.isStepExecuted(this.name);  // 默认:已执行过则跳过
    }
    
    // 执行步骤(模板方法,统一处理日志和错误)
    async execute(context) {
        if (this.canSkip(context)) {
            Logger.log(`⊳ 跳过步骤: ${this.name}`);
            return context.getStepResult(this.name);
        }
        
        try {
            Logger.log(`▶ 开始执行: ${this.name}`);
            const startTime = Date.now();
            
            const result = await this.run(context);  // 调用子类实现
            
            const duration = ((Date.now() - startTime) / 1000).toFixed(2);
            Logger.success(`✓ 完成: ${this.name} (耗时: ${duration}s)`);
            
            context.setStepResult(this.name, result);
            context.markStepExecuted(this.name);
            return result;
        } catch (error) {
            Logger.error(`✗ 失败: ${this.name}`);
            throw error;
        }
    }
    
    // 实际执行逻辑(子类必须实现)
    async run(context) {
        throw new Error('子类必须实现 run()');
    }
}

基类帮你处理了日志、计时、错误处理、结果缓存,子类只需要专注于业务逻辑。

3.3 Pipeline:执行器

Pipeline 的实现超级简单,就是按顺序执行 Step 数组:

class Pipeline {
    #steps = [];
    
    constructor(steps = []) {
        this.#steps = steps;
    }
    
    async execute(context) {
        Logger.blue('==================== Pipeline 开始执行 ====================');
        Logger.log(`总步骤数: ${this.#steps.length}`);
        
        const startTime = Date.now();
        
        for (let i = 0; i < this.#steps.length; i++) {
            const step = this.#steps[i];
            Logger.log(`\n[${i + 1}/${this.#steps.length}] ${step.name}`);
            await step.execute(context);  // 每个步骤共享同一个 context
        }
        
        const totalDuration = ((Date.now() - startTime) / 1000).toFixed(2);
        Logger.success(`✓ 总耗时: ${totalDuration}s`);
    }
}

3.4 BuilderFactory:工厂类

这里我用了数据驱动的方式,消除了一堆 if/else:

class BuilderFactory {
    // 平台 → Builder 映射表
    static #builderMap = {
        'android': BuilderAndroid,
        'ios': BuilderIOS,
        'harmonyos-next': BuilderHarmony,
        'wechatgame': BuilderWechat,
        'alipay-mini-game': BuilderAlipay,
        'bytedance-mini-game': BuilderBytedance,
        'huawei-quick-game': BuilderHuaweiQuick,
        'oppo-mini-game': BuilderOppoQuick,
        'xiaomi-quick-game': BuilderXiaomiQuick,
        'vivo-mini-game': BuilderVivoQuick
    };
    
    static createByPlatform(platform, params) {
        const BuilderClass = this.#builderMap[platform];
        if (!BuilderClass) {
            throw new Error(`不支持的平台: ${platform}`);
        }
        return new BuilderClass(params);
    }
}

新增平台只需要往 Map 里加一行,不改逻辑。

四、关键优化:buildGroup 共享机制

这个优化真的让我省了不少时间。

4.1 问题背景

Android 平台有多个渠道:官方包、TapTap、抖音APP…

它们都要先执行 Creator 构建,而 Creator 构建是最耗时的(5分钟起步)。

如果打3个 Android 渠道,就要执行3次 Creator 构建,15分钟就没了。

但实际上,同平台的渠道可以共享 Creator 构建产物

4.2 解决方案

在配置文件里,给同平台的渠道设置相同的 group

[
    { "channel": "official", "platform": "android", "group": "android" },
    { "channel": "taptap", "platform": "android", "group": "android" },
    { "channel": "douyin", "platform": "android", "group": "android" }
]

然后在 BuildCreatorStep 里实现跳过逻辑:

class BuildCreatorStep extends Step {
    canSkip(context) {
        const channel = context.get('channel');
        const buildGroup = DataHelper.channels.getBuildGroup(channel);
        
        // 检查该 buildGroup 是否已经构建过
        if (buildGroup && BuildCache.isGroupBuilt(buildGroup)) {
            Logger.log(`跳过 Creator 构建:buildGroup [${buildGroup}] 已构建(共享产物)`);
            return true;
        }
        return false;
    }
    
    async run(context) {
        // 执行 Creator 构建
        await runCreatorBuild(...);
        
        // 标记 buildGroup 已构建
        const buildGroup = DataHelper.channels.getBuildGroup(channel);
        if (buildGroup) {
            BuildCache.markGroupBuilt(buildGroup, channel);
        }
    }
}

效果:

  • 打包 official 渠道:执行 Creator 构建,标记 android 组已构建
  • 打包 taptap 渠道:检测到 android 组已构建,跳过 Creator 构建
  • 打包 douyin 渠道:检测到 android 组已构建,跳过 Creator 构建

3个渠道只需要1次 Creator 构建,从15分钟优化到5分钟!

4.3 BuildCache 实现

class BuildCache {
    static #builtGroups = new Map();  // 已构建的 buildGroup
    
    static isGroupBuilt(buildGroup) {
        return this.#builtGroups.has(buildGroup);
    }
    
    static markGroupBuilt(buildGroup, channel) {
        if (!this.#builtGroups.has(buildGroup)) {
            this.#builtGroups.set(buildGroup, {
                builtBy: channel,   // 首次构建的渠道
                sharedBy: []        // 共享的渠道列表
            });
        } else {
            const info = this.#builtGroups.get(buildGroup);
            info.sharedBy.push(channel);
        }
    }
    
    static clear() {
        this.#builtGroups.clear();  // 每次批量构建开始时清空
    }
}

批量打包结束后,还会打印共享汇总:

==================== Creator 构建共享 ====================
[android]
  构建者: official
  共享者: taptap, douyin (节省 2 次 Creator 构建)

五、命令行入口设计

我设计了两种使用方式:

5.1 交互式打包

运行 npm run build,会弹出交互式界面:

? 请选择渠道类型: (Use arrow keys)
  ━━━━━━━━ 渠道分组 ━━━━━━━━
  🌍 全部渠道 (all)
  🎮 小游戏 (minigame)
  ⚡ 快游戏 (quickgame)
  📱 原生平台 (native)
  ━━━━━━━━ 单个渠道 ━━━━━━━━
❯ 官方android (official)
  TapTap (taptap)
  微信小游戏 (wechatgame)
  ...

按上下键切换选中渠道,回车确认,继续输入版本号、构建号、选择模式等。

这种方式适合开发时用,直观方便。

5.2 命令式打包(CI/CD)

npm run build:jenkins -- \
  -p official,taptap \
  -v 1.0.0 \
  -b 100 \
  -d false \
  -r 15 \
  -m "修复bug" \
  -n true

参数都通过命令行传入,适合 Jenkins 等 CI 系统调用。

5.3 渠道分组

为了方便批量打包,我还设计了渠道分组:

-p all          # 所有渠道
-p minigame     # 小游戏渠道(微信、抖音、支付宝)
-p quickgame    # 快游戏(华为、oppo、vivo、小米)
-p native       # 原生平台(Android、iOS、鸿蒙)
-p official,taptap  # 指定多个渠道

实现也很简单:

class ChannelParser {
    static parseChannels(channelInput) {
        const inputs = channelInput.split(/[,\s]+/);
        const channelSet = new Set();
        
        for (const input of inputs) {
            // getChannelsByGroupKey 会根据关键字返回对应的渠道列表
            const channels = DataHelper.channels.getChannelsByGroupKey(input);
            channels.forEach(ch => channelSet.add(ch));
        }
        
        return Array.from(channelSet);  // 去重后返回
    }
}

六、通知系统

打包完成后,自动发送飞书通知。

6.1 消息收集

每个渠道打包完成(成功或失败),都会把结果收集到 MessageHelper

// BuilderBase.start()
async start() {
    try {
        await pipeline.execute(this.context);
        
        // 成功,收集消息
        const message = this.context.getBuildMessage();
        message.succeed = true;
        MessageHelper.addMessage(message);
    } catch (error) {
        // 失败,也收集消息
        const message = this.context.getBuildMessage();
        message.succeed = false;
        message.message = error.message;
        MessageHelper.addMessage(message);
    }
}

6.2 批量发送

批量打包时,所有渠道都打完后,统一发送一条飞书卡片消息:

// build-core.js
async function startBatchBuild(params) {
    // 初始化
    MessageHelper.initBaseInfo('build', version, mode, '', buildCode);
    
    // 逐个打包
    for (const channel of channels) {
        try {
            await startBuild({ ...params, channel }, true);  // true = 跳过单独通知
        } catch (error) {
            // 继续打包下一个
        }
    }
    
    // 统一发送通知
    await MessageHelper.send();
}

这样打包10个渠道,只会收到1条汇总消息,不会被通知轰炸。

6.3 飞书卡片

针对不同平台,飞书卡片的展示也不一样:

  • Android/鸿蒙:显示下载按钮 + CDN 链接
  • 微信/抖音小游戏:显示二维码图片
  • 打包失败:显示错误信息

代码里用不同的方法处理:

#parseBuildMessageElement(messageType, info) {
    if (!info.succeed) {
        return this.#buildFailMessage(info);
    }
    if (DataHelper.platforms.isQRCode(info.platform)) {
        return this.#buildMessageQrcode(info);
    }
    if (info.platform === "harmonyos-next") {
        return this.#buildMessageHarmony(info);
    }
    return this.#buildMessageDefault(info);
}

七、热更新支持

除了完整打包,我还支持了热更新流程。

热更新的 Pipeline 更简单:

class BuilderHotUpdate extends BuilderBase {
    buildPipeline() {
        return [
            new ModifyVersionJsonStep(),    // 修改 version.json
            new BuildCreatorStep(),         // 构建 Creator 项目
            new ModifyMainJsStep(),         // 修改 main.js
            new GenerateManifestStep(),     // 生成热更新 manifest
            new UploadHotUpdateResStep()    // 上传热更新资源到 CDN
        ];
    }
}

复用了 Creator 构建相关的 Step,只是后面的步骤不一样。

八、配置文件设计

所有配置都放在 config/ 目录下,模版在 template/ 目录:

config/
├── base.json           # 基础配置(Creator 路径、项目路径)
├── channels.json       # 渠道配置(渠道列表、分组)
├── platforms.json      # 平台配置(构建路径、打包配置文件)
├── certificates.json   # 证书配置(Android/鸿蒙签名证书)
├── oss.json           # OSS 配置(上传地址)
├── hotupdate.json     # 热更新配置
└── notification.json  # 通知配置(飞书 webhook)

配置和代码分离,不同项目只需要改配置文件,不用改代码。

九、目录结构

最后放一下项目的目录结构:

src/
├── core/                   # 核心框架
│   ├── Context.js         # 数据容器
│   ├── Step.js            # 步骤基类
│   ├── Pipeline.js        # 执行器
│   └── BuildCache.js      # 构建缓存(buildGroup 共享)

├── builders/               # 构建器
│   ├── BuilderBase.js     # 构建器基类
│   ├── BuilderFactory.js  # 工厂类
│   ├── BuilderAndroid.js  # Android
│   ├── BuilderWechat.js   # 微信小游戏
│   ├── BuilderHarmony.js  # 鸿蒙
│   └── ...

├── steps/                  # 步骤
│   ├── creator/           # Creator 相关
│   │   ├── BuildCreatorStep.js
│   │   ├── ModifyVersionJsonStep.js
│   │   ├── ModifyMainJsStep.js
│   │   └── GenerateManifestStep.js
│   ├── compile/           # 编译相关
│   │   ├── CompileAndroid.js
│   │   ├── CompileWechat.js
│   │   └── ...
│   ├── sign/              # 签名相关
│   └── upload/            # 上传相关

├── config/                 # 配置加载器
├── notification/           # 通知系统
├── oss/                    # OSS 上传
├── utils/                  # 工具类
└── bin/                    # 入口脚本
    ├── build.js           # 交互式打包
    ├── build-jenkins.js   # CI/CD 打包
    ├── hotupdate.js       # 交互式热更新
    └── hotupdate-jenkins.js  # CI/CD 热更新

十、总结

说实话,这个工具我写了大概一周,后面又断断续续优化了几天。

核心就这几个东西:

  1. Pipeline 模式:把流程拆成步骤,组装执行
  2. Context 数据容器:步骤间解耦,通过数据通信
  3. buildGroup 共享:同平台渠道共享构建产物,省时间
  4. 工厂模式:数据驱动,消除 if/else

其实架构不复杂,关键是想清楚要解决什么问题。

之后每次发版,我就运行一条命令,然后去喝杯咖啡。等收到飞书通知,所有渠道都打完了。

后来我把它集成到Jenkins后,每次发版,策划直接在网页上点击几下就可以完成打包了。

任务顺利交出去了,反正我再也不用发版当天加班到凌晨了。


如果你也在做游戏开发,也被多渠道打包折磨过,希望这篇文章能给你一些启发。

十一、扩展阅读

当然也有Store版本,不想自己动手的可以购买使用:

热更新最佳实践【CocosCreator】

前言

热更新的本质很简单,说白了就是把游戏资源放到远程服务器,然后客户端在需要时下载远程资源,使用远程资源替换本地文件。

一、Creator官方提供的热更新方案

Creator官方提供了热更新方案,详细信息请参考文档热更新。 这里简单介绍一下:

  • project.manifest文件 用来比对本地和远程的资源差异,确定哪些文件需要下载。
    • 本地和远程各有一份 project.manifest 文件,project.manifest 文件中包含了所有资源的简略信息,比如文件名、大小、MD5等。
    • 通过比对本地和远程的project.manifest 中文件的md5,来确定哪些文件需要下载。
  • version.manifest文件 减少流量消耗,减少计算量
    • 由于project.manifest可能比较大,所以官方还提供了一份version.manifest 文件,有用的信息其实只有资源版本号
    • 通过比对本地project.manifest和远程version.manifest 中的资源版本号,来确定是否需要下载project.manifest以及是否需要做文件比对
  • 生成热更新资源流程
    1. 构建项目(构建选项不要选中 MD5 Cache 选项)
    2. 使用构建后的资源生成 project.manifestversion.manifest 文件
    3. 上传资源到CDN
  • 客户端更新的流程 (每次都会下载version.manifest)
    1. 初始化AssetsManager,加载本地project.manifest文件
    2. 下载远程的version.manifest文件,比对资源版本号,不需要更新跳过,需要更新继续下一步
    3. 下载远程的project.manifest文件,比对文件MD5
    4. 下载差异文件到本地,设置文件搜索路径
    5. 重启游戏

二、踩坑经历

2.1 远程资源存储路径问题

很多年前第一次做热更新功能时,我们把资源按照游戏版本号放到CDN上 最初的方案是这样的

cdn.example.com/game/1.0.0/  # 游戏版本 1.0.0
  ├── project.manifest
  ├── version.manifest
  └── remote-assets/
      ├── assets/
      ├── src/
      └── jsb-adapter/

每次发布热更新,直接在 1.0.0/ 目录下覆盖资源再覆盖 manifest 文件和 version.manifest 文件。看起来没问题,但实际上有个时间窗口问题:

  1. 玩家 A 在 10:00 开始检测更新, 发现远程资源版本号是2,需要更新 100 个文件
  2. 玩家 A 开始下载,已经下载了 50 个文件
  3. 这时候 10:10 我们发了资源版本,把CDN上的资源全部覆盖了
  4. 玩家 A 继续下载剩下的 50 个文件,但这些文件已经是版本 3 的了
  5. 最终玩家 A 本地的资源是版本 2 和版本 3 混合的,文件完整性被破坏,启动游戏时直接崩了

2.2 本地资源污染的问题

从CDN下载的远程资源会保存到本地,开始就直接在可写目录下新建了一个hotupdate文件夹,并没有其他区分机制,导致不同包版本的热更新资源全部放到同一个目录下,跨包版本更新时旧文件没清理干净,运行的是四不像版本,各种诡异 bug。

后来才找到靠谱的方案。这篇文章说说我是怎么踩坑、怎么填坑的。

三、解决方案

先明确两个概念:

  • 游戏版本号:指的是通过应用商店发布的包版本,比如 1.0.0、1.1.0、2.0.0
  • 资源版本号:指的是同一个游戏版本下的热更的资源版本,这里我们用数字表示,比如 1、2、3、4…,发布包中的资源版本号用0表示初始资源版本

举个例子:游戏版本 1.0.0 可能有多个资源版本(1、2、3…),每次热更新都会递增资源版本号。

3.1 远程资源存储路径问题的解决方案

按照下面这样分布热更新资源,还有另外一个好处 可以提前准备热更新资源,并上传到CDN,但是不上传version.manifest文件 等时间到发布的时间节点,再替换掉远程的version.manifest文件,指向最新版本的资源

上文中2.1中提到的问题,是因为我们直接操作了已经发布了的热更新资源,我们不能保证瞬间上传完成,所以就需要已经发布的资源保证不再修改。 所以我们改成了下面这样的CDN文件布局:

cdn.example.com/game/
  └── 1.0.0/  # 游戏版本 1.0.0
      ├── version.manifest  # 固定地址,内容指向最新的资源版本
      ├── 1/  # 资源版本 1
      │   ├── project.manifest
      │   └── remote-assets/
      ├── 2/  # 资源版本 2
      │   ├── project.manifest
      │   └── remote-assets/
      └── 3/  # 资源版本 3
          ├── project.manifest
          └── remote-assets/

每次发布热更新,直接在1.0.0/目录下根据资源版本号新建一个目录,然后上传 project.manifest远程资源 文件。 由于每次都会重新下载version.manifest文件,所以我们把变更后的新地址保存到version.manifest

{
    "packageUrl":"https://cdn.example.com/game/1.0.0/3",  // 指向新的资源地址
    "remoteManifestUrl":"https://cdn.example.com/game/1.0.0/3/project.manifest", // 指向新的 project.manifest 地址
    "remoteVersionUrl":"https://cdn.example.com/game/1.0.0/version.manifest",    // 这个地址保持不变
    "version":"3"  // 新的资源版本号
}

当所有文件上传完成之后,最后替换远程的1.0.0/version.manifest 文件 这样就保证了已经发布的资源不会被修改,也不会被覆盖。

3.1.1 引入了新的问题

玩家热更新时,下载远程的version.manifest文件和project.manifest文件使用的都是本地的project.manifest文件中的地址。 这些地址是不会变化的,指向的远程资源还是老的文件,当然远程version.manifest文件中的地址已经发生变化了。 但是version.manifest目前有用的信息只用到了version字段,也就是资源版本号。

3.1.2 解决问题(动态变更资源的指向)

通过查看官方AssetsManager的源码,发现AssetsManager中其实是提供了动态修改远程地址的问题 下载远程version.manifest文件后,把其中的地址相关的信息,覆盖到本地的project.manifest文件中

    // 参数1: 本地project.manifest文件路径,可以传空字符串,或者加载后的资源Asset的nativeUrl属性
    // 参数2: 本地存储目录
    // 参数3: 版本号比对函数,这里我用的是数字,比较大小就行了
    this._am = new native.AssetsManager("", writablePath, (v1, v2) => {
        return v1 > v2;
    });
    // 之后下载远程的version.manifest文件,替换本地project.manifest文件中的地址后,再重新加载LocalManifest
    this._am.getLocalManifest().parseJSONString(JSON.stringify(content), manifestRoot);

2.2 本地资源污染解决

这个就很简单了,可以根据游戏版本号组织本地资源的缓存目录,或者跨游戏版本后,清理之前存的本地资源。

    // 之前的资源存储路径
    let storagePath = `${jsb.fileUtils.getWritablePath()}hotupdate/`;

    // 新的资源存储路径
    let gameVersion = '1.0.0'; // 游戏版本号
    let storagePath = `${jsb.fileUtils.getWritablePath()}hotupdate/${gameVerison}/`;

3.3 完整流程:

3.3.1 打包流程:

  1. 构建Creator项目
  2. 修改构建后的main.js文件,添加热更代码
  3. 生成project.manifest文件
  4. 原生平台打包(Android、iOS、鸿蒙)

3.3.2 热更新资源上传:

  1. 构建Creator项目
  2. 生成project.manifestversion.manifest 文件
  3. 先按资源版本号上传资源文件到CDN
  4. 再上传project.manifest 文件到CDN
  5. 最后上传version.manifest 文件到CDN

3.3.3 游戏热更新流程:

  1. 启动游戏
  2. 创建AssetsManager实例
  3. 下载远程version.manifest文件,比对资源版本号,不需要更新跳过,需要更新继续下一步
  4. 读取本地project.manifest文件,使用3下载的version.manifest文件中的地址,替换本地project.manifest文件中的地址
  5. 重新加载LocalManifest
  6. 调用AssetsManagerupdate方法,开始更新
  7. 更新完成,设置搜索路径,重启游戏

四、总结

跨游戏版本更新,只需要更新对应版本文件夹下的version.manifest文件,指向最新版本的资源即可。

  • 不要修改已发布热更新资源
  • 动态修改manifest是关键
  • 热更的资源按游戏版本隔离
  • 使用脚本自动化构建、热更流程,防止人为操作失误

这篇文章分享的方案不一定是最优的,但起码是我在实际项目中验证过的,基本能覆盖常见场景。如果你也在做热更新,希望能帮你少踩点坑。

有问题随时交流,大家一起进步。

五、扩展阅读

资源加载【CocosCreator】

CocosCreator资源加载

先吐槽一下

用 Cocos Creator 开发也有段时间了,说实话资源加载这块一直让我挺头疼的。

每次写加载代码都是这样,或者先加载bundle再这样:

resources.load("prefab/player", Prefab, (err, prefab) => {
    if (err) {
        console.error(err);
        return;
    }
    // 终于可以用了
});

加载个资源要写这么一坨,关键是项目里到处都是这种代码。

更麻烦的是批量加载。比如进入战斗场景,我要加载:

  • config 文件夹下的配置
  • icon 文件夹下的图标
  • prefab 文件夹下的预制体
  • 还有其他 bundle 里的资源

这时候就得自己写循环、计算进度、处理异常…每个项目都要封装一遍,烦死了。

还有资源释放的问题。退出战斗场景时,怎么把刚才加载的资源都释放掉?一个个记录路径?太蠢了。引用计数?自己管理容易出错。

反正就是觉得官方的 API 不太够用,每次都要自己折腾。

干脆自己封装一个

既然每个项目都要写,不如封装成库,以后直接用。于是就有了 bit-assets。

核心思路很简单:

  1. 用配置的方式批量加载资源
  2. 自动管理资源池和引用计数
  3. 支持按批次释放资源

批量加载资源

import { AssetLoader, IAssetConfig } from "kunpocc-assets";

// 把要加载的资源配置好
let configs: IAssetConfig[] = [
    { path: "config" },
    { path: "icon", type: SpriteFrame },
    { path: "prefab", type: Prefab },
    { path: "texture/avatar", type: SpriteFrame, isFile: true },  // 单个文件
    { path: "pet", type: SpriteFrame, bundle: "battle" },     // 其他 bundle
];

// 创建加载器
let loader = new AssetLoader("battle");  // 给个名字,后面释放用得上
loader.parallel = 10;  // 并行的任务数量
loader.retry = 3;      // 失败了重试 3 次

loader.setCallbacks({
    complete: () => {
        console.log("加载完了");
    },
    fail: (code, msg) => {
        console.error("加载失败:", msg);
    },
    progress: (percent) => {
        console.log("进度:", Math.floor(percent * 100) + "%");
    }
});

loader.start(configs);

使用已加载的资源

import { AssetPool } from "kunpocc-assets";

let prefab = AssetPool.get<Prefab>("prefab/player");
let icon = AssetPool.get<SpriteFrame>("icon/gold", "bundleName");

// 也可以用 UUID 获取
let asset = AssetPool.getByUUID<SpriteFrame>("xxxxx-xxxx-xxxx");

释放资源

import { AssetPool } from "kunpocc-assets";

// 释放单个资源
AssetPool.releasePath("prefab/player");

// 释放整个文件夹下的 SpriteFrame 类型资源
AssetPool.releaseDir("icon", "resources", SpriteFrame);

// 重点:按批次释放
AssetPool.releaseBatchAssets("battle");  // 把刚才加载的战斗资源全释放掉

// 释放所有资源
AssetPool.releaseAll();

这个批次释放真的很好用。比如我做了个战斗场景和商城场景:

// 进战斗
let battleLoader = new AssetLoader("battle");
battleLoader.start(battleConfigs);

// 进商城
let shopLoader = new AssetLoader("shop");
shopLoader.start(shopConfigs);

// 退出战斗,一行代码释放所有战斗资源
AssetPool.releaseBatchAssets("battle");

// 退出商城,一行代码释放所有商城资源
AssetPool.releaseBatchAssets("shop");

场景切换的时候再也不用担心资源释放的问题了。

其他功能

用Creator加载的资源也可以加入到管理中,最后统一释放

resources.load("prefab/player", Prefab, (err, prefab) => {
    if (err) {
        console.error(err);
        return;
    }
    // 参数1: 资源
    // 参数2: 资源所在的bundle 默认: resources
    // 参数3: 资源加载批次名 可以不传 默认 ""
    AssetPool.add(prefab, resources, "batchName");
});

一些特点

  • 支持 Cocos Creator 3.7+
  • 没有其他依赖,就几个文件
  • 自动管理引用计数,不用担心内存泄漏
  • 同一个资源加载多次和一次效果一样,释放一次卸载

开源免费

代码放 GitHub 上了,ISC 协议,随便用:

  • GitHub: https://github.com/Gongxh0901/kunpocc-assets
  • NPM: https://www.npmjs.com/package/kunpocc-assets

也有商城版本,同样免费

有 bug 或者建议欢迎提 issue,我看到会回复。

最后

这个库主要是我自己项目在用,觉得还挺顺手的,就分享出来了。

如果你也觉得 Creator 的资源加载 API 不太好用,可以试试这个。代码不多,看源码也很快。

有问题随时交流。

自动化打包工具架构设计

分享一个 Cocos Creator 多渠道自动化打包工具的设计思路,采用 Pipeline 模式实现灵活的构建流程,支持 Android、iOS、鸿蒙、微信小游戏等10+平台一键打包。

Creator插件集合

游戏开发工具集合

比特小队

《比特小队》:一场硬核又有趣的星际冒险

网络模块

kunpocc-net:专为小游戏和原生(Android、iOS)平台开发的网络库

调试与内存分析插件

即插即用的 Cocos Creator 调试与性能分析工具,实时编辑属性、定位节点、分析资源内存占用。

kunpocc框架

kunpocc是基于Cocos Creator的游戏开发框架,提供UI管理、平台适配、计时器等常用功能模块。

批量打包工具

批量打包工具:解决多平台发布的重复劳动

宫爆:老奶奶家族篇

《宫爆:老奶奶家族篇》:我们的十二年经典回归之路

网络模块

kunpocc-net:专为小游戏和原生(Android、iOS)平台开发的网络库

它解决什么问题

如果你在开发小游戏,特别是需要同时支持微信、支付宝、字节跳动等多个平台,你会发现一个头疼的问题:每个平台的网络API都不完全一样。

微信小游戏用wx.requestwx.connectSocket,支付宝用my.requestmy.connectSocket,字节跳动又是另一套API。写一次代码要适配多个平台,需要大量的if-else判断。

kunpocc-net就是为了解决这个问题——用统一的API,让你的网络代码在所有平台上都能跑

主要功能

1. HTTP请求模块

  • 封装XMLHttpRequest,支持GET/POST/PUT/HEAD
  • 统一的API接口,不用管底层平台差异
  • 支持JSON、文本、二进制数据响应
  • 完整的错误处理和超时控制

2. WebSocket模块

  • 抹平各小游戏平台WebSocket API的差异
  • 统一的连接、收发消息、断开接口
  • 支持文本和二进制数据传输
  • 自动处理平台兼容性

3. 网络文件读取

  • 简化网络文件加载流程
  • 统一的文件读取API

快速开始

安装

npm install kunpocc-net

HTTP请求示例

import { HttpManager, IHttpEvent } from 'kunpocc-net';

// 定义请求回调
const loginEvent: IHttpEvent = {
    name: "login",
    onComplete: (response) => {
        console.log('登录成功:', response.data);
    },
    onError: (response) => {
        console.log('登录失败:', response.error);
    }
};

// 发送POST请求
HttpManager.post(
    "https://api.example.com/login",
    { username: "test", password: "123456" },
    "json",
    loginEvent
);

// 发送GET请求
HttpManager.get(
    "https://api.example.com/userinfo", 
    { userId: 123 },
    "json",
    loginEvent
);

WebSocket连接示例

import { Socket } from "kunpocc-net";

// 创建连接
const socket = new Socket("wss://game-server.com/ws", {
    binaryType: "arraybuffer",
    timeout: 5000
});

// 监听连接事件
socket.onopen = () => {
    console.log("连接成功");
};

socket.onmessage = (data) => {
    console.log("收到消息:", data);
};

socket.onclose = (code, reason) => {
    console.log("连接断开:", code, reason);
};

// 发送消息
socket.send("Hello Server");

// 发送二进制数据
socket.sendBuffer(buffer);

// 主动断开
socket.close(1000, "正常关闭");

技术特点

简单实用:API设计简洁,上手快。一个HttpManager.post()就能发请求,一个new Socket()就能建连接。

跨平台兼容:自动识别运行平台,无需手动适配。在微信、支付宝、字节跳动小游戏,以及普通Web环境都能正常工作。

类型安全:完整的TypeScript类型定义,IDE有完整的代码提示和类型检查。

零依赖:不依赖任何第三方库,打包后体积小。

生产可用:已在多个游戏项目中使用,稳定可靠。

适用场景

  • 小游戏网络通信(特别是需要多平台发布的项目)
  • Web游戏开发
  • 需要简化HTTP请求管理的项目
  • 需要WebSocket长连接的实时游戏

项目信息

如果你在小游戏开发中遇到网络API兼容问题,或者想简化HTTP请求代码,kunpocc-net应该能帮到你。

kunpocc框架

kunpocc:我的Cocos Creator游戏开发框架

项目简介

kunpocc(简称kunpocc)是我开发的一个基于Cocos Creator的游戏开发框架。在用Cocos Creator做游戏项目时,经常会遇到一些重复性的开发工作,比如UI窗口管理、资源加载、平台API差异处理等。为了提高开发效率,我把这些常用功能封装成了一个框架。

这个框架已经在几个商业项目中使用。

技术栈

  • TypeScript: 完全使用TypeScript编写,提供完整的类型定义
  • Cocos Creator: 支持3.7+版本
  • FairyGUI: UI编辑器,提供强大的UI制作能力
  • NPM: 已发布到npm,方便安装使用

主要功能模块

1. UI管理系统

这是框架的核心功能,基于FairyGUI构建,提供完整的窗口管理功能:

主要特性

  • 装饰器语法简化UI开发
  • 自动资源加载和释放
  • 窗口层级管理
  • 多窗口组管理
  • 顶部资源栏(Header)复用

使用示例

import { Window, _uidecorator } from 'kunpocc';
const { uiclass, uiprop, uiclick } = _uidecorator;

@uiclass("Window", "Home", "MainWindow")
export class MainWindow extends Window {
    @uiprop private btnStart: GButton;
    @uiprop private txtTitle: GTextField;

    @uiclick
    private onBtnStart(): void {
        console.log('开始游戏');
    }
}

2. 平台工具

提供平台检测和小游戏API封装,支持:

  • 微信小游戏
  • 抖音小游戏
  • 支付宝小游戏

平台检测示例

import { Platform } from 'kunpocc';

if (Platform.isWX) {
    console.log('当前是微信小游戏');
} else if (Platform.isAndroid) {
    console.log('当前是Android平台');
}

小游戏API使用

import { MiniHelper } from 'kunpocc';

// 获取小游戏基础信息
const common = MiniHelper.common();

// 播放广告
const ad = MiniHelper.ad();

// 支付功能
const pay = MiniHelper.pay();

3. 全局计时器

提供统一的计时器管理功能:

import { GlobalTimer } from 'kunpocc';

// 启动定时器 (回调函数, 时间间隔秒, 重复次数: 0=执行一次, -1=无限重复)
const timerId = GlobalTimer.startTimer(() => {
    console.log('定时器执行');
}, 1, -1); // 每秒执行一次,无限重复

// 停止定时器
GlobalTimer.stopTimer(timerId);

// 暂停和恢复
GlobalTimer.pauseTimer(timerId);
GlobalTimer.resumeTimer(timerId);

4. 屏幕适配工具

提供屏幕尺寸相关的静态属性:

import { Screen } from 'kunpocc';

// 获取屏幕信息
console.log('屏幕宽度:', Screen.ScreenWidth);
console.log('屏幕高度:', Screen.ScreenHeight);
console.log('设计分辨率:', Screen.DesignWidth, Screen.DesignHeight);
console.log('安全区域:', Screen.SafeWidth, Screen.SafeHeight);

5. 热更新功能

提供热更新的基础功能:

import { HotUpdateManager } from 'kunpocc';

// 需要先获取实例并初始化
const hotUpdate = HotUpdateManager.getInstance();

// 检查更新
hotUpdate.checkUpdate().then(result => {
    if (result.code === HotUpdateCode.CHECK_FOUND_UPDATE) {
        console.log('发现新版本');
        // 可以开始更新流程
    }
});

6. 条件显示节点

用于UI红点等条件显示功能,需要配合装饰器使用:

import { _conditionDecorator, ConditionManager } from 'kunpocc';

// 条件系统需要先初始化
ConditionManager.initCondition();

// 条件系统主要通过装饰器和条件类来管理UI节点的显示状态
// 具体使用方式需要定义条件类并配合UI节点

项目结构

src/
├── cocos/          # Cocos Creator适配层
├── condition/      # 条件显示模块
├── fgui/          # FairyGUI相关
├── global/        # 全局工具
├── hotupdate/     # 热更新
├── minigame/      # 小游戏平台
├── tool/          # 工具函数
└── ui/            # UI管理核心

安装使用

npm install kunpocc

详细的使用文档和示例代码可以在项目的docs目录中找到。

配套工具

框架还提供了一些配套的开发工具:

kunpo-fgui插件: Cocos Creator插件,可以一键导出FairyGUI界面配置,减少手写代码量。

独立模块

开源信息

项目特点

这个框架的设计原则是实用性优先。每个功能都是在实际项目中遇到问题后,总结出来的解决方案。代码结构清晰,文档相对完整,适合中小型游戏项目使用。

框架还在持续优化中,会根据实际使用中遇到的问题不断改进。如果你也在使用Cocos Creator开发游戏,欢迎试试这个框架,也欢迎提出改进建议。


这个项目主要是为了解决我在游戏开发中遇到的实际问题。如果对其他Cocos Creator开发者也有帮助,那就更好了。

批量打包工具

批量打包工具:解决多平台发布的重复劳动

它解决什么问题

如果你用Cocos Creator开发游戏,要发布到多个平台,你就知道有多痛苦了。

每次更新版本,需要:

  • iOS包:Creator构建 → 修改版本号 → Xcode打包 → 上传TestFlight
  • Android包:Creator构建 → 生成热更新文件 → 修改版本号 → 签名打包 → 上传分发
  • 微信小游戏:Creator构建 → 上传CDN资源 → 上传小游戏包 → 设置体验版
  • 支付宝小游戏:Creator构建 → 上传CDN资源 → 上传小游戏包 → 设置体验版
  • 抖音小游戏:Creator构建 → 上传CDN资源 → 上传小游戏包 → 设置体验版
  • 鸿蒙包:Creator构建 → 生成热更新文件 → 修改版本号 → DevEco打包

一个游戏6个平台,每个平台5-8步操作,手动操作一遍要1-2小时,而且容易出错。

这个工具就是为了把这些重复劳动自动化,一个命令搞定所有平台的打包发布

核心功能

支持平台

  • 原生平台: Android、iOS、鸿蒙
  • 小游戏平台: 微信、支付宝、抖音
  • 多渠道: TapTap、小米、4399等Android渠道

自动化流程

原生平台打包:

Creator构建 → 生成热更新manifest → 修改版本号/build号 → 平台打包 → 上传CDN → 飞书通知

小游戏打包:

Creator构建 → 上传远程资源到CDN → 上传小游戏后台 → 设置体验版 → 飞书通知+二维码

热更新发布:

Creator构建 → 生成新manifest文件 → 上传更新资源到CDN → 飞书通知

快速开始

1. 安装依赖

cd BuildTools
npm install

2. 配置文件

修改config.json,主要配置:

{
  "creator": "/Applications/Cocos/Creator/3.8.6/CocosCreator.app/Contents/MacOS/CocosCreator",
  "project": "/Users/your-name/YourGame",
  "channels": [
    {
      "channel": "wechatgame",
      "name": "微信小游戏", 
      "platform": "wechatgame",
      "config": "./local/buildConfig_wechatgame.json"
    }
  ],
  "platforms": [
    {
      "platform": "android",
      "native": "./native/engine/android/app",
      "build": "./build/android/proj"
    }
  ]
}

3. 环境变量

# 阿里云OSS(用于CDN上传)
export OSS_ACCESS_KEY_ID="your-key-id"
export OSS_ACCESS_KEY_SECRET="your-key-secret"
export OSS_URL="your-oss-url"
export OSS_REGION="oss-cn-hangzhou"
export OSS_BUCKET="your-bucket"

# 飞书通知机器人
export FEISHU_ROBOT_WEBHOOK="your-webhook-url"

# Android打包工具
export APKSIGNER="/path/to/sdk/build-tools/30.0.3/apksigner"

4. 使用方式

交互式打包:

node BuildCommand.js
# 选择平台、输入版本号、选择debug/release

命令行打包:

# 打包微信小游戏 v1.2.0 release版
node BuildJenkins.js -p wechatgame -v 1.2.0 -b 1 -d false -n true

# 热更新 Android v1.2.1
node HotUpdateJenkins.js -p android -v 1.2.1 -hot 1001 -d false -n true

集成Jenkins:

// Jenkins Pipeline 示例
pipeline {
    agent any
    parameters {
        choice(name: 'PLATFORM', choices: ['wechatgame', 'android', 'harmonyos-next'], description: '选择平台')
        string(name: 'VERSION', defaultValue: '1.0.0', description: '版本号')
        booleanParam(name: 'IS_DEBUG', defaultValue: false, description: '是否Debug版本')
    }
    
    stages {
        stage('Build Game') {
            steps {
                script {
                    sh """
                        cd BuildTools
                        node BuildJenkins.js -p ${params.PLATFORM} -v ${params.VERSION} -b ${env.BUILD_NUMBER} -d ${params.IS_DEBUG} -n true
                    """
                }
            }
        }
    }
    
    post {
        success {
            echo "构建成功: ${params.PLATFORM} v${params.VERSION}"
        }
        failure {
            echo "构建失败"
        }
    }
}

技术特点

配置化驱动: 通过JSON配置文件管理所有平台参数,不需要改代码。

模块化设计: 每个平台一个独立模块,添加新平台只需实现对应接口。

完整的构建链: 从Creator构建到最终发布的完整自动化。

错误处理: 每步操作都有结果检查,构建失败会及时停止并通知。

通知集成: 自动发送飞书通知,包含版本信息、下载链接、二维码。

二次开发指南

添加新平台

  1. 创建平台模块
    // platforms/YourPlatform.js
    class BuildYourPlatform {
     static async build(config, channel, version, buildCode, isDebug) {
         // 实现平台特定的构建逻辑
         return Result.success();
     }
    }
    
  2. 注册到主流程
    // AutoBuild.js
    this._platformFlowBindFuncs = {
     ['your-platform']: this.buildYourPlatformFlow,
     // ... 其他平台
    }
    
  3. 添加配置
    {
      "channels": [
     {
       "channel": "your-channel",
       "name": "Your Platform",
       "platform": "your-platform", 
       "config": "./local/buildConfig_your-platform.json"
     }
      ]
    }
    

自定义构建步骤

继承基础构建类,重写需要的方法:

class CustomAndroidBuild extends BuildAndroid {
    static async beforeBuild() {
        // 构建前的自定义操作
        await super.beforeBuild();
        // 你的自定义逻辑
    }
    
    static async afterBuild() {
        // 构建后的自定义操作  
        await super.afterBuild();
        // 你的自定义逻辑
    }
}

扩展通知方式

添加新的通知渠道:

// notifications/YourNotification.js
class YourNotification {
    static async send(title, content, isDebug) {
        // 实现通知逻辑
    }
}

核心模块说明

  • AutoBuild.js: 主控制器,协调各模块
  • BuildCreator3.8.js: Creator构建封装
  • platforms/: 各平台构建实现
  • utils/: 通用工具类(命令执行、文件操作、结果处理)
  • oss/: CDN上传模块
  • NotificationFeishu/: 飞书通知模块

开发建议

遵循现有模式: 每个平台模块都返回Result对象,统一错误处理。

配置优先: 尽量通过配置文件控制行为,减少硬编码。

详细日志: 使用Colors.js输出带颜色的日志,方便调试。

异常处理: 每个异步操作都要try-catch,构建失败要有明确提示。

适用场景

  • Cocos Creator游戏多平台发布
  • 需要频繁更新版本的项目
  • 有多个Android渠道的游戏
  • 团队协作需要标准化构建流程的项目
  • Jenkins集成自动化发布

如果你也被多平台打包折磨,不妨试试。

开源项目集合

游戏开发工具集合

这是我在游戏开发中积累的一系列常用工具和框架,主要基于 Cocos Creator 开发。这些工具涵盖了从基础框架到具体功能模块的各个方面,旨在帮助开发者快速构建高质量的游戏项目。

感兴趣的可以看看,喜欢的话可以给个小星星

完整工具列表

1. kunpocc 游戏框架

一个专为 Cocos Creator 开发的游戏框架,提供了一套完整的游戏开发工具和模块。基于 FairyGUI 的强大UI管理系统,支持装饰器语法和多窗口管理,包含全局计时器、平台工具、屏幕尺寸适配、小游戏接口封装等功能。

GitHub: https://github.com/gongxh0901/kunpolibrary
Gitee: https://gitee.com/gongxh0901/kunpolibrary

2. ecs 框架

一个高性能实体组件系统 (Entity-Component-System) 框架,专为游戏开发和大规模实时模拟设计。使用稀疏集合 + 密集数组的数据结构,提供优秀的频繁添加删除性能和掩码高效匹配的快速查询系统。

GitHub: https://github.com/gongxh0901/kunpo-esc
Gitee: https://gitee.com/gongxh0901/kunpo-ecs

3. EC框架

一个轻量级的实体组件(Entity-Component)框架,相比完整ECS架构更加简单易用。专为小型到中型游戏项目设计,提供了基础的实体管理和组件系统,适合快速原型开发和简单的游戏逻辑实现。

GitHub: https://github.com/gongxh0901/kunpo-ec
Gitee: https://gitee.com/gongxh0901/kunpocc-ec

4. 四叉树

一个高效的四叉树空间数据结构实现,主要用于2D空间的快速分割和查询。在游戏开发中广泛应用于碰撞检测、空间查询、可视区域剔除等场景,能够显著提升大量对象的空间检索性能。

GitHub: https://github.com/gongxh0901/kunpo-quadtree
Gitee: https://gitee.com/gongxh0901/kunpocc-quadtree

5. 网络库(Http 和 WebSocket)

一个跨平台的网络通信库,封装了Http请求和WebSocket连接功能。抹平了小游戏平台和原生平台的使用差异,提供统一的API接口。支持完整的Http请求方法、多种响应类型处理、自定义请求头和超时控制,以及标准的WebSocket通信功能。

GitHub: https://github.com/gongxh0901/kunpocc-net
Gitee: https://gitee.com/gongxh0901/kunpocc-net

6. 事件系统

一个使用TypeScript编写的轻量级事件系统,不依赖任何游戏引擎。提供了完整的事件管理功能,包括事件的添加、移除、发送、批量移除等操作。适用于需要解耦模块间通信的各种项目,为应用程序提供灵活的消息传递机制。

GitHub: https://github.com/gongxh0901/kunpocc-event
Gitee: https://gitee.com/gongxh0901/kunpocc-event

7. 资源管理

一个智能的游戏资源管理库,提供资源加载、缓存和释放的完整解决方案。支持通过路径或UUID获取资源,具备防重复加载机制,可通过批次名称实现批量资源管理。支持多种资源类型和bundle配置,提供并行加载、失败重试、进度回调等功能,有效管理游戏运行时的内存占用。

GitHub: https://github.com/gongxh0901/kunpocc-assets
Gitee: https://gitee.com/gongxh0901/kunpo-assets

8. 行为树

一个强大的AI决策系统,用于实现复杂的游戏AI行为。支持多种节点类型(动作、组合、条件、装饰),提供完整的状态管理(成功、失败、运行中)。具备黑板数据共享机制、记忆节点功能和并行执行能力,帮助开发者构建灵活、高效的AI逻辑系统。

GitHub: https://github.com/gongxh0901/kunpocc-behaviortree
Gitee: https://gitee.com/gongxh0901/behaviortree

9. 打包工具

一个基于Cocos Creator项目的全自动化打包工具,支持多平台多渠道的一键构建和发布。覆盖iOS、Android、鸿蒙、微信小游戏、抖音小游戏、支付宝小游戏等平台。集成了自动版本管理、热更新生成、CDN资源上传、包体签名、平台发布和飞书通知等完整流程,可与Jenkins等CI/CD系统无缝集成。

GitHub: https://github.com/gongxh0901/creator-build-tools
Gitee: https://gitee.com/gongxh0901/creator-build-tools

贡献指南

欢迎社区贡献:

  1. 问题反馈: 通过 GitHub Issues 报告 bug 或提出建议
  2. 代码贡献: 提交 Pull Request 改进代码
  3. 文档完善: 帮助完善文档和示例
  4. 功能建议: 提出新功能需求

这套工具集合致力于为 Cocos Creator 开发者提供高效、易用的游戏开发解决方案。无论是独立开发者还是团队项目,都能为您的游戏开发之旅提供强有力的支持。

项目持续优化中,敬请期待更多功能和改进!

Cocos Creator开发者 & 技术分享者

十年游戏开发沉淀,专注技术传承与创新

👨‍💻 个人简介

你好,我是gongxh。拥有10+年一线游戏开发经验的技术从业者,专注于Cocos Creator游戏开发领域。从传统PC游戏到移动端H5小游戏,见证并参与了游戏行业的技术变迁。

作为累计流水过亿游戏项目的核心开发者,我不仅在技术实现上追求卓越,更致力于通过分享经验帮助开发者社区共同成长。我推崇《代码整洁之道》,在实践中不断重构和改善既有设计,始终追求代码的整洁、高效与可维护性。

💡 开发理念

🚀 追求效率:能自动,不手动

开发者的精力应该聚焦于创造性的问题解决,而非机械的重复劳动。我热衷于在工作中寻找并实现自动化,无论是编写辅助开发的小工具,还是构建完整的自动化脚本,目标始终是提升效率、减少人为错误。

🎯 追求卓越:代码是写给未来的

好的软件架构是逐步演进的。在项目中,我习惯于识别和沉淀那些通用的基础模块,为未来的开发奠定基础。这源于对”让营地比你来时更干净”这一信条的坚持,通过持续的代码重构来改善既有设计。

🛠 技术专长

编程语言

  • Lua
  • JavaScript/TypeScript
  • C/C++
  • Python
  • Objective-C

游戏引擎 & 框架

  • Cocos Creator 2.x/3.x - 全栈开发经验,深度掌握
  • Cocos2d-x - 原生开发经验

核心技术 & 专长

  • 🎮 游戏架构设计 - ECS系统、模块化设计
  • 📊 数据管理系统 - 高效的数据流管理
  • 🎨 UI系统设计 - 灵活可扩展的界面框架
  • 性能优化 - Draw Call优化、内存管理
  • 🔧 自动化工具链 - Python脚本、Jenkins集成
  • 🤖 AI系统开发 - 行为树、状态机设计

平台发布经验

  • 微信小游戏 - 深度开发与性能优化
  • 多端小游戏 - 抖音、支付宝、华为快游戏
  • 移动原生 - iOS/Android平台SDK接入
  • 鸿蒙平台 - 新兴平台适配经验

🎮 代表项目

🏆 宫爆:老奶奶家族篇

流水过亿的移动平台休闲射击游戏,知名IP续作

作为项目技术支柱,独立完成整个客户端架构设计与实现:

  • 架构设计:从零搭建ECS架构、数据管理、网络通信系统
  • 核心玩法:实现碰撞系统、怪物AI行为树、技能系统
  • 开发工具:为团队打造实体编辑器和UI编辑器
  • 平台适配:负责所有平台SDK接入与维护
  • 自动化:编写自动化打包脚本,集成Jenkins实现CI/CD

🎯 比特小队

TapTap 9.4高分的Roguelike射击游戏

作为项目初期核心开发者,奠定了坚实的技术基础:

  • 框架搭建:主导整体架构设计,引入ECS系统
  • 随机生成:独立设计XML配置驱动的随机地图生成系统
  • 性能优化:通过Draw Call优化和代码重构提升运行效率
  • 核心功能:负责碰撞检测、角色技能、机关逻辑实现

🥊 快打世界

微信小游戏平台的线上匹配PK对战游戏

探索微信小游戏平台技术边界的试水项目:

  • 换装系统:使用Spine技术实现高度灵活的角色换装
  • UI框架:搭建支撑整个游戏的UI系统
  • 平台优化:针对微信小游戏进行启动性能优化
  • 技术探索:为团队积累宝贵的小游戏平台经验

🎲 其他项目

  • 挖穿地心:资源循环驱动的休闲挖掘游戏,探索深度玩法设计
  • 暴力学园:局域网联机跑酷对战游戏,融合竞速与策略元素,使用Tiled Map构建地形
  • 不太聪明祖玛:创新混合玩法,结合祖玛消除与动物园经营的独特体验

📚 分享内容

技术教程

  • ECS架构设计与实践经验
  • 性能优化实战技巧与案例
  • 多平台发布完整流程

开发工具

  • 编辑器插件开发教程
  • 自动化构建脚本分享
  • 调试辅助工具制作
  • 工作流优化方案

项目实战

  • 完整项目架构设计思路
  • 大型项目性能优化案例
  • 团队协作与项目管理经验
  • 从0到1的产品开发全流程

🤝 分享理念

“独行快,众行远。技术的价值在于分享与传承。”

通过分享经验可以:

  • 💡 启发思路 - 提供不同维度的解决方案
  • 提升效率 - 传授开发工具和最佳实践
  • 🛡️ 避免踩坑 - 分享实战中的经验教训
  • 🚀 共同成长 - 与开发者社区携手进步

📞 联系交流

欢迎与我交流Cocos Creator开发、项目架构设计相关的任何问题:

联系方式见本站底部 (添加微信时请注明”技术交流”)

交流方向

  • 🤝 技术问题讨论与解决方案
  • 💼 项目合作与技术咨询
  • 📝 技术文章交流与投稿
  • 🎯 职业发展与成长建议
  • 🛠️ 工具开发与分享

工作履历

  • 青岛蓝飞互娱科技股份有限公司 - 研发 (2015/04 - 至今)
  • 合肥丸巨网络科技有限公司 - 研发 (2013/11 - 2015/04)

“每一次分享都是双赢,每一行代码都是未来的基石。期待与你的技术交流!”