首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >致谢我们(我与LLM)的第一个颗星星:从一张战役地图到一个会自己长经验的战争动画实验室

致谢我们(我与LLM)的第一个颗星星:从一张战役地图到一个会自己长经验的战争动画实验室

作者头像
用户6900693
发布2026-07-10 19:00:39
发布2026-07-10 19:00:39
50
举报

WAR ANIMATION LAB OSS

致谢我们(我与LLM)的第一个颗星星(GitHub):从一张战役地图到一个会自己长经验的战争动画实验室

从第一次出门,到第一颗星星;从一张战役地图,到一套会沉淀经验的动画制作方法。

项目地址:https://github.com/fuxiaoyan1/war-animation-library

在线演示:https://fuxiaoyan1.github.io/war-animation-library/

图 1|战争动画藏书馆首页:目前项目已经把 21 部战争动画放进同一个入口,按拿破仑时代前后分成“古代战争”和“现代战争”。

SECTION 01

01 / 这次更新,不是“又加了几张地图”

前几天第一次把 war-animation-library 放出来时,它更像一个刚开门的小作坊:有货架,有一些作品,也有一套还在打磨的制作方法。

这几天继续往前走了一步。

现在它已经不是“给历史战役画几条箭头”的小网页,而更接近一个小型的战争动画实验室:资料先进入文档,战役被拆成事件、路线、编队、镜头、音效和验证规则,然后由同一个 React/Vite 渲染器播放成一部大约五分钟的互动短片。

截至这次检查,仓库 HEAD 是 ce7f874,README 中列出的当前动画数量是 21 部。代码结构里有 21 个数据文件、24 个组件文件、24 份 sources 文档、62 个单位图标资源和 19 个音频资源。它仍然很小,但已经有一点“生产线”的样子了。

这件事有意思的地方在于:一个战役动画做得好不好,最后不是看它是不是炫,而是看它有没有把战场逻辑讲清楚。

舰队为什么从这里转向?

飞机为什么不能一直悬停在伦敦上空?

一个标注为什么不能提前出现?

炮声、爆炸声和机枪声为什么必须卡在事件窗口里?

这些问题听起来像视觉细节,其实都是叙事纪律。

图 2|项目生产链:资料、数据、渲染、验证四层一起工作,才可能把“历史资料”变成“可观看、可复盘、可测试”的动画。

SECTION 02

02 / 当前货架:21 部动画,真正变化在海战和空战

这次最明显的变化,是海战和空战开始有了自己的运动语法。

首页现在能看到这些作品:亚历山大、布匿战争、大秦统一、垓下、凯撒、十字军、蒙古帝国;拿破仑、特拉法尔加、对马、日德兰、1940 德法战役、伦敦上空的鹰、苏德战争、太平洋战争、中途岛、俾斯麦海、第二次瓜岛海战、大周行动、抗美援朝和海湾战争。

但数量不是重点。

真正值得说的是:海战不再只是“船从 A 点到 B 点”,空战也不再是“飞机像陆军一样常驻地图”。

特拉法尔加开始表现风帆时代两纵队突破;日德兰开始强调侦察接触、南向追逐、北向引诱、主力展开、T 字横切、Scheer 全舰队转向和夜间撤离;瓜岛夜战加入雷达火控和关键射击位延迟揭示;俾斯麦海则把船队航线、侦察、高空轰炸、低空扫射、跳弹轰炸和船队瓦解放在同一个时间窗口里。

空战部分也在被重写。伦敦上空的鹰不再铺开整个不列颠空战,而是聚焦 1940 年 9 月 15 日伦敦方向的两次昼间大空袭;大周行动把轰炸机流、护航战斗机、德军截击机和受损返航放进短时波次;俾斯麦海的盟军飞机则要出击、攻击、追击、返航,不能打完就凭空消失。

图 3|日德兰海战:侦察舰接触只是开场,真正的看点是主力舰队如何逐段接近、展开、转向和撤离。

图 4|伦敦上空的鹰:动画聚焦 1940 年 9 月 15 日,雷达预警、11 群升空、12 群增援、伦敦上空混战和返航追击被拆成短时空中波次。

SECTION 03

03 / 为什么海战和空战不能共用一套箭头

战争动画最容易偷懒的地方,是把所有东西都变成“路线”。

陆军推进是一条线,舰队航行是一条线,飞机出击也是一条线。表面上都能播放,实际上很快就会露馅。

海战的关键是连续性。舰队一旦出现,除非战损、沉没、失能或历史上脱离战场,否则不能突然消失。航迹线最好保留,因为观众需要复盘 T 字横切、折返、追击和夜间脱离。舰船还不能从港口中心开出来直接穿陆,哪怕中心点在海上,图标边缘压到陆地也会破坏可信度。

空战则完全相反。飞机不是长期驻留单位,它们应该是短时出击波次:起飞、接触、护航、截击、轰炸、追击、返航。飞机图标可以退场,但航迹要留下来,让观众看到这一天空域到底发生过多少层行动。

所以项目里开始出现一些看起来很“工程”的字段:routeKind、waypoints、formationUnits、visibleUntil、unitVisibleUntil、revealAt、unitGroupId、retainUnitAfterRouteEnd。

它们不是给代码看的装饰,而是给动画叙事用的语法。

图 5|海战与空战的运动语法:海战强调舰队连续存在、航迹保留和不上陆;空战强调短时出击、离场、航迹密度和同窗接触。

SECTION 04

04 / 这次最像“动画制作”的地方:反馈被写进测试

这类项目如果只靠肉眼调,很快会变成玄学。

今天修好了舰队消失,明天改一个视窗又回来了;今天飞机返航了,后天某条路线的 unitVisibleUntil 晚于 end,飞机又停在终点悬空;今天字幕不挡地图,明天新增一个图例,又把字幕压住。

所以这次很大一部分工作不是“画得更漂亮”,而是把用户指出过的问题变成回归门禁。

测试文件 tests/battle-france-smoke.spec.ts 现在已经不只是“页面能打开”的 smoke test。它会检查首页分类、所有动画入口、地图交互、滚轮平移、缩放按钮、字幕低侵入性、背景配乐来源、图标资产、事件点击音效、空战短波次、飞机离场、航迹保留、反剧透标注、海路不上陆、舰船 bbox 不压陆地、齐射和弹着效果等。

这听上去有点笨,但这正是小项目变得可靠的方式:把每一次“看起来不对”翻译成下一次不会轻易回归的规则。

SECTION 05

05 / 动画助手:真正被开源出来的不是页面,而是一套做动画的方法

如果只看在线演示,war-animation-library 像是一个战争动画网页;如果看仓库里的 `agents/skills/animation-assistant` 和 `docs/animation-assistant-agent.md`,它其实还开源了一套动画助手的工作法。

这个助手的定位不是“帮我写个页面”。它负责把一个主题转成可播放、可暂停、可回放、可拖拽时间轴、可事件跳转、可浏览器验证、可长期运行的网页动画作品。换句话说,它处理的是完整生产闭环:先读项目和资料,再建数据模型,再写渲染,再跑浏览器,再把用户反馈沉淀成下一次的规则。

这也是“我与 LLM”的协作里最值得“沉淀”的部分。LLM 更像一个记得住教训的制作副手:用户指出“飞机不该悬停”“舰队不该消失”“字幕挡住地图”“音效不该乱响”,这些反馈不只是修一次 bug,而是被写进 skill、文档和 Playwright 断言,变成下一部动画的起点。

目前动画助手里已经沉淀了几类规则。

第一类是资料规则:先读 `package.json`、入口组件、数据文件、测试和 sources 文档;事实内容要来自主要或可信来源;不确定性要写在 `docs/sources`,不要把历史争议伪装成确定叙事。

第二类是数据规则:事件、坐标、路线、阶段、字幕、音效和来源应放在数据层;插值、投影、时间轴压缩和地图交互放在 `src/lib` 或通用组件里。新增动画优先复用 `CampaignMapAnimation`,不要每部战役复制一套临时渲染器。

第三类是观看规则:动画必须有播放、暂停、回放、时间轴拖拽、事件跳转和当前状态;片长默认控制在五分钟;长跨度战争要压缩非作战空档,短会战则可以按小时推进。地图标题只能做小型情报牌,不能遮住战场;旁白字幕要低侵入,不能拦截地图交互。

第四类是战争语法规则:古代陆战、近代海战、二战空战、现代装甲战不能共用一套视觉语言。单位图标要按时代匹配,战车、战马、大炮、战船、航母、坦克都要有可辨识细节;海战路线必须走海面,必要时增加港口点和 `waypoints`;空袭路线必须使用 `routeKind="air"` 和写实飞机图标,不能让飞机像坦克一样长期驻留在终点。

第五类是音效规则:配乐要按动画分别选择并记录来源,不要所有战役复用同一首进行曲;战斗事件点击也要触发对应时代的 SFX。古代战役是冷兵器碰撞,拿破仑与风帆舰是炮声,二战空战是飞机、机枪、爆炸。音效不是气氛糖衣,而是事件是否进入正确窗口的证据。

第六类是测试规则:视觉 claim 要能被测试。页面入口、地图交互、缩放复位、字幕位置、图标资产、音效触发、反剧透标注、航迹保留、飞机离场、舰船不上陆,都应该进入 Playwright smoke。源码改完如果跑的是 `vite preview` 产物,必须先 `npm run build`,否则测试可能还在旧 dist 上误判。

所以这套动画助手的价值,不只是“能继续帮我做战争动画”。它更像一个小型经验编译器:把人的审美、历史判断、工程约束和一次次返工,翻译成可复用的制作规则

当这个仓库拿到第一颗星星时,我想感谢的也正是这件事:不是某一张图终于画完了,而是我和 LLM 共同搭出了一条会留下经验的工作台,并且可以给别人用了。下一次再做海战、空战、古代战役或现代火力战,起点已经不再是空白页面,而是一套带着记忆的制作方法。

图 6|动画助手循环:看仓库、建模型、跑动画、写测试、沉淀技能。用户反馈不是一次性修 bug,而是被编译成下一轮制作规则。

SECTION 06

06 / 代码结构:一个通用渲染器,多部战役数据

从仓库看,项目的核心思路比较克制。

src/data 里放战役事实和结构化数据:事件、地图点、路线、编队、音效 cue、旁白。src/components 里是动画 wrapper 和通用组件。src/components/CampaignMapAnimation.tsx 是最核心的通用地图动画渲染器。src/lib 里放投影、地图交互、时间轴、音频和单位规则。

换句话说,新增一部动画不应该先复制一套渲染器,而应该先写资料文档和数据模型。只有当通用层真的表达不了“连续舰队交接”“空战短波次”“齐射弹着”“关键点延迟揭示”这些共性能力时,才改通用层。

这个边界很重要。

因为如果每部动画都有自己的逻辑,项目很快会变成二十多个互不相干的小网页;而如果所有战役都硬套同一种模型,又会变成“历史题材的路线播放器”。

现在这条线还在摸索,但方向是清楚的:每个战役有自己的数据和叙事节奏,通用渲染器负责把这些数据稳定地播出来。

图 8|大周行动:轰炸机流、护航、截击和受损返航不应该只是文字说明,而要在地图上形成可复盘的空中层次。

SECTION 07

07 / 音效不是附属品,它也是叙事的一部分

这次更新里还有一个小但关键的变化:音效被当成动画制作的一部分,而不是背景装饰。

古代战斗适合冷兵器和近战音效;拿破仑、风帆舰和近代海战更适合炮声;二战空战和海空战则需要区分飞机飞行、空战扫射、轰炸爆炸。更麻烦的是,音效不能只在自动播放时响,用户点击事件跳转时也要响,因为事件点击本身就是一次探索动作。

所以测试里会去 mock Audio,检查点击战斗事件时是不是请求了正确的 SFX 文件。

这背后的原则很简单:如果画面上是雷达预警,就不应该突然有爆炸声;如果画面上已经进入轰炸窗口,却完全没有爆炸声,观众也会觉得空。

战争动画的节奏感,不只是画面速度,也是声音和事件对齐的结果。

图 9|俾斯麦海海空战:船队路线、盟军侦察、高空轰炸、低空跳弹和后续追击都需要在同一时间逻辑中对齐。

SECTION 08

08 / 开源边界:代码 MIT,素材不能一概而论

这个项目已经是公开仓库,但它不是一个可以无脑商用素材包。

README 和 NOTICE 的口径比较明确:代码按 MIT License 发布;媒体素材来自混合来源,包括 public domain、CC0、需要署名、非商业限制或尚未完全核验的资源。也就是说,如果你只是看 demo、学习结构、复用代码思路,边界相对清楚;如果要把图标、音频、图片拿去商业发布,就必须回到 NOTICE.md 和 docs/sources 逐项确认。

这也是我觉得这个项目有一点“实验室感”的地方:它不是把所有不确定性藏起来,而是把来源、许可和不确定性写进文档。

对于一个历史动画项目来说,这比“看起来很完整”更重要。

SECTION 09

09 / 验证结果:构建通过,smoke 暴露了四个回归点

这次写文章前,我重新拉取了公开仓库并检查了当前 main。

验证结果要如实说:npm run build 通过;animation-assistant 自带的项目健康检查通过;但全量 Playwright smoke 不是全绿,而是 21 项里 17 项通过、4 项失败。

四个失败点分别是:蒙古/秦和凯撒两个动画在某些事件跳转时当前事件位置超出 map core 阈值;伦敦上空的鹰在傍晚事件点击后多触发了一次机枪音效;特拉法尔加的字幕和图例之间垂直间距期望至少 4px,实际为 3px。

我反而觉得这些失败值得写出来。

因为它说明这个项目的测试已经开始管到“观看体验”的边界:事件点有没有落在核心视野里,字幕有没有压住图例,音效有没有多响一次。它也说明当前项目还不是一个“完美成品”,而是一个持续制作中的开源实验室。

这比假装全都好了更真实。

图 10|特拉法尔加:风帆舰列、两纵队突破和近距离混战需要靠路线、编队、图标和镜头一起表达。

SECTION 10

10 / 我为什么喜欢这个小项目

它有一种不太常见的气质:既像一个网页玩具,又不满足于只做网页玩具。

它当然还有很多粗糙处。测试还会失败,动画质量不均,素材许可还需要继续梳理,老动画也需要按日德兰和海空战的新标准逐部回炉。

但它已经开始回答一个更有意思的问题:AI 和工程工具能不能帮助一个人持续生产“可观看的知识作品”?

不是生成一张漂亮图,也不是写一篇空泛介绍,而是把资料、代码、地图、音效、测试、用户反馈和经验沉淀绑在一起,形成一个可以继续生长的小系统。

这也是 war-animation-library 目前最值得看的地方。

它不是一座已经完工的博物馆。

它更像一间有点乱、有点认真、桌上摊着战史书、地图、浏览器和测试报告的小工作室。

下一部动画会变好,不是因为“灵感突然来了”,而是因为上一次的错误已经变成了下一次的规则。

SECTION 11

11 / 怎么运行

如果你想自己跑一下:

```bash

git clone https://github.com/fuxiaoyan1/war-animation-library.git

cd war-animation-library

npm install

npm run dev

```

本地构建和验证:

```bash

npm run build

npm run test:smoke

node agents/skills/animation-assistant/scripts/check-animation-project.mjs .

```

在线演示:

https://fuxiaoyan1.github.io/war-animation-library/

GitHub 仓库:

https://github.com/fuxiaoyan1/war-animation-library

如果你点开它,建议不要只看首页。可以先看日德兰,再看伦敦上空的鹰、大周行动、俾斯麦海和特拉法尔加。它们最能看出这几天真正发生的变化:这个项目正在慢慢变成“战争动画制作系统”。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 晓谈岩说 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 致谢我们(我与LLM)的第一个颗星星(GitHub):从一张战役地图到一个会自己长经验的战争动画实验室
    • 01 / 这次更新,不是“又加了几张地图”
    • 02 / 当前货架:21 部动画,真正变化在海战和空战
    • 03 / 为什么海战和空战不能共用一套箭头
    • 04 / 这次最像“动画制作”的地方:反馈被写进测试
    • 05 / 动画助手:真正被开源出来的不是页面,而是一套做动画的方法
    • 06 / 代码结构:一个通用渲染器,多部战役数据
    • 07 / 音效不是附属品,它也是叙事的一部分
    • 08 / 开源边界:代码 MIT,素材不能一概而论
    • 09 / 验证结果:构建通过,smoke 暴露了四个回归点
    • 10 / 我为什么喜欢这个小项目
    • 11 / 怎么运行
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档