ミニDTL.xna “ゲームはイチニチ30分まで!” 第5回

by key

ミニDTL.xnaその5です。

これは月曜日の配信分のまとめ記事です。

Mini DTL.xna (5)

こんなことをやりました。

自弾発射をFighterクラスに任せる

今までは、せっかくFighterクラスでコントローラの面倒をみていたのにListとの繋ぎを作るのが面倒で、自弾発射処理がGame1クラスに飛び出してしまっていました。

さすがにそれではGame1側が複雑になってしまうので、Fighter.UpdateにListを渡して勝手に追加してくれ、という実装にしてしまいました。

Fighter.Updateの定義を

  1. public void Update(GameTime gameTime, List<Shot> shots)

として、その中に

  1. if (shotButtonState > 0) {
  2.     if (shotButtonState % 4 == 1) {
  3.         Shot shot = new Shot();
  4.         shot.Position.X = Position.X;
  5.         shot.Position.Y = Position.Y;
  6.         shots.Add(shot);
  7.     }
  8. }

を入れました。ついでにShotButtonStatesをprivateにしました。

が、さすがにデータを素手で扱ってる感が強くなってまいりました。次回はここを作り直したい。

敵に敵弾を発射させる

同じ要領で、EnemyにEnemyShot(前回半分ぐらい作ってた)を撃たせるようにしました。

敵弾を自機に向かって発射する

自弾は真上に向かって飛ばしていますが、敵弾はそれだとつまらないので速度ベクトルを作り

  1. public Vector2 Speed;

毎フレームその速度で移動させるようにしました。

  1. Position += Speed;

Enemyクラス側では、弾の発射時に敵と時機の位置関係を計算し、EnemyShot.Speedを設定するようにしています。

  1. if (rand.NextDouble() < 0.02) {
  2.     EnemyShot enemyShot = new EnemyShot();
  3.  
  4.     Vector2 relPos = fighter.Position - Position;
  5.     relPos.Normalize();
  6.     relPos.X *= 5;
  7.     relPos.Y *= 5;
  8.  
  9.     enemyShot.Position.X = Position.X;
  10.     enemyShot.Position.Y = Position.Y;
  11.     enemyShot.Speed.X = relPos.X;
  12.     enemyShot.Speed.Y = relPos.Y;
  13.    
  14.     enemyShots.Add(enemyShot);
  15. }

これを行うため、Enemy.UpdateにはListとFighterを渡すようにする必要がありました。

  1. public void Update(GameTime gameTime, List<EnemyShot> enemyShots, Fighter fighter)

やはり、この構造は気持ち悪いです。

爆発エフェクトの実装

例によってペイントで絵を描きました。

explosion.png

explosion.png

全然爆発に見えない。追々描きなおします。

ExplosionEffectクラスを作り、Game1クラスに対応するリストを作ります。

  1. List<ExplosionEffect> effects;

ExplosionEffectのListなのに名前がeffectsなのは、そのうち基底クラスEffectを作りたいからです。この手のTODOは次回一気に回収したいですね。

後はいつも通りLoadContentして、リストへの追加、リスト内での更新、リストからの削除、リストの描画を行います。

リストからの削除条件ですが、いつも通りのDestroyedを以下のようにtrueにしています。

ExplosionEffectのUpdateで

  1. public void Update(GameTime gameTime) {
  2.     count++;
  3.  
  4.     drawDest.Width = drawDest.Height = count * 3;
  5.  
  6.     drawDest.X = (int)(Position.X - drawDest.Width * 0.5);
  7.     drawDest.Y = (int)(Position.Y - drawDest.Height * 0.5);
  8.  
  9.     if (count > 30) {
  10.         Destroyed = true;
  11.     }
  12. }

ついでに、drawDestの大きさをcountにあわせてみました。爆発がのろーりと広がります。

30分経過してしまったのでここまで。

今日の感想

  • 構造の汚さが限界を超えてしまいました。次回はリファクタリングDayにしたいと思います。ゲームの要素的な進歩はなくなってしまいますが、ご了承ください。

タグ: , , ,

コメント / トラックバック 1 件

  1. XNA Today » ミニDTL.xna 第5回 より:

    [...] ミニDTL.xna “ゲームはイチニチ30分まで!” 第5回 [...]

コメントをどうぞ