これと同じようなものを作ります。
数字で表された敵インベーダー(数字インベーダー)にあわせてプレーヤーが移動ボタンで砲台の数値を増加させ、発射ボタンでその数値の数字インベーダーを撃破する。ゼロ以外の数字インベーダーを撃破した際に撃破した数字の合計が10の倍数になっていればПの形をしたUFOが出現した。これを撃破すると高い点が入るため、暗算力がものをいうゲームでもあった。数字インベーダーの桁が砲台のある左端に届いてしまうと攻撃されたことになり、砲台の表示が 三 → 二 → 一 と減っていく。1つの面内で、3つ全ての砲台が無くなるか、残弾(画面には表示されない)を使い切るとゲームオーバーになる。数字インベーダーを全滅させると砲台と弾数が回復し、次の面へ続く。
そして完成したものがこちらになります。
ここでは
数字インベーダーを出現させる
数字インベーダーを撃破する
UFOを出現させる
ゲームクリアとゲームオーバー
これらが必要です。
まず数字インベーダーを出現させます。
フィールド変数は以下のとおり。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class Form1 : Form { int Score = 0; int Stage = 1; int EnemiesCount = 0; int EnemiesMaxCount = 16; int InitTimerInterval = 2 * 1000; Timer Timer = new Timer(); Random Random = null; string Enemies = ""; int EnemiesMax = 6; } |
出現する数字インベーダーは乱数で決定します。また数字インベーダーの出現はタイマーイベントを捕捉しておこないます。コンストラクタ内でRandomオブジェクトを生成するとともに、タイマーの初期化を行ないます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); Random = new Random((int)DateTime.Now.Ticks); Timer.Tick += Timer_Tick; GameStart(); ShowEmemies(); } } |
数字インベーダーの出現ですが、最初は2秒に1回です。ステージが進むにつれて速くしていきます。それから1ステージ当たりの数字インベーダーの数は16個です。残りの数字インベーダーの数はフィールド変数 EnemiesCount で管理します。
1 2 3 4 5 6 7 8 9 10 11 12 |
public partial class Form1 : Form { void GameStart() { Timer.Interval = InitTimerInterval; Timer.Start(); EnemiesCount = EnemiesMaxCount; Score = 0; Stage = 1; } } |
タイマーイベントが発生したら数字インベーダーをひとつずつ出現させます。6体まで表示されます。すでに撃墜されていない数字インベーダーが6体存在していて7体目が出現したらミスということになります。数字インベーダーが存在しない部分は「-」で埋めます。
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 |
public partial class Form1 : Form { private void Timer_Tick(object sender, EventArgs e) { if(Enemies.Length == EnemiesMax) { Miss(); return; } int i = Random.Next(0, 10); Enemies += i.ToString(); ShowEmemies(); } void ShowEmemies() { // EnemiesMax = 6 である int space = EnemiesMax - Enemies.Length; string s = ""; for(int ii = 0; ii < space; ii++) { s += "-"; } s += Enemies; label2.Text = s; } } |
数字インベーダーが左側に到達したらミスです。ミスをしたらタイマーを一旦止めます。そして3秒後に再スタートします。
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 |
public partial class Form1 : Form { void Miss() { labelDebug1.Text = "miss!"; Timer.Stop(); ShowScore(); Enemies = ""; Timer timer2 = new Timer(); timer2.Interval = 3000; timer2.Tick += Timer2_Tick; timer2.Start(); } private void Timer2_Tick(object sender, EventArgs e) { Timer t = (Timer)sender; t.Stop(); t.Dispose(); labelDebug1.Text = "play"; ShowEmemies(); Timer.Start(); label1.Text = Target.ToString() + ":"; } void ShowScore() { label1.Text = Stage.ToString() + ":"; label2.Text = String.Format("{0:000000}", Score); } } |
次に数字インベーダーを撃破するコードを書きます。
Zキーを押すとターゲットが変更され、Xキーを押すと攻撃できます。Targetが10のときはUFOを攻撃します。
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 |
public partial class Form1 : Form { int _target = 0; int Target { set { if(value > 10) value -= 11; _target = value; } get { return _target; } } private void Form1_KeyDown(object sender, KeyEventArgs e) { if(e.KeyData == Keys.Z) { Target++; if(Target != 10) label1.Text = Target.ToString() + ":"; else label1.Text = "n" + ":"; } if(e.KeyData == Keys.X) { Shot(); } } } |
Shot() は、数字インベーダーを攻撃するメソッドです。Targetが10でないときはその数字を、10のときはUFOを攻撃します。ターゲットと同じ数字インベーダーが存在する場合は一番左のものをひとつだけ消します。そして数字インベーダーをひとつだけ後退させます。またEnemiesCountの値をひとつ下げます。
点数計算も行ないます。数字インベーダーは一番右で撃墜した場合が一番高得点(60点)で、左にいくほど点数が下がります。
EnemiesCountがゼロになったらステージクリアです。現在の得点を表示してStageをインクリメントします。またTimer.Intervalを小さな値にして数字インベーダーの出現速度を上げます。
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 |
public partial class Form1 : Form { void Shot() { string targetString = ""; if(Target < 10) targetString = Target.ToString(); else targetString = "n"; int ret = Enemies.IndexOf(targetString); if(ret != -1) { if(Target != 10) { int index = label2.Text.IndexOf(targetString); int plus = (index + 1) * 10; Score += plus; labelDebug1.Text = plus.ToString(); } else { Score += 300; labelDebug1.Text = 300.ToString(); } labelDebug2.Text = Score.ToString(); Enemies = Enemies.Remove(ret, 1); ShowEmemies(); EnemiesCount--; if(EnemiesCount == 0) { StageClear(); } } } void StageClear() { labelDebug1.Text = "Clear!"; Timer.Stop(); Stage++; ShowScore(); Enemies = ""; EnemiesCount = EnemiesMaxCount; if(Timer.Interval > 260) Timer.Interval -= 250; Timer timer2 = new Timer(); timer2.Interval = 3000; timer2.Tick += Timer2_Tick; timer2.Start(); } } |
それからTimer_Tick(object sender, EventArgs e)を修正します。1ステージあたりの数字インベーダーの数は16個です。すでに撃退されたものと現在表示されているものの合計が16になっている場合は、新しい数字インベーダーはつくらずに残されたものを左に移動させるだけにしなければなりません。
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 |
public partial class Form1 : Form { private void Timer_Tick(object sender, EventArgs e) { if(Enemies.Length == EnemiesMax) { Miss(); return; } // すでに撃退されたものと現在表示されているものの合計が16未満のときだけ新しい数字インベーダーを出現させる。 // すでに撃退されたもの EnemiesMax - EnemiesCount // 現在表示されているもの Enemies.Length // EnemiesMax - EnemiesCount + Enemies.Length < EnemiesMax ⇔ EnemiesCount - Enemies.Length > 0 if(EnemiesCount - Enemies.Length > 0) { int i = Random.Next(0, 10); Enemies += i.ToString(); } else { Enemies += "-"; } ShowEmemies(); } } |