游策手记GAMESTRATEGISTS

第一方作品 · 节奏

听雨

RAIN BEATS

《听雨》是一款在浏览器里实时合成声音的四轨节奏游戏,打开网页就能玩。三首曲子96/120/144 BPM,谱面由固定种子生成,音符数依次48、72、104。D、F、J、K对应四轨,判定窗口±45/±100毫秒,每10连击分数加5%、上限50%。没有音频文件,成绩只存在这台设备上。

查看玩法
曲目 3 首轨道 4 条音符 48 / 72 / 104BPM 96 / 120 / 144判定窗口 ±45 / ±100 ms最高连击加成 +50%

键盘:方向键 / WASD、空格、P 暂停、M 静音 · 手机:直接在画面上触摸

怎么玩

四条轨道,三首曲子,声音全部当场算出来。音符从画面上方落到判定线,在重合的那一刻按下对应的键。判定不看画面画到第几帧,看的是声音时钟:每个音符带着一个目标时间,命中时拿当前歌曲时间减去它,差多少就给什么评价。

生命 100 起步,Perfect 回 1.2、Good 回 0.5、Miss 扣 6;归零判失败但曲子会放完。准确率是 (Perfect×1 + Good×0.6) 除以总音符数,全 Perfect 正好 100%。想打高,先把 ±45 ms 的窗口按稳,再把连击续到 100。

曲目
3 首
轨道
4 条
音符
48 / 72 / 104
BPM
96 / 120 / 144
单曲时长
均为 40 秒
判定窗口
±45 / ±100 ms
连击加成
每 10 连击 +5%,上限 +50%
生命
100 / Perfect +1.2 / Good +0.5 / Miss −6

操作

D / F / J / K四轨击打
P暂停 / 继续
R重开本曲
Esc回到标题
M静音 / 取消静音
手机底部四触摸区,按 x 分轨,支持多指

这是什么

《听雨》是一款四轨下落式节奏游戏,打开网页就能玩,不用下载、不用注册。四条轨道对应键盘上的 D、F、J、K,音符从画面上方落到判定线,你在它和判定线重合的那一刻按下对应键就算击中。手机上没有键盘,画面底部画出四个触摸区,手指按哪一列就打哪条轨,支持多指同时按。判定和画面是分开算的,掉帧不会把节奏带偏。

游戏一共三首曲子:「檐下」96 BPM、64 拍、48 个音符,「涨潮」120 BPM、80 拍、72 个音符,「骤雨」144 BPM、96 拍、104 个音符。时长都按拍数除以 BPM 换算,三首都是 40 秒。谱面用固定种子生成,同一首曲子每次打开的音符位置、轨道和数量都一样,成绩才有可比性。

它的主时钟是 AudioContext 的 currentTime,不是帧数。每个音符、每一声 bass、每一层雨声都提前排到未来的时间点上,命中时就拿当前的歌曲时间和音符目标时间作差。±45 ms 以内是 Perfect,±100 ms 以内是 Good,超过 100 ms 没打中就是 Miss。哪怕某一帧卡了半个刷新周期,判定窗口也不会跟着漂。

三首曲子是怎么来的

三首曲子都没有音频文件。低频正弦负责 bass,三角波加快速衰减做木琴式的短音,再叠一层经过高通和低通滤波的噪声当雨声底噪。它们在浏览器里由 WebAudio 实时合成,每个事件按 currentTime 提前排程到未来的时间点,声音和判定共用同一把尺子。三首用各自的音阶和音色,从柔和到紧绷,难度也跟着往上走。

谱面不是手写死的,是用固定种子生成的。生成时把曲子的拍子切成八分音符网格,按权重挑出若干格放音符,难度越高密度越大,还会在部分格子放两条轨同时命中的和音。挑完再数一遍,确保「檐下」正好 48 个、「涨潮」72 个、「骤雨」104 个,一个不多一个不少;运行时也能数出来,不会随刷新变化。

判定与计分

生命从 100 开始。Perfect 回 1.2、Good 回 0.5、Miss 扣 6,生命夹在 0 到 100 之间。归零会判失败,但曲子仍会放完,结算里明确标出未通关,不会中途把你踢出去,也不会停止伴奏。连击在 Perfect 和 Good 上累加,Miss 清零。

