弾幕STGの作り方の考察 その1
弾幕STGの作り方の考察 その1
ググればその手の解説の載っているサイトとかあるんでしょうけど、こういうのを自分で考えるのが楽しいので考えてみます。
fps算出
ゲームそのものには関係ないでしょうけど、スピードが落ちればよけやすくなってしまうわけですから配布する物を作るのであれば必要でしょう。
ある処理の前後でそれぞれ秒とミリ秒を取得して、単位ミリ秒で足した者の差を取れば時間が出ます。大小関係が逆であれば60000ミリ秒 (1分) を足します。(つまり、処理後の数値から処理前の数値を引いて、0以上はそのまま、0未満は60000足すとすればおk)
これを配列変数に代入していくのですが、本来は新しい数値を追加するごとに古いデータを消していきます。が、いちいちデータを最後に付け足しては最初を削除とすると大変なので、順番に1,2,3、4,1,2,3,4番目…というように (実際は4とかじゃあ足りませんけど) データを追加してあげればいいんです。
このデータを平均して1000を割ってfpsを出すのですが、1フレームごとに算出してたら重くなっちゃうんで、30フレームとかに1回づつ算出していきます。
スパゲティーにならないようにする
タイトル画面からゲームへ、そっから戻る、設定画面…と、gotoで飛ばしまくるとスパゲティになってきます。
そこで、「タイトル画面からゲームへ」とするのではなく、「タイトル画面のループを行っているサブルーチンから (ループから) 抜けて、ゲームのループがあるサブルーチンに飛ぶ」というふうにしたほうがよいです。
敵・敵弾・自機弾の発生・移動・消去などの処理のおおまかな流れ
基本的に全部同じようなやり方でできます。
発生位置、発生時間、スピードと向きで基本的に指定します。発生してからの時間を取得することで今後の処理を行うわけですが、ひとつひとつの敵にタイマーを設けて1づつ進めるなどをしてしまうと大変動作が重くなると思われるので、ループ内に一つだけタイマーをもうけて、発生時のタイマーの数値を取っておいて、現在のタイマーの数値との差で時間を計ります。
基本的なあたり判定
弾のスピードが速すぎると通り抜けてしまったりするのですが、今回はそれ虫で行きます。
普通の丸い弾どうしてあれば三平方の定理で距離が出せます。
点と直線の距離は、
点の座標を(a,b)、半直線の始まりの所の座標を(c,d)角度sとすると、
sin(s)*(a-c)-cos(s)*(b-d)の絶対値が距離になります。(ただし、直線でなく半直線なので、これに加えてもう少し工夫が必要です。そこはまだ考えていません…。ごめんなさい。)
最後に
かなり大雑把には書いていますが、「これはこういうふうにしないと動作重くなる」とか、結構重要なところをたくさん書いているので役には立てると思います。
ではまた。
fpsは……一番ラクなのはDirectX使って垂直同期に合わせることです。
算出方法、よくお考えになりましたね^^ 納得であります。
ゲームはやっぱりそうですね……いかにメイン関数をコンパクトにできるか。
しかしHSPはそこまで規模の大きなものに関しては作りづらい面があります。
なるほど、タイマーとの差を使う方法もありですね^^!
レーザーの発射口から始まるとするなら、半直線でいいのではないですか。
よく考察されていると思います。大事なことですよね。
体感的に、一番重いのは画像の描画に思います。でもきっとだいじょうぶ^^;
FPSねー
よく分からんことになったから撤去したがな!!←
>フェルミウム湾さん
ありがとうございます。
やっぱりDirectXですか…。
一度は使おうとしましたが、環境によって動作が変わるというのと、画像の処理にいろいろと面倒くさい仕様があったりしたのでやめました (おい
まあ確かにほんとは他の言語で作ったほうがいいのかもしれませんが、私はHSPしかできないので…orz
あ、いや、直線と点の距離の式が簡単に出たので、半直線とのあたり判定にするにはもうちょっと工夫必要だなーって思ったんです。
>橙さん
えww
スパゲッティにならないようにですが、個人的にはgotoはエラー処理以外は使わないべきだと思います。
gosubか、出来れば一つ一つの処理を関数にするべきでしょうね。関数にすれば、内部処理用の変数がグローバルスコープを汚すとこが無くなるので。
>関数
>グローバルスコープ
そうですね。でもまああんまり関数化ばっかりしても、たしかHSPだと処理が遅くなる的なのをどっかで見た記憶があるので、まあそうでないならいいんですが、念のためサブルーチンで私は進めていこうと思ってます。