音楽ゲームの譜面を自作する方法——設計から実装まで
遊びを見つける執筆にClaudeを使用しています。

「好きな曲で遊べる音楽ゲームを作りたい」と思ったとき、多くの人が最初に壁にぶつかるのは譜面の設計です。ゲームのルールや見た目よりも、音と判定のズレ、ノーツの配置の難易度感、プレイヤーが「気持ちよく叩ける」かどうかは、譜面の質に大きく依存します。 この記事では、ブラウザで動く音楽ゲームの譜面を自作するときに必要な考え方と手順を説明します。既製のツールや教材で譜面制作を学ぶ方法ではなく、自分でゲームを作るときに「譜面データをどう設計し、どうコードに落とし込むか」という実装側の話を中心にします。
譜面データとは何かを整理する
音楽ゲームの譜面とは、「いつ・どのレーンに・どんな種類のノーツを置くか」を記述したデータです。最終的にはゲームエンジン(JavaScriptなど)が読み込み、再生中の時刻と照合してノーツを描画・判定します。
シンプルな構造から始めると理解しやすいです。たとえば次のようなJSON形式が出発点になります。
{
"bpm": 120,
"notes": [
{ "time": 0.5, "lane": 0 },
{ "time": 1.0, "lane": 2 },
{ "time": 1.5, "lane": 1 }
]
}time は楽曲開始からの秒数、lane はどの鍵盤・レーンかを示す番号です。これだけでも基本的なリズムゲームは動きます。長押し(ホールドノーツ)が必要なら duration を足し、フリック入力が必要なら type フィールドを追加する、という形で段階的に拡張できます。
BPMと拍に合わせてノーツを配置する
「秒数で直接指定すればいい」と考えがちですが、BPMが一定の曲なら拍数を基準にして計算するほうが整合性が取れます。
BPM120の曲では1拍=0.5秒です。4拍子なら1小節=2秒。8分音符は0.25秒ごと、16分音符は0.125秒ごとに打ちます。この値を使うと、ノーツの間隔が音楽的にきれいに揃います。
実装例として、拍数から秒数に変換する関数を用意しておくと便利です。
function beatToTime(beat, bpm) {
return (beat / bpm) * 60;
}beatToTime(1, 120) は 0.5、beatToTime(4, 120) は 2.0 を返します。譜面データを拍数で記述しておき、読み込み時に秒数へ変換する設計にすると、BPMの変更や曲の差し替えが楽になります。
BPMが曲中で変わる楽曲(BPM変化・テンポチェンジ)は難易度が上がります。変化ポイントごとに「その時点の経過秒数」と「新BPM」をテーブルで持ち、累積計算で各ノーツの時刻を出す方法が一般的です。最初は一定BPMの楽曲から始めるのが無難です。
判定タイミングのズレを取り除く
譜面の配置が正しくても、「なんかズレて感じる」という問題が起きやすいです。原因は大きく3つです。
オーディオの遅延(オーディオレイテンシ)
ブラウザでWeb Audio APIを使って音楽を再生すると、AudioContext.currentTime を基準に時刻管理をするのが定番です。<audio> タグの currentTime は精度が低く、判定ゲームには向きません。
const ctx = new AudioContext();
// ソースを作ってctx.currentTimeに同期して再生するWeb Audio APIで再生開始した時刻を変数に保存しておき、ctx.currentTime - startTime を常に参照することで、ノーツとの時刻比較を正確に行えます。
映像の描画遅延
requestAnimationFrame のコールバックは「次の描画フレームの直前」に呼ばれます。60fpsなら約16msの誤差が生じえます。判定ウィンドウを±50ms程度に設定している場合は許容範囲ですが、±30ms以下の厳しい判定を実装するときはこの誤差が目立ちます。判定ウィンドウの設計とフレームレートは合わせて検討します。
入力イベントの遅延
keydown や touchstart イベントはブラウザのイベントループを経由するため、物理的な入力から数ms〜十数msの遅れがあります。これはユーザー側の環境差も大きいです。設定画面で「判定オフセット」を手動調整できるようにしておくと、プレイヤーの不満を減らせます。
難易度を意識した配置の考え方
譜面データを作ったあと、「これが易しいのか難しいのか」を判断する基準を持っておくと整理しやすいです。
密度(ノーツ数/秒) が最もわかりやすい指標です。1秒に1ノーツ以下なら初心者向け、4〜6ノーツを超えると中級以上になります。ただし密度だけでなく、同時押しの有無とレーン間の移動距離が体感難易度を大きく左右します。
配置を作るときの実用的な判断基準を挙げます。
- メロディラインのリズムに沿ってノーツを置くと、初見でも押しやすい
- サビや盛り上がり部分だけ密度を上げると、曲の起伏と一致して自然に感じる
- 同時押しは「和音が鳴るタイミング」に絞ると乱用を防げる
- 難易度の異なる複数譜面を用意するときは、EasyはメロディのみをNormalに削ったバージョンから始めると一貫性が出る
譜面を作ったら、必ず自分でプレイして「押しやすいか」「音と合っているか」を確認します。数値上の密度が適切でも、実際に叩いて違和感があれば配置を直します。
著作権と音楽素材の選び方
自作の音楽ゲームに使う楽曲は、著作権の扱いに注意が必要です。
商業楽曲をゲームに組み込んで公開する場合、著作権者の許諾が原則必要です。「ゲームBGMとして使う」「パブリックドメイン」「クリエイティブ・コモンズのライセンスで商用・改変可と明示されている」といった条件を確認する必要があります。個別の判断は著作権に関する公式情報や専門家に確認してください。
実用的な選択肢として、CC0(パブリックドメイン)や CC BY(クレジット表示のみ)で提供されているフリー音源を使う方法があります。freesound.org、Incompetech(Kevin MacLeod)、DOVA-SYNDROME などのサービスは日本のゲーム制作者にも広く利用されています。ライセンス条件は各サービスの最新規約で確認してください。
次の行動
まずBPM一定のシンプルな楽曲を1曲選び、JSONで10〜20ノーツだけの最小譜面を作ってみてください。判定と描画が動いたら、オフセット調整の設定項目を追加してプレイヤーが快適にできる仕組みを整えます。ブラウザで動く完成品ができたら、アソバース(https://aso-verse.com)にHTMLやZIPファイルとして投稿して公開することができます。
参考資料
- MDN Web Docs「Web Audio API」
- Web Audio API仕様(W3C)