连击每到 10 的整数倍,之后每个音符的得分就加 5%,一直加到上限 50% 封顶,也就是连到 100 之后不再涨。基础分 Perfect 最高,Good 约为它的六成。准确率按 (Perfect×1 + Good×0.6) 除以总音符数算,分母是整首曲子的音符数,所以全 Perfect 是 100%,全 Good 是 60%,全程 Miss 是 0%。结算再给出评级 S / A / B / C。

为什么用浏览器合成声音

不加载音频文件,主要是为了让节奏和判定严格对齐。下载来的音频在浏览器里要解码、进缓冲,开始播放的时刻和画面首帧常常差几十毫秒,而且不同设备差得还不一样;这个游戏把每个音符、每一声 bass、每一层雨声都按 currentTime 提前排程,判定用的也是同一个时钟,音画之间是同一把尺子,不用再猜偏移。

做法是把未来一小段时间内的事件先排好:每帧把未来约 0.15 秒内该响的音符和伴奏交给 WebAudio,剩下的等下一帧再排。这样既不卡帧,也不会因为一次性排满整首而在切后台回来后抢拍。暂停时把 AudioContext 挂起、currentTime 停走,恢复后从同一位置接着走,不会多响或漏响一个音。

代价是声音没法做得像录音那样厚,换来的是体积和确定性:页面里没有 mp3、没有 ogg,断网也能玩,三首曲子各用各的音阶与音色。雨声是叠了滤波的噪声,木琴是三角波配快速衰减,低频是正弦,全部现场算,没有一个采样文件要等。

键位、判定线和落速

电脑用 D、F、J、K 打四条轨,P 暂停,R 重开本曲,Esc 回标题,M 和页面上的按钮管声音。音符的落速是固定的,单位是像素每秒,判定线的位置跟着画布高度走,窗口拉高拉低都不会让音符提前或迟到;变的是它出现在画面里的时长,不是它该被击中的时间。

手机在画面底部画了四个触摸区,和四条轨道一一对应,按 x 坐标判断落在哪一轨,多指同时按也能分别判定。触摸区上标着键位字母,横屏竖屏都能用。四条发光轨道从紫色渐变到薄荷绿,命中时会在判定线炸开涟漪和粒子,连击数字弹出来,按下的那条轨会亮一下。背景雨丝分了几层视差,远处细而慢,近处粗而快。

成绩记在哪

每首曲子的最高分和最高准确率分开保存在这台设备的浏览器 localStorage 里,按曲目分别记录,选曲界面和结算界面会读出来,破纪录时结算会提示。数据不上传、不跨设备同步,也没有账号;清掉站点数据或换一台设备,纪录就从零开始。页面会加载广告脚本来覆盖运营成本,但游戏本身没有服务端、没有表单、没有自建统计。我们不知道你是谁,也不知道你打了多少局。

常见问题

下面是几个和判定、声音、成绩有关的实际问题,答案都对应到具体实现,而不是笼统的说法。

判定准不准,会不会因为我屏幕刷新率不同而变?
不会。判定用的是 AudioContext 的 currentTime 与音符目标时间的差值,和帧率、刷新率无关。画面掉帧最多让音符看起来跳一下,±45 ms 和 ±100 ms 的窗口不变。
暂停之后声音会不会错位?
暂停会把 AudioContext 挂起,currentTime 停走,已经提前排程的音符一起冻结;恢复后从冻结的位置继续,歌曲时间不变,所以不会多响、漏响或抢拍。
音符数量真的固定吗?
是。谱面由固定种子生成,生成后会数一遍,「檐下」48、「涨潮」72、「骤雨」104,严格等于标注值,每次打开都一样,运行时可数。
手机上怎么按四条轨?
画面底部有四个触摸区,按 x 坐标分轨,支持多指。不需要真的找四个按键,手指落在哪一列就打哪一轨。
生命扣到零会怎样?
生命归零判失败,但曲子会放完,结算明确标出未通关并照常给评级和成绩,不会中途结束。

雨还在下,来打一局

选一首曲子,从 48 个音符的「檐下」开始。成绩只记在你自己的浏览器里。