はじめに
この記事は 「MM2025 開発記」 シリーズ第11回です。
前回の記事ではプレイヤーキャラクターの物理挙動設計について解説しました。
今回は、歌詞情報と連動したコインの生成コードについて解説します。
Lyric / LyricCoinの役割分担
LyricとLyricCoinの2つのクラスを中心として、歌詞情報をゲーム内のコインに組み込んでいる。それぞれのクラスの役割について解説する。
Lyricクラス
簡単に言うと、音楽側のデータを扱っているクラス。
コインの描画などは全く行わず、TextAliveから取得した生の歌詞情報をコインの描画に使用できる形に整理するための場所である。
LyricCoinクラスと分けることで、音楽情報のコードとゲーム系のコードが混ざらず可読性が上がる。
class Lyric
{
constructor (data)
{
this.text = data.text; // 歌詞文字
this.startTime = data.startTime; // 開始タイム [ms]
this.endTime = data.endTime; // 終了タイム [ms]
this.duration = data.duration; // 開始から終了迄の時間 [ms]
this.x = 0; // グリッドの座標 x
this.y = 0; // グリッドの座標 y
this.isDraw = false; // 描画するかどうか
}
}
LyricCoinクラス
画面上に表示され、実際にプレイヤーキャラクターと衝突判定を行う歌詞コインを表すクラス。
- 描画
- スクロール
- 衝突判定
- スコア加算
といった、完全にゲーム側の役割を担っている。
歌詞タイミングからコインの座標に変換
コインの配置をするところでは、歌詞のstartTime(再生開始時刻)を使ってステージ上のx座標を計算している。
基本的な考え方
再生時間(ms) → ステージ上の距離
という変換を行う。
const x = playerX + scrollSpeed * (t / 16.67);
これにより、プレイヤーが前に進む → 音楽が進行する ようになる。
アーチ状配置アルゴリズム
yOffset = 70 + Math.sin(theta) * jumpHeight;
歌詞コインは、曲の盛り上がりに合わせてアーチ状に配置するようにしている。
理由としては、
- ジャンプ操作の誘導
- 音の盛り上がりを視覚的にも表現
- 単調さを回避
などがある。
高さの決め方
1. 歌詞グループごとにインデックスを振る
2. 中央が一番高くなるようにする
3. 両端に行くほど低くする
このように決めることで、音の盛り上がりをジャンプのリズムとして体感できるようになる。
さいごに
今回は、歌詞に連動したコインの生成について解説しました。
次回は、グラデーションと背景描画について解説していきます。
