前回作成したモグラ叩き兼タイピング練習ソフトではモグラは1匹ずつしか現れませんでした。今回は複数同時に出現させます。
モグラ叩きゲームなので叩かれないモグラはいつまでも存在することはありません。一定の時間が経過したらいなくなってしまいます。そこでMoguraクラスに以下を追加します。
1 2 3 4 5 |
public class Mogura { // 生成された時間を記録する public DateTime CreateTime = DateTime.Now; } |
それからスコアもつけることにします。以下のようにすれば叩くことができたモグラと叩き損ねたモグラ、叩かなくて良い場所を叩いた回数をスコア化することができます。
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 |
public partial class Form1 : Form { void ShowScore() { label1.Text = String.Format("Hit = {0} MissHit = {1} Pass = {2}", HitCount, MissHitCount, PassCount); } void ResetScore() { _hitCount = 0; _missHitCount = 0; _passCount = 0; ShowScore(); } int _passCount = 0; int PassCount { set { _passCount = value; ShowScore(); } get { return _passCount; } } int _hitCount = 0; int HitCount { set { _hitCount = value; ShowScore(); } get { return _hitCount; } } int _missHitCount = 0; int MissHitCount { set { _missHitCount = value; ShowScore(); } get { return _missHitCount; } } } |
以下はゲームスタート関連のメソッドとイベントハンドラです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public partial class Form1 : Form { void GameStart() { ResetScore(); Timer.Start(); } private void StartMenuItem_Click(object sender, EventArgs e) { GameStart(); } } |
では複数モグラを表示させてみましょう。
モグラを生成したらリストのなかに格納していきます。そのときすでに同じ文字列をもつモグラがいた場合は追加しないでそのまま破棄します。
そのあと出現後一定時間が経過したのに叩かれずに残っているモグラがいないか調べます。見つかったらリストのなかから取り除いて破棄します。そして叩き損ねたモグラとしてカウントします。
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 |
public partial class Form1 : Form { // モグラは同時に複数出現するのか? bool IsMultiMoguras = true; int PassTime = 2000; // MillSecond private void Timer_Tick(object sender, EventArgs e) { CreateNewMogura(); CheckList(); this.Invalidate(); } void CreateNewMogura() { if(IsMultiMoguras) { Mogura mogura = new Mogura(Random); if(!Moguras.Any(x => x.String == mogura.String)) Moguras.Add(mogura); else mogura.Dispose(); } else Mogura = new Mogura(Random); } void CheckList() { // DateTimeクラスのTicksプロパティは、0001年1月1日00:00:00からの経過時間を // 100ナノ秒単位で返すので ミリ秒を10,000倍する必要がある //List<Mogura> moguras = Moguras.Where(x => x.CreateTime.Ticks > DateTime.Now.Ticks - PassTime * 10000).ToList(); List<Mogura> removes = Moguras.Where(x => x.CreateTime.Ticks <= DateTime.Now.Ticks - PassTime * 10000).ToList(); // 叩き損ねたモグラを破棄したあと、その数を記録する foreach(Mogura m in removes) { Moguras.Remove(m); m.Dispose(); PassCount++; } } } |
モグラを叩くときの処理です。リストのなかに文字列が一致するモグラがいるかどうか調べます。あれば取り除て破棄したあと、叩くことができたモグラとしてカウントします。
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 |
public partial class Form1 : Form { protected override void OnKeyPress(KeyPressEventArgs e) { Hammer = new Hammer(e.KeyChar.ToString()); if(IsMultiMoguras) { Mogura mogura = Moguras.FirstOrDefault(x => x.String == e.KeyChar.ToString()); if(mogura != null) { OnHit(); Moguras.Remove(mogura); } else MissHitCount++; } else { if(Mogura != null) { string str = Mogura.String; if(str == e.KeyChar.ToString()) { OnHit(); } else { MissHitCount++; } } } Invalidate(); base.OnKeyPress(e); } void OnHit() { Mogura = null; HitCount++; } } |
これはモグラが1匹ずつ現れるときに使用するプロパティです。
valueがnullのときはモグラが叩かれたときです。そうでないときは新しいモグラが生成されたときです。_mogura が null ではないときに新しいモグラがセットされたら叩き損ねたことになります。このときも叩き損ねたモグラとしてカウントします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { Mogura _mogura = null; Mogura Mogura { set{ if(_mogura != null) _mogura.Dispose(); // _mogura が null ではないときに新しいモグラがセットされたら叩き損ねたことになる。 if(value != null && _mogura != null) PassCount++; _mogura = value; } get{ return _mogura; } } } |
最後に描画のためのOnPaint(PaintEventArgs e)を示します。
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 |
public partial class Form1 : Form { protected override void OnPaint(PaintEventArgs e) { if(IsMultiMoguras) { foreach(var m in Moguras) { Bitmap bitmap = m.Bitmap; bitmap.MakeTransparent(Color.FromArgb(0, 128, 0)); e.Graphics.DrawImage(bitmap, new Point(m.PosX, m.PosY)); } } else { if(Mogura != null) { Bitmap bitmap = Mogura.Bitmap; bitmap.MakeTransparent(Color.FromArgb(0, 128, 0)); e.Graphics.DrawImage(bitmap, new Point(Mogura.PosX, Mogura.PosY)); } } if(Hammer != null) { Bitmap bitmap = Hammer.Bitmap; bitmap.MakeTransparent(Color.FromArgb(0, 128, 0)); e.Graphics.DrawImage(bitmap, new Point(Hammer.PosX, Hammer.PosY)); } } } |