2011年4月7日木曜日

2Dシューティングの進捗動画

しばらく体が辛い状態が続いて更新できませんでした。少し落ち着いたかなと思ったのですが、すぐに風邪っぽい症状でまたしばらく更新できない時間がつづきました。すみませんでした。

あまりにも時間が空き過ぎましたので、ひとまず以前作成したホーミングレーザー関連の動画をアップしてみたいと思います。
2Dシューティングの途中経(ホーミングレーザー)
以前の報告では、ホーミングレーザーはベジェ曲線をで実装したと報告してましたが、最終的にはHermite(エルミート)曲線で実装することになりました。どの曲線を使用しても通過点などの調整でおなじようなラインを描くことはできるとおもうのですが、レーザーの動きに対してエルミート曲線を使用するとレーザーの入射角をイメージしやすいなどプログラム的に使いやすかったというのが変更した経緯になります。

今回のホーミングレーザーの動きの概要は次のようなものになります。
  1. あえてターゲットと、ほぼ反対方向に対してホーミングレーザーを発射します。
    (ターゲットが上にいる場合、下方向にレーザーを発射することになります。)
  2. ターゲットの少し横を通ります。
  3. ターゲットを敢えて、一度通り過ぎます。
  4. 最後に急にグイッとターゲットの後ろに回りこんで、ターゲットをバックから狙い撃ちする。
という動きをするようにしています。自分としては、最後にグイッと敵を回りこんでバックから狙い撃ちという、ちょっとやらしい動きに特徴を持たせてみたつもりです。

エルミート曲線は、点の開始と点の終了に対して、方向を指定できるので、こういう動きを作成するのは非常に都合がよかったです。さらにこのエルミート曲線はゲーム一般にも都合がよいのか Vector2.Hermit()ということで標準で用意されていました。ちなみにベジェ曲線は標準では用意されていなかったので、いろいろなページを参考に自分で用意する必要がありました。


ホーミングレーザーのターゲッティングなのですが、ガイドスコープでどの敵を狙うかを指定するのが一般的だとは思うのですが、シューティングゲーム初心者の方でも気軽に気持よく操作ということを考えますと、自動で敵を探索して攻撃してくれるというのがいいかなということで、ボタンを押すだけでホーミングレーザーという簡単操作で進めたいと思っています。
そろそろゲームの仕様を決めないと、このままだらだらと時間だけが過ぎてしまいそうな感じです。プログラムよりも仕様決めが難しいなと最近よく思います。


背景の星スクロール 今回から背景の星を流すようにしてみました。昔の私ならCPU側で全部計算してGPUに頂点を転送などというダメダメプログラムを組んでいたと思うのですが、少しはGPUプログラムに慣れてきたこともあり、今回はほぼGPU側のみで実装しています。星の動き自体は画面下で消えたら上から表示しなおすだけなのでGPU側だけでも充分計算できるような簡単なGPUプログラミングになります。
CPU側の処理は経過時間を表すをカウンタを更新して、GPU側のuniform変数を1つ設定するだけです。 後はGPU側がこのカウンタを元に自分の頂点位置を計算して勝手にスクロールしてくれるという流れになります。

   1:  internal void Update()
   2:  {
   3:      // カウンタのみ更新。実計算はGPU側で全て行う
   4:      counter += 1.0f;
   5:      starEffect.Counter.SetValue(counter);
   6:  }

星は最初、点(ポイントリスト)で表示する予定だったのですが、XNA4.0からはプリミティブタイプからPointListが無くなってます!。ということでラインで星を表現することにしました。

   1:  internal void Draw()
   2:  {
   3:      GraphicsDevice g = XGame.Instance.GraphicsDevice;
   4:      g.SetVertexBuffer(vertexBuffer);
   5:      Effect effect = starEffect.Effect;
   6:      effect.CurrentTechnique.Passes[0].Apply();
   7:      g.DrawPrimitives(PrimitiveType.LineList, 0, STAR_COUNT);
   8:      g.SetVertexBuffer(null);
   9:  }

頂点はカスタム頂点を作成しました。頂点ごとにスクロール速度など必要なデータを持たせてそれぞれが適当な速度でスクロールするようになっています。なお頂点データ自体は最初に用意しておけばよいので、わざわざDynamicVertexBufferにする必要もなく、VertexBufferで充分です。GPUプログラミング初級の私にとっては調度良い勉強課題となりました。
後はテクスチャ座標なんかを用意してあげたりすると、星のスプライト的なものをGPU側だけでスクロールすることも簡単にできますね。きっと一昔の私なら、全部CPUで処理してました…。
今回、星は1000個ほど表示してますので、ラインで考えると倍の2000頂点ほどの操作が必要になります。これをCPU側で処理しようとすると1000回 forループさせて、頂点データを更新して、更新した頂点データをGPUに転送して…となるので、結構な処理時間を食ってんだろうなと思います。

昔、XNAは遅くて使えないと批判的なことを言う方をWEB上でちょこちょこ見かけていましたが、きっとそういう人達は全部CPUに処理させようとかしてる人だったんだろうなと最近は思うようにしてます。きっとすごい人達はGPUで処理できることは全部されると思うので、そういうことは言われないんだと思います。

余談ですが、今回もXBOX版の動画になります。 XBOX版のキャプチャでは動画が粗すぎますね。、画面エフェクトなど見ていただきたい部分が伝わらない気が致します。

しかし、ノートPCのグラフィック能力ではキャプチャしながらのゲーム実行は辛くなってきたのか、PC版をキャプチャすると画面がカクカクでキャプチャがうまくできなくなってきました。

6月あたりにデスクトップPCを導入予定と申してましたが、時期的にAMD Bulldozerの詳細もみえてきそうな時期ですので、そのあたりを考慮してIntelかAMDのどちらにしようか検討したいと思っています。僕のようなPCの使い方ではどっちを選んでも充分すぎるほど高性能でしょうねきっと。昔から人とおなじものはあまり欲しくないというようなひねくれた性格でしたので、はやりの2600KではなくBulldozer選択でしょうか…。

実際のゲームとしては、XBOX版でもCPU・GPUともにまだまだ余裕があるので、エフェクトをもっと派手にしたいのですが、敵の弾が見えにくいなどの問題もではじめてきているので、今後どうやってエフェクトを派手にするかが検討課題の1つでもあります。良いアイデアがあればよいのですが…。
いくつかブログに書いておきたいこともありますので、また近々更新したいなと思っております。また時折、思い出したときにでもこのブログを閲覧頂けますと幸いです。

0 件のコメント:

コメントを投稿