[HOME](https://hackmd.io/2BHmUlxZRy-eNbUEF2Mc-A?view) # ゲーム画面実装メモ ノーツの描画を時間の関数として実装するためのメモ ## 計算式 ### ボツ案 <details> **必要な情報** - プレイヤーから右画面端までの時間的距離(s) - ノーツの移動速度(pixel/s) - ノーツの配置位置(s) - 楽曲再生位置(s) - bpm **プレイヤーから右画面端までの時間的距離(s)** = プレイヤーから右画面端までの距離(pixel) / ノーツの移動速度(pixel/s) **ノーツのプレイヤーからの相対時間(s)(ノーツがプレイヤーに重なるまでの時間)** = ノーツの配置位置(s) - 楽曲再生位置(s) **ノーツのプレイヤーからの相対x座標(pixel)** = ノーツのプレイヤーからの相対時間(s) * ノーツの移動速度(pixel/s) = (ノーツの配置位置(s) - 楽曲再生位置(s)) * ノーツの移動速度(pixel/s) ※ 参考まで、ノーツが必ずしもプレイヤーに向かって等速直線運動するわけではない? **1拍の間隔(s/beat)** = 60 / bpm **1拍の間隔(pixel)** = 1拍の間隔(s/beat) * ノーツの移動速度(pixel/s) = (60 / bpm) * ノーツの移動速度(pixel/s) **ノーツのプレイヤーからの相対拍位置(beat)** = ノーツのプレイヤーからの相対時間(s) / 1拍の間隔(s/beat) = (ノーツの配置位置(s) - 楽曲再生位置(s)) / (60 / bpm) = (ノーツの配置位置(s) - 楽曲再生位置(s)) * bpm / 60 </details> ### 案 **必要な情報** - ノーツが出現してからプレイヤーに衝突するまでの拍数(beat) - ノーツの配置位置(s) - 楽曲再生位置(s) - bpm **ノーツのプレイヤーからの相対時間(s)(ノーツがプレイヤーに重なるまでの時間)** = ノーツの配置位置(s) - 楽曲再生位置(s) **1拍の間隔(s/beat)** = 60 / bpm **ノーツが出現してからプレイヤーに衝突するまでの時間(s)** = ノーツが出現してからプレイヤーに衝突するまでの拍数(beat) * 1拍の間隔(s/beat) = ノーツが出現してからプレイヤーに衝突するまでの拍数(beat) * 60 / bpm **ノーツ出現からプレイヤー衝突までの進行率(%)** = ノーツのプレイヤーからの相対時間(s) / ノーツが出現してからプレイヤーに衝突するまでの時間(s) = (ノーツの配置位置(s) - 楽曲再生位置(s)) / (ノーツが出現してからプレイヤーに衝突するまでの拍数(beat) * 60 / bpm) **ノーツがプレイヤーに衝突するまでの残りビート数(beat)** = ノーツのプレイヤーからの相対時間(s) / 1拍の間隔(s/beat) **ノーツ出現を基準とした経過ビート数(beat)** = (楽曲再生位置(s) - (ノーツの配置位置(s) - ノーツが出現してからプレイヤーに衝突するまでの時間(s))) / 1拍の間隔(s/beat) ### 計算式から考えるノーツ描画の実装方法 ```cpp= // 1拍の間隔(s)を計算する Duration secPerBeat(double bpm) { return 60 / bpm; } class HogeNote { private: const Duration posSec = 10s; // ノーツの配置位置(s) const double intervalBeat = 1.5; // ノーツが出現してからプレイヤーに衝突するまでの拍数 ??? status; // ノーツの状態(回避に成功したかどうか) // ノーツが出現してからプレイヤーに衝突するまでの時間を計算する Duration intevalSec(double bpm) const { return intervalBeat * secPerBeat(bpm); } // プレイヤーがノーツに衝突するまでの時間(s) // 衝突する前は+ 後は- Duration culcDiffSec(Duration musicPosSec) const { return posSec - musicPosSec; } // プレイヤーがノーツに衝突するまでの残りビート数 // 衝突する前は+ 後は- double culcDiffBeat(musicPosSec, bpm) const { return culcDiffSec(musicPosSec) / secPerBeat(bpm); } // ノーツ出現を基準とした経過ビート数を計算する // double culcElapsedBeat(Duration musicPosSec, double bpm) const { // return (musicPosSec - (posSec - intervalSec(bpm))) / secPerBeat(bpm) // } public: void draw(musicPosSec, bpm) const { const double diffBeat = culcDiffBeat(musicPosSec, bpm); if (diffBeat > 1) { // 出現してからの0.5拍で、フィールドへの出現のアニメーションを行う } else { // elapsedBeat <= 1 // switch-caseを使う代わりに、変数で保持した画像を表示するとよい // 画像は成功・失敗時に差し替える switch (status) { case プレイヤーに衝突する前: // 1拍前からプレイヤーに衝突するまでの予備動作を描画する break; case プレイヤーが回避に成功した: // 回避に成功した場合の描画 break; case プレイヤーが回避に失敗した: // 回避に失敗した場合の描画 break; } } } void update(musicPosSec, bpm) const { const double diffBeat = culcDiffBeat(musicPosSec, bpm); if (diffBeat <= 1) { // 1拍前になったら1回だけ前フリの効果音を鳴らす処理 } } } ``` ## データフロー ### NoteManager => Note::draw() ## コード ### NoteManager ```cpp= Array<Note*> notes; void draw() const { for (auto note : notes) { note->draw(musicPosSec, bpm); } } ``` ### Note インターフェース定義 ``` interface Note { ノーツの配置時間(s)を取得する update void draw(musicPosSec, bpm) const; void update(musicPosSec, bpm); } ``` ```cpp= void HogeNote::draw(musicPosSec, bpm) const { } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up