[BlueLeaf1336]> PROBLEMS> FlatZone>

シューティングゲームの作り方 > FlatZone

historyTOP

2010/01/31:作成

はじめにTOP

最近、携帯電話でダウンロードした BLASTZONE というシューティングゲームがかなり好きです。ひとことでいうと、グラディウス型パワーアップ方式ノンスクロールシューティングと思います。4面ぐらいしか進んだことがないのですが、多分最後までそうだと思います。で、ランキング登録ができるんですが、1位の人は全桁9が並んでる信じられないスコアです。

かなりやってるにもかかわらず、下手すぎて歴代で4分の3程度しか届いてません。かなり爽快な感じなんですが、4面までいくと弾幕(?)が異常。よけられるわけなし。というわけで、もう少し進みたいので自分で作ってみたくなりました。ま、パーフェクトに真似できたとしても自分の知ってる面までしかいけませんけど。

そもそもシューティングなんて作ったことないので、どこまでいけるかは楽観的には未知数、現実的には針の山です。が、どうやって敵が動いてるのかを考えたりするのは普段使わない部分が活性化しそうなのでやってみることにします。

妄想構想TOP

以降は、自分の忘備録程度の断片的なメモになります。あと、「作り方」なんてタイトルですけど、本当は「作り方をまさぐる」感じなんで、間違ってやってきた方はすみません。

目標

登場人物

敵編隊についてTOP

何はともあれ敵機を画面に表示させて見ました。

今はこれっぽっちも動きませんが、これまでの経験上、なにか目に見えるものがないとテンションが続かないのが目に見えてるので、「今からこいつらを動かしてやる」という目標を作ったというか。

目先の目標はこれです。

実際どうなってるのかわからないんですが、ここでは、敵編隊を一塊と考えた時の原点(敵編隊の左上)を設定して、各敵機は原点からの相対的な位置で決めることにしました。

もう少し具体的には、敵機クラスを作って、0から999までのIDを持たせます。クラスのインスタンスを作るときにこのIDを決めてやってIDから各自の編隊原点に対する相対原点(意味不明)を計算します。横40縦25なので、IDが50だったら上から2段目の左から何番目みたいな感じです。

で、描画するときは、編隊原点と相対原点を足しこんで実際の位置を決めることにしました。後で変更するようなことがなければうれしいのですが、こうすればとりあえず編隊原点だけをそれなりに動かすことで、敵機全体が動くなぁと。

先のことを考えるべきですが、あまり考えすぎて先が見えてしまうと満足してしまうので、小さな目標をいちいち作ってジグザグしながら進めていくことにします。

とりあえず、上の画面はそういう状態です。

次に、敵編隊を「左右方向に一定のスピードで移動(左右にゆれる)」させます。作戦はこれで。

左右に動くというのは、円運動をべちゃっと平べったくしたものと考えられるので、sin関数を使って次のようにあらわしてみる。

これでいけそうな気がします。と思って、動かしてみようとすると、編隊の幅って何? って気づいてしまいます。ま、とりあえず適当な数字でごまかしてみると何とか動きました。しかし、動きが変。情緒がないというか。

とにかく先に進めます。さっき気づいてしまった編隊の幅についてです。これって固定値じゃありません。たとえば、編隊の右半分だけを撃墜してしまったとすると、編隊の幅は半分になります。そうなったとき左右のゆれが元通りなら画面の左半分ぐらいでうろうろするだけになってしまいます。それはそれでいいのかも知れませんが、もうひとつな感じです。実際に本家のBLASTZONE(以下、本物)でも編隊を端っこからやっつけていくと編隊が小さくなりますが、しばらくすると、ちゃんと小さくなった編隊が画面いっぱいにゆれ始めます。

1000機いるわけで、動く前にいちいち左端と右端を全部ループまわして確認するのが一番シンプルですが一番馬鹿そうです。

とりあえず現状のコーディングだと、敵機は描画のため(ひいては当たり判定とかにも使うはずです)に、それぞれ編隊原点に対する相対的な原点を持ってます。でも、1000機いるうちの1番最初の機体と1番最後の機体が必ず両端というわけじゃありません。TObjectListで管理しているので、一番最初はそうなっていますが、敵(自機)にやられる順番によって当然狂ってきます。

ここでは、速いかどうかは別にして、生き残っている全部の横座標を調べるよりはマシのはずと信じて、次のようにしてみます。

これでいけそうです。縦25段なので、同じ座標を表す文字列が25個ずつ登録されるはずです。各自死ぬときに自分のX座標を道連れにしていけば、縦25機が全滅するまでは、その座標が残ります(説明になってませんけど)。

敵編隊について2 (2010/02/01)TOP

昨日作った円運動ぺっちゃんこ方式での左右移動は端っこに近づくと遅くなるので、どうもシャキっとしません。等速度運動に変更したいんですが、グラフが三角形になるような方程式を知りません。そうなると場合わけをしないといけないんですが、それは避けたい(なんとなく)。

ん? x = | (t mod 5) - 5 | だといけそうな気が。

t012345678910
x54321543215

だめか。でも mod を使いそうな気がしたので、1時間ほどエクセルでがんばってみたところ、少しだけ近づきました。

右端が得られた答ですが、気持ち悪いのは、左端の連番(プログラム的には画面更新の度にインクリメントしてるカウンターに相当するつもり)から一撃で答えが求まらないということです。残念ながら右端から2列目の数字を覚えておかないといけない。右端から2列目の値は、連番と直前の値で決まります。で、これを仮にAと呼ぶと、答は、「連番 - A」で求まります。

で、下のようなほぼ魔法の呪文を画面更新のたびに計算すると、ちゃんと右に進んだ後で左に戻ってきました。惜しい点は、開始位置が画面の左端になってしまう点です。なんというか、もうそれでもいい気がしてきました。

    //  カウンターインクリメント
    Inc(FCounter);
    //  さっきの「A」を計算
    Inc(FTag, 2 * (((FCounter - 1) div (画面幅 - 編隊幅)) mod 2));
    //  編隊位置を計算
    編隊位置 := FCounter - FTag;

敵編隊について3 (2010/02/01)TOP

さて、それはそれとして、昨日、敵編隊の幅について検討した処置を施したのはいいのですが、今のところ、敵が一向に死なないので、うまくいけてるのかどうか全く試せません。ということで、次は敵の撃墜について考えてみます。

本物を確認してみると、敵の死に方はいくつかあります。

時限弾による爆発は多分しんどいので、まずは通常弾あるいはレーザーによる通常撃墜だけを攻略します。

それからもちろんまだ弾なんて高度なものはありませんので、撃墜されたらどうするかを考えます。まあ、考えるといってもやることはちょっとのはずです。

何が難しいって、撃墜中の画像の準備... よく見ると本物はかなりマメに撃墜画像切り替えてるし。でも、爽快感ってつまるところ撃墜感だもの。

敵編隊について4 (2010/02/02)TOP

何秒かに1回、右端の敵がいっせいに死ぬようにしてみると、敵編隊の幅の計算はうまく動いているようです。ただ、別の問題が出てきました。

昨日考えたジグザグ移動の計算式は、移動し始めた後で幅が変わるとおかしな動きになってしまいます。端っこにたどりつくと画面をはみ出したり、方向転換直後にまた方向転換してしまったり。少し考えればわかることでしたが、次の状態がこれまでどのように動いてきたかという歴史に影響されてしまうので、そりゃ無理な相談でした。

結局のところ、別の方法を考えないといけないようです。普通に考えると、今動いている向きを覚えておいて、端っこに来たときにひっくり返すことになりそうです。せっかく見つけたのに、残念。

敵編隊について5 (2010/02/07)TOP

メモ

軍隊 Army,Troops > 軍団 Army corps > 師団 Division (6000-20000) > 旅団 Brigade (1500-6000) >= 連隊 Regiment (3000) > 大隊 Battalion (=2-6中隊) > 中隊 Company, Battery, Troop > 小隊 Platoon

EOFTOP