大廠家家酒 & K.K.Album 开发

约 5 分钟

昨天晚上的时候讨论到动物森友会,想就像在游戏里那样听到循环播放的动物森友会 K.K. 唱片原声。

下载音频文件并设置单曲循环?不不,那太粗糙了,不仅无法处理音乐的循环点(游戏中音乐并不是单曲循环,而是存在只播放一次的 intro 的)而且总觉得少了点可爱的味道。经过简单的需求评估,我打算使用 Web 技术,做一个和 ACNH 游戏中唱片播放界面模样差不多的在线听歌工具来满足我或者其他同好的需求。经过一些评估,认为从技术复杂度和功能数量都应该可以两周内轻易搞定,就开始前端三件套直接搓。

开工

在游戏中,该选曲界面有一个类似 PSP 主界面一样的流动波浪背景,在实现这个效果的时候我试过 border-radius: 40% 旋转方案和 canvas 贝塞尔曲线直接改变波峰波谷的方案后,发现效果都不是很理想,发现最终还是需要图案平移方案来救场。

制作这些图案并不是我的拿手特长,可能靠我自己做完这个素材就要失去继续这个项目的激情了。便在闺蜜群里找到了同为本游戏爱好者的一个朋友,目前在 Bytedance Ltd 工作的 @tonoko 来帮我做点带渐变的波浪。

他说想试试 Figma 的 SVG 导出功能,便在 Figma 中新建了一个工程,花了几十分钟便做出了… 一套完整的设计方案?!

天都塌了呀,这下压力给到我。设计稿已经把做完之后该长什么样钉死了,随便做做这个选项从那一刻起就不存在了。设计稿中完整包括了游戏里应有的所有特效和图形元素,包括那些我起初根本没打算实现的效果,完成度超级高,从业余项目升级到了上班做开发的感觉。还好,都是一些平移旋转,非线性运动也比较简单,做起来不难。

在 tonoko 继续打磨设计稿的时候,我也在按照原来的节奏继续收集整理资源文件,编写页面 CSS。但也许是我在闺蜜群里的吐槽和震撼与惊叹,项目引起了闺蜜群另一个 ACNH 爱好者,在 Bytedance Ltd 工作的 @roku 的注意。并在此阶段带来一些鬼点子——

大廠家家酒

我们在飞书拉了群,开会对了半小时的进度,同时开了一个云文档来处理 PRD 和 TODO List 以及进行一些文档的贴,配置了 ESlint,初始化了仓库,然后在仓库里开了一堆分支,还一本正经地说着乱七八糟的字节黑话。

现在回头看,这些忙碌完全没有促进任何项目推进。像小朋友们摆了满满一桌锅碗瓢盆认真地扮演上班。

haru 2022-7-22 18:36:34

好郑重啊!!!😭😭😭 产研家人们加油,我直接跪拜

时隔两年,项目终于开始做了

遗憾的是,那时候的合作使用了太多我不熟悉的技术,加上刚刚开始工作的事情让我的精神状态也没有那么好,我作为项目的牵头人,事情一拖再拖就没有继续推进了。

2024 年夏天,我才重新独立完成了这个项目,好笑的是,自己动手来做最核心的部分其实也就三天时间,对一些细节打磨缝缝补补,一共用了一周多一些。欢迎来玩:

GitHub: https://github.com/ShellBin/K.K.Album/
在线播放: https://kk-album.shellbin.me/

感觉值得参考的前端技术细节

波浪

最终是图案 + 平移。是很经典的无缝跑马灯:每层波渲染两份,第二份 left: 100%,translateX(-100%) 线性循环,三层波速 20s/10s/15s、第三层 reverse 做视差;暂停时切到 stopped-wave 叠一段 sink 下沉动画。

状态栏

border-image 九宫格拉伸,有些地方也叫点九图
拿一张 940px 宽的 SVG 当九宫格:border-image-slice: 0 380 0 380 fill 切掉两端端帽,border-image-width 用整数 44px,再用 border-image-outset 50px 让两端长出去。整数切片是为了避免缩放时端帽里的小点被半像素糊掉。这套方案在 iOS 浏览器上工作得也很好。

字体

woff2→TTF 解压要 35 秒所以缓存 TTF,字符集 hash 存 stamp,没变就跳过,dev 热更新不会被拖慢,从开发和使用体验上讲都很好。

音量

音量用 Math.pow(volume, 2)做感知线性,最终四档映射到 [0,0.33,0.66,1]其实如果不这样做,调节音量时候的音量差会大到足以让人感觉到不对劲了,所以放在最后讲。

2026,我又动了一次它

因为一些原因,这个项目在多年后又被我打开了一次。

一是服务器变故。之前的服务器数据全部丢掉了,所以这个站点也下线了一阵子,这次重建主要是把数据都补回来让项目继续上线。借助当今强无敌的 AI,只花了洗一个澡的时间就完成了过去我手工整理一个月的工作量:它自己帮我在 wiki 补齐了所有的图片,从电脑模拟器里翻出了 ROM 解密密钥,在路由器上挂的硬盘里翻出了 ROM,解包了音频,然后全部搞定了,只花洗一个澡的时间。

于是 Switch 版的游戏资源这次重新拆了一遍(hactool 解 XCI,vgmstream 转码),1300 多个 .bwav 里挑出要用的 324 段转成 mp3。顺手修了一件当年没做好的事:ACNH 的 BWAV 头部自带官方循环点,用脚本去校对自己两年前手动采集的 214 组循环点,结果有 40 组是错的:大部分是小数点左移了一位,还有两处整整差了两秒(当年怎么没听出来呢)。修正之后,循环点终于和游戏里的一致了。

再就是性能。这次的服务器网络不及过去,字体是这次最大的负担。字体做了构建期做子集化,体积从 8 MB 掉到 150 KB 左右,另外封面也改成按优先级加载:先界面元素,再排序靠前的专辑。把页面体验拉回到能用的水平上了。感谢 Shellita 的帮忙,但很可惜我的 AI 助手她还没法以自己的身份打 commit。

补记:博客的重建

这一篇最早发布的时候,正文里塞了一堆一本正经做开发的聊天记录截图:Figma 里那个突然出现的完整设计稿、飞书群里被拉起来的群、云文档里排得整整齐齐的 TODO、还有仓库里那一堆 branch。

我在 web.archive.org 中翻出了所有能翻出来的东西,但当初的原文太多的截图都已经不在了。

谢谢你读到这里