feat(软著): 新增软著登记全套文档与资源整理

1. 新增软著登记所需的源程序生成脚本、docx生成脚本与依赖配置
2. 新增像素大勇者游戏软件V1.0设计说明书与填表指引文档
3. 更新技能配置相关的prefab与meta文件,清理冗余的up状态预制件
4. 修复部分技能buff的颜色与精灵帧引用,更新动画资源引用
5. 新增两个技能图标资源文件
This commit is contained in:
panFD
2026-09-14 20:46:31 +08:00
parent f2a4926c49
commit 2dc44b2393
35 changed files with 15108 additions and 8189 deletions

View File

@@ -0,0 +1,111 @@
/**
* 软著源程序文档生成脚本
* 规则:每页 60 行有效代码;超过 60 页时取前 30 页 + 后 30 页;
* 自动清理文件头第三方署名/版权行;排除声明文件与空文件。
* 用法:node docs/软著/gen_source_doc.mjs
*/
import fs from 'fs';
import path from 'path';
const ROOT = path.resolve(import.meta.dirname, '../../assets/script');
const OUT_DIR = import.meta.dirname;
const OUT = path.join(OUT_DIR, '像素大勇者游戏软件_V1.0_源程序.txt');
const LINES_PER_PAGE = 60;
const KEEP = 30; // 前 30 页 + 后 30 页
const SOFTWARE = '像素大勇者游戏软件 V1.0';
/** 需要从文件头清除的第三方署名 / 编辑器元数据行 */
const BAD_PATTERNS = [
/dgflash/i,
/落日故人/,
/QQ\s*\d+/,
/Copyright \(c\)/i,
/@(Author|LastEditors?|Date|LastEditTime)/i,
];
function walk(dir) {
const out = [];
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const p = path.join(dir, e.name);
if (e.isDirectory()) out.push(...walk(p));
else out.push(p);
}
return out;
}
const rel = (f) => path.relative(ROOT, f).replace(/\\/g, '/');
// 1. 收集源文件:仅 .ts,排除 .d.ts 声明文件、空文件、非脚本目录
let files = walk(ROOT).filter(
(f) =>
f.endsWith('.ts') &&
!f.endsWith('.d.ts') &&
!rel(f).includes('hit-flash-white/shaders') &&
fs.readFileSync(f, 'utf8').trim().length > 0
);
// 2. 排序:入口 Main.ts 优先,其次初始化模块,其余按路径字母序
files.sort((a, b) => {
const rank = (r) =>
r === 'Main.ts' ? 0 : r.startsWith('game/initialize') ? 1 : 2;
return rank(rel(a)) - rank(rel(b)) || rel(a).localeCompare(rel(b));
});
// 3. 清理文件头(前 40 行)中的第三方署名行,统一换行符与缩进
function cleanFile(content) {
const lines = content
.replace(/\r\n/g, '\n')
.replace(/\t/g, ' ')
.split('\n');
const head = lines.slice(0, 40).filter(
(l) => !BAD_PATTERNS.some((rx) => rx.test(l))
);
return [...head, ...lines.slice(40)];
}
const all = [];
for (const f of files) {
all.push(`// ===================== 文件: ${rel(f)} =====================`);
all.push(...cleanFile(fs.readFileSync(f, 'utf8')));
}
// 4. 统计(审校用)
const total = all.length;
const blank = all.filter((l) => l.trim() === '').length;
const comment = all.filter((l) => /^\s*(\/\/|\/\*|\*|\*\/)/.test(l)).length;
const tooLong = all.filter((l) => l.length > 84).length;
const totalPages = Math.ceil(total / LINES_PER_PAGE);
// 5. 分页:超过 60 页取前 30 + 后 30
const pageIdx =
totalPages > 60
? [
...Array.from({ length: KEEP }, (_, i) => i),
...Array.from({ length: KEEP }, (_, i) => totalPages - KEEP + i),
]
: Array.from({ length: totalPages }, (_, i) => i);
const submitPages = pageIdx.length;
// 6. 生成文档(页眉:左侧软件全称+版本号,右侧页码)
const out = [];
for (const pi of pageIdx) {
const pageNo = pageIdx.indexOf(pi) + 1;
const start = pi * LINES_PER_PAGE;
const body = all.slice(start, start + LINES_PER_PAGE);
out.push(`${SOFTWARE}            第 ${pageNo} 页 共 ${submitPages} 页`);
out.push('='.repeat(76));
out.push(...body);
out.push('');
}
fs.mkdirSync(OUT_DIR, { recursive: true });
fs.writeFileSync(OUT, out.join('\n'), 'utf8');
console.log('=== 源程序文档生成完成 ===');
console.log(`文件数: ${files.length}`);
console.log(`总行数: ${total}(含文件分隔行)`);
console.log(`总页数: ${totalPages},提交页数: ${submitPages}`);
console.log(`空行占比: ${((blank / total) * 100).toFixed(1)}%`);
console.log(`注释行占比: ${((comment / total) * 100).toFixed(1)}%`);
console.log(`超 84 字符行数: ${tooLong}`);
console.log(`输出: ${OUT}`);