一套 Cocos 旧工程的资源、代码、协议应该怎么系统化梳理
资源、代码、协议三块都梳一遍后,建议你整理一份简单的“工程说明”,哪怕很简陋也没关系,内容大概包括:目录结构说明(哪些目录是核心)资源说明(图集、配置、音效大概怎么分类)启动流程(从 main.js 到第一个场景)网络流程(连接 → 登录 → 心跳 → 收发)协议总表位置(xlsx / markdown)这份文件是给未来的你看的,半年后再打开工程,你起码还能很快接上手,不用重新挖一遍历史。
旧工程最麻烦的地方是:
东西都在,但没人记得“为什么这样写”“哪里还在用”。
想接着开发或者二开,第一步就是把它系统化梳理一遍。
下面我按三个部分来讲:
1)资源怎么梳
2)代码怎么梳
3)协议怎么梳
中间会加一些我自己常用的小脚本和思路。

一、先梳理资源:目录、引用关系、冗余
1. 先搞清楚资源目录的“真实结构”
一般旧的 Cocos 工程资源目录大概这样:
res/
ui/
font/
audio/
anim/
particles/
config/
但实际情况是:
-
有些目录已经废弃
-
有些资源被移走但引用没改
-
有些是早期测试残留
我建议第一步做的很简单:
把资源目录完整列一遍,并输出到一个文件里,后面好对比。
用个简单脚本:
# 把资源文件列出来存到 res_list.txt
find ./res -type f > res_list.txt
或者用 Python:
import os
with open("res_list.txt", "w", encoding="utf-8") as f:
for root, dirs, files in os.walk("./res"):
for name in files:
path = os.path.join(root, name)
f.write(path.replace("\\", "/") + "\n")
这一步听起来很简单,但后面排查“资源没用到”“引用路径错误”的时候非常有用。
2. 查资源是否真的被代码引用
旧工程常见问题:
-
资源很多,但真正用到的只有一部分
-
有些 UI 图是旧版本遗留
-
plist、json、音效等可能已经没人用
做法很直接:
一边扫描代码里的字符串引用,一边对比 res_list。
比如在 Cocos2d-js 里,资源引用很常见:
cc.spriteFrameCache.addSpriteFrames("res/ui/main_ui.plist");
cc.textureCache.addImage("res/bg/login_bg.png");
cc.audioEngine.playEffect("res/sound/click.mp3");
可以写个粗暴一点的脚本,把代码里的字符串全抓出来,对比是否存在对应文件。
示意脚本(简化版):
import os, re
code_paths = ["./src", "./res"] # 代码可能散在 src / res/config 里
res_files = set()
# 统计资源文件
for root, dirs, files in os.walk("./res"):
for name in files:
res_files.add(os.path.join(root, name).replace("\\", "/"))
# 简单抓字符串(只做演示)
pattern = re.compile(r'"(res/[^"]+)"')
used_res = set()
for base in code_paths:
for root, dirs, files in os.walk(base):
for name in files:
if not name.endswith((".js", ".json", ".plist", ".csd")):
continue
path = os.path.join(root, name)
with open(path, "r", encoding="utf-8", errors="ignore") as f:
text = f.read()
for m in pattern.finditer(text):
used_res.add(m.group(1))
unused_res = res_files - used_res
with open("unused_res.txt", "w", encoding="utf-8") as f:
for p in sorted(unused_res):
f.write(p + "\n")
作用就是:
-
先统计所有 res 下的文件
-
再从代码里抓出所有
"res/xxx"的引用 -
做个集合差集,得到**“疑似未使用资源列表”**
当然不是 100% 准(比如资源名拼接、通过表配置),
但能帮你找出一大批明显没用的东西。
3. 资源命名和分类顺手整理一下
既然已经在梳理了,可以顺带做两件事:
-
调整目录结构(不改名的前提下先理清层级)
-
ui 按模块拆:
ui/login/、ui/hall/、ui/room/ -
配置单独一个目录:
res/config/ -
公共资源单独放:
res/common/
-
-
梳理图集与散图的关系
看哪些 png 应该打到 plist 里,哪些散图其实已经在图集中重复了。
这一步做完,你对“资源这一块究竟有多乱”心里就有数了。
二、梳理代码:入口、模块、依赖关系
旧 Cocos 工程最普遍的问题:结构不清晰。
1. 先找到项目真正的“入口链路”
一般 Cocos2d-js 工程入口大致是:
-
main.js -
project.json/settings.js -
AppDelegate.cpp(原生端)
你先看 main.js 里干了什么:
cc.game.onStart = function(){
cc.view.adjustViewPort(true);
cc.view.setDesignResolutionSize(1136, 640, cc.ResolutionPolicy.SHOW_ALL);
cc.view.resizeWithBrowserSize(true);
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new LoginScene());
}, this);
};
cc.game.run();
从这里你就能顺着找下去:
-
第一个 scene 是谁
-
UI 层级是怎么搭的
-
Manager 之类的全局单例在哪里初始化
梳代码的顺序建议是:入口 → 全局管理类 → 核心逻辑模块
比如常见的几类:
-
XXXManager.js(UserManager、NetManager、UIManager…) -
XXXScene.js(LoginScene、HallScene、GameScene…) -
XXXLayer.js(各种界面层) -
config/XXXConfig.js(配置类)
先做一张简单的“调用关系草图”就行,不用太精美:
main.js
└── LoginScene
├── UI_LoginLayer
├── NetManager.login()
└── ConfigManager.load()
这玩意儿画在纸上也行,关键是你要能一眼说出来:
“项目启动的完整流程是:加载资源 → 初始化配置 → 连接服务器 → 进大厅”。
2. 用简单工具看一下“代码引用图谱”
如果工程很大,单靠肉眼看会很痛苦。
我通常会至少做两件小事:
-
统计一下 src 目录下代码行数、文件分布
find ./src -name "*.js" | xargs wc -l > code_stat.txt
你能一眼看到:
-
哪些文件超大(几千行那种)
-
哪个目录最大(重点模块在哪)
-
简单搜关键字看耦合情况
比如你怀疑 NetManager 到处被直接调用,可以 grep 一下:
grep -R "NetManager" ./src > net_ref.txt
多看几个典型 Manager 的引用次数,你就大概知道这套工程写得“散不散”。
3. 找出“配置驱动”的部分,和“写死”的部分
旧项目一般会有一堆这样的配置文件:
-
res/config/*.json -
res/config/*.plist -
res/config/*.csv(可能导出来的)
核心问题是:
哪些逻辑是被这些配置驱动的,哪些是直接写死在 JS 里的。
做法也不复杂:
-
搜某个配置 key 在代码里出现多少次
-
看 UI/玩法/功能是跟配置绑定还是写死
举个例子(示意):
// 配置驱动
var conf = GlobalConfig.get("room_list");
for (var i = 0; i < conf.length; i++) {
this.addRoomItem(conf[i]);
}
// 写死
this.addRoomItem({id: 1, name: "初级场"});
this.addRoomItem({id: 2, name: "中级场"});
this.addRoomItem({id: 3, name: "高级场"});
如果你后面要做二开重构,这个阶段顺便做个标记:
-
哪些地方是“可配置”的
-
哪些是“写死不易改”的
三、梳理协议:消息 ID、结构、收发流程
很多人对旧工程最头疼的其实是协议,尤其是:
-
文档不全
-
服务端有人改过
-
前端只是照着抄
1. 先把“协议相关的所有文件”搜出来
一般协议涉及几个地方:
-
协议常量定义(cmd、msgId)
-
消息结构(protobuf / json)
-
实际收发代码(NetManager / SocketManager)
你可以先搜一下几个关键词:
grep -R "send" ./src/Net* ./src/*Net* > send_log.txt
grep -R "onMessage" ./src/Net* ./src/*Net* > recv_log.txt
grep -R "CMD_" ./src > cmd_log.txt
grep -R "msgId" ./src > msgid_log.txt
目的就是先粗略把“和网络相关的代码”集中出来,方便统一看。
2. 建一个简单的“协议总表”
哪怕是旧工程,我也建议你建一个自己的协议表,就一个 xlsx / markdown 都可以,比如:
| CMD / MsgId | 方向(C2S/S2C) | 功能模块 | 数据结构说明 | 备注 |
|---|---|---|---|---|
| 1001 | C2S | 登录 | account, token | 登录请求 |
| 1002 | S2C | 登录 | result, userInfo | 登录返回 |
| 2001 | C2S | 心跳 | timestamp | ping |
| 2002 | S2C | 心跳 | timestamp | pong |
然后你在看代码时,顺手往里补。
比如某个地方看到:
NetManager.send(1001, {
account: acc,
token: tk
});
你就往表里登记一条。
这件事看起来有点“体力活”,但后面你会很感谢当时的自己。
3. 看清楚“封包 / 解包流程”
老工程一般都会有一层网络封装,比如:
NetManager.send = function(cmd, body){
var buf = Packet.encode(cmd, body);
socket.send(buf);
};
socket.onmessage = function(event){
var data = event.data;
var msg = Packet.decode(data);
NetManager.dispatch(msg.cmd, msg.body);
};
你需要重点搞清楚几个点:
-
包头结构:
-
cmd 占几个字节
-
length 怎么算
-
是否有序列号 / 校验位
-
-
包体结构:
-
是 json / protobuf / 自定义二进制
-
有没压缩 / 加密
-
-
心跳机制:
-
心跳间隔
-
超时重连策略
-
简单示例(仅示意):
Packet.encode = function(cmd, body){
var bodyStr = JSON.stringify(body);
var bodyBuf = stringToUtf8(bodyStr);
var totalLen = 4 + bodyBuf.length;
var buf = new Uint8Array(totalLen);
buf[0] = (cmd >> 8) & 0xff;
buf[1] = cmd & 0xff;
buf[2] = (bodyBuf.length >> 8) & 0xff;
buf[3] = bodyBuf.length & 0xff;
buf.set(bodyBuf, 4);
return buf;
};
把这部分看明白之后,协议层基本就算摸清了。
4. 和服务端对一下,看看有没有“私自修改过”
很多旧项目的真实情况是:
服务端后来被人改过,但前端工程还是旧的。
典型症状:
-
登录报错,但前端看不出原因
-
某些消息收不到返回
-
某些 cmd 改了业务含义
这里建议你做两件事:
-
抓一份真实线上数据(如果条件允许)
用 tcpdump / wireshark / 或服务端日志,抓一下真实包头、包体格式。 -
写一个小测试客户端,只跑“网络 → 协议”这一块
不带 UI,单纯连上去发登录 / 心跳 / 几个典型请求,看返回结构。
这样你至少可以确认:
“现在跑的这套前端协议定义,到底和服务端对不对得上。”
四、最后做一份自己的“工程地图”
资源、代码、协议三块都梳一遍后,建议你整理一份简单的“工程说明”,哪怕很简陋也没关系,内容大概包括:
-
目录结构说明(哪些目录是核心)
-
资源说明(图集、配置、音效大概怎么分类)
-
启动流程(从 main.js 到第一个场景)
-
网络流程(连接 → 登录 → 心跳 → 收发)
-
协议总表位置(xlsx / markdown)
这份文件是给未来的你看的,半年后再打开工程,你起码还能很快接上手,不用重新挖一遍历史。
更多推荐



所有评论(0)