現在の状態ではミスをしても自機から弾丸を発射できたり、すべての要塞を破壊してもステージクリア時の処理がおこなわれません。今回はこの状態を改善します。
まず自機が死亡した場合は弾丸を発射できなくします。そしてすべての爆発が終わったときに残機を減らしてゲームを再開させます。自機がゼロであればゲームオーバーの処理をおこないます。
isGameOverフラグを用意して最初はtrueにしておきます。またアプリケーションが開始されたときはゲーム開始前なので自機は表示させません。Jiki.IsDead = true にしておきます。
また自機が破壊され、残機がゼロになったらゲームオーバーです。Update()内でIsGameOver == true のときはなにもしません。
ミスしたときをどうやって判断すればよいでしょうか? ゲームオーバーではないのにJiki.IsDead == true のときです。爆発がおさまってからミス時の処理をおこないます。この場合は2秒処理を停止して、JikiRestart()メソッドを呼び出します。JikiRestart()では残機をひとつ減らして飛行中の弾丸や敵をクリアして自機を最初の位置に戻します。そしてゲームを再開します。残機がゼロになったらゲームオーバーです。
敵の要塞をすべて破壊したらステージクリアです。この判定もUpdate()メソッド内でおこないます。爆発がおさまっていて、Fortresses.Count == 0のときがステージクリアです。ステージをクリアしたら要塞を配置しなおしてゲームを再開します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
public partial class Form1 : Form { bool IsGameOver = true; int Stage = 0; float HomeX = 0; float HomeY = 0; private void glControlEx1_Load(object sender, EventArgs e) { GL.ClearColor(glControl.BackColor); SetProjection(); GL.Enable(EnableCap.DepthTest); Jiki = new Jiki(this, 0, 0, 0, 0, JikiRadius, 1); Jiki.IsDead = true; } new void Update() { if(IsGameOver) return; MoveJiki(); UpdateBurrets(); CreateEnemyIfNeed(); UpdateEnemies(); FortressesUpdate(); FortressesBurretsUpdate(); HitJudge(); UpdateExplosions(); RemoveOutOfSightObject(); WarpIfNeed(); UpdateMap(); if (Jiki.IsDead && Explosions.Count == 0) { OnJikiDead(); } if (Explosions.Count == 0 && Fortresses.Count == 0) { OnStageClear(); } UpdateCount++; } void OnJikiDead() { System.Threading.Thread.Sleep(2000); JikiRest--; if (JikiRest > 0) JikiRestart(); else GameOver(); } void JikiRestart() { ClearObjects(); Jiki.IsDead = false; Jiki.X = HomeX; Jiki.Y = HomeY; Jiki.Rotate = 90; } void GameOver() { IsGameOver = true; ClearObjects(); } void OnStageClear() { ClearObjects(); System.Threading.Thread.Sleep(2000); InitStage(++Stage); } void ClearObjects() { Burrets.Clear(); Enemies.Clear(); FortressesBurrets.Clear(); Explosions.Clear(); UpdateCount = 0; UpdateCountEndLeft = -1; UpdateCountEndRight = -1; } protected override void OnKeyDown(KeyEventArgs e) { if (Jiki.IsDead) return; if (e.KeyCode == Keys.Left) UpdateCountEndLeft = UpdateCount + 5; if (e.KeyCode == Keys.Right) UpdateCountEndRight = UpdateCount + 5; if (e.KeyCode == Keys.Down) UpdateCountEndRight = UpdateCount + 5 * 4; if (e.KeyCode == Keys.Space) Shot(); base.OnKeyDown(e); } } |
ゲームオーバーになったあとやゲームの途中に[ゲーム開始]をクリックするとInitGame()が実行されます。InitGame()のなかでは IsGameOver が falseになり、スコアや残機がリセットされInitStage(0)が実行されます。InitStage(int stage)のなかで要塞が再配置されゲームが始まります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public partial class Form1 : Form { void InitGame() { IsGameOver = false; Score = 0; Stage = 0; Jiki = new Jiki(this, 0, 0, 0, 0); JikiRest = Config.MaxJikiRest; InitStage(Stage); } void InitStage(int stage) { ClearObjects(); Jiki.Rotate = 90; Fortresses.Clear(); // ステージがあがると配置を変える。ここではすべて同じにしている //if (stage == 0) { HomeX = 50; HomeY = 10; Jiki.X = HomeX; Jiki.Y = HomeY; Fortresses.Add(new Fortress(this, 40, 50, 0, 0, true)); Fortresses.Add(new Fortress(this, 60, 50, 0, 0, true)); Fortresses.Add(new Fortress(this, 30, 70, 0, 0, true)); Fortresses.Add(new Fortress(this, 70, 70, 0, 0, true)); Fortresses.Add(new Fortress(this, 40, 90, 0, 0, true)); Fortresses.Add(new Fortress(this, 60, 90, 0, 0, true)); } } } |
Your goal may be to inform, it may be to sell a product. Marnia Frederick Alexandrina