2013/12/25

HSPで音ゲーをつくろう(備忘録まとめ)

こんばんはひつぶです。

CATEGORIZEを作ったはいいものの、
せっかく思いついた仕組みとかを忘れたら勿体無いと思って記事にしておくこととしました。

講座なんてけったいなものではなく大雑把にまとめていく感じです。

ソースコードも綺麗に載せる方法がよく分からないのでひたすら文章です。
そのうち講座形式でやるかもしれません。

こういう資料みたいなものって探しても全く無いので。

興味のある方だけどうぞ。
([ ]内は単位です)

音楽の知識


「BPM(テンポ)」と「小節」と「拍子」と「音符(ノーツ)」の関係。

BPMとは、1分間に鳴る拍の量です。
なので、

( 60[s]÷BPM ) x 1000 x 一小節内の拍子の数 = 一小節の長さ[ms]

となります。

後は、使いたいノーツの音符の種類によってこれを割り算してあげれば良いだけです。
最初はここでガッツリ躓いてました。

ノーツの描画

HSPのDirectXモジュールHSPDXに、「es_apos」「es_aim」「es_adir」といった、
一見すごい使えそうな命令が多々あります。

しかし、絶対にこれらは使用してはいけません。
HSPに限らず、他の言語でもそうです。

描画開始させて後は放置、みたいな方式を取ってしまうと、
FPSを一定に保つことは難しい為、所謂「ズレ」が極端に起こってしまいます。
面倒臭がらず、丁寧にやりましょう。

曲同期の話は後述します。

タイミングの管理

この辺からは「CATEGORIZE」でのお話となります。
もっとうまい方法はあるだろうし、自分で考えたほうが絶対楽しいし達成感あります。

かてごらでは、
「ノーツが出現するタイミング」と、
「ノーツが判定ラインに重なるタイミング」、つまり譜面に実際に書いてあるタイミングの2つを、
譜面を読み込む際に配列に保管しておきます。

判定タイミングは譜面そのままで、
出現タイミングは判定タイミングから描画されるだけの長さを引き算したものとなります。

また、配列に保管しておくことでノーツ全てに0から順番に番号が振られます。

これを利用し、
「今どこまでノーツが出終わったか」を、出現と判定の2箇所でカウントしていきます。

すると、描画されなければいけないノーツは

「判定カウント」番号から「出現カウント - 判定カウント」個、となるわけです。

書いてて頭が混乱してきます。

曲同期

これは授業中突然思いついた方法ですが。

ループ毎に楽曲の再生時間からノーツ毎の座標を計算させ、描画する、というものです。

式にすると、ある時間のあるノーツの座標は

{ 曲時間 - 出現タイミング(判定カウント番号)[ms] } ×( 1msごとに動かすピクセル数 )

となります。
これからノーツのサイズを引き算すればより自然になります。

始点の座標が0でない場合、足す必要もあります。

判定

さて。一番の闇。判定です。

CATEGORIZEでは、
「判定ラインに最も近いノーツ」の持つ判定タイミング[ms]と、曲の再生時間[ms]との差をとり、
これで判定をしています。

また、ここで別の配列でそのノーツが判定されたかどうかを配列で保管しておきます。

もし判定しようとしたノーツが判定済み(描画対象外)であるなら、
判定ラインから2番目に近いノーツを探す、といったような形です。

長押し

構造は至って単純ですが、ノーツ番号の管理が単押しに特化しているため少し面倒臭いことになります。

譜面読み込みの段階で、全ノーツ分の「長押し時間」を保管しておきます。
単押しの時はそもそも見に行かないし、0を入れておけば問題ありません。

描画用に判定カウントとは別に、「今描画されなきゃいけない長押しノーツ」のノーツ番号を保持しておき、
その長押しノーツの持つ判定ミリ秒と曲の再生時間との差から残り時間を出すことが出来ます。

最後に

以上です。
いざ構造を文章にするとコード以上にわけが分かりません。

CATEGORIZEは頭の中で完結していまっていたのでこうして文章にしておこうと思った次第です。

そのうちもっとしっかりまとめます。
それでは。




1 コメント:

  1. 初めまして
    CATEGORIZEプレイしています!!
    楽しいゲームをありがとうございます!!

    返信削除