RippleMusicこぼれ話(プログラム編)
- 音楽について
音楽は、画面や入力とはまったく無関係にスレッドを作ってその中でぴったりのタイミングでならしています。最小分解能は16分音符です。処理時間を引いてThread.sleep()かけてますのでかなり正確です。ここはこだわりました。Javaはスレッドまわりはかなりリアルタイムで動くのがありがたいです。
- 音について
javax.sound.sampledを使って、ベースを1オクターブ全ての音程、ピアノを1オクターブ全ての音程、メロディを2オクターブ全ての音程、ドラム(バスドラム、ハイハット)それぞれをサンプリングして持っています。
音楽データはMMLなんて凄い物ではなく、「配列に1小節48音分」全て持つという豪快な方法で鳴らすタイミングを制御しています。音楽スレッド側からゲーム側に「今鳴らすべき音」をリアルタイムで問い合わせて鳴らしています。
ゲームの進行に合せて伴奏が変わるのはゲーム側で音を制御している何よりの証拠です。ピアノが裏拍になるゲーム進行最高位の伴奏はかなり気持ちよくてお気に入りです。
- 画面について
画面は「なるべく早く書き込めるといいね」という超アバウトな方法論でJComponent.repaint()をタイマーでかけています。画面の描画が追いつかないときはさくさく飛ばされます。
- 入力について
入力も基本的にはイベントが来たタイミングを実時間で取ってます(そのせいでデバッグ時ステップ実行が出来ず死ぬ思いに)。フレームレートにほぼ依存しません。
- ログについて
マウス関連のログは片っ端から取ってます。なので、「どっちを押せばいいかなー」と迷っている動きもログが残ってます。今のところ、難易度が超高くなったときの「もうだめだな」というあきらめがログから読み取れます。
- JITについて
超遅いマシンで動かすと、JITが効き始めるまでフレームレートがひどく遅くなります(でもゲームはリアルタイムで動く)。が、ひとたびJITが効くととたんにぬるぬるしたフレームレートになると言う。Oracleのリファレンス実装であるHotSpotJVMむちゃくちゃ優秀です。
とりあえず、Javaで音ゲーを作るのはjavax.sound.sampledが妙に不安定なので鳴らすのが大変と言うことが判りました。ちぇー、音楽大好きなのに。