ミスをしたときの処理
ボールがフィールドの下から外にでた場合はミスとなります。ミスをした場合の処理が必要です。
ミスをしたら残機をひとつ減らす、新しいボールが最初の位置からでてくる
残機がゼロになったらゲームオーバー
ミスをした場合とはボールがフィールドの下から外にでた場合なので、SetBallDirectIfHitWallメソッドで下の壁に当たったと判定された場合になります。
ミスと判定された場合はOnMissメソッドが呼ばれます。
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 |
public partial class Form1 : Form { bool SetBallDirectIfHitWall() { Rectangle ballRect = GetBallRectangle(); Rectangle fieldRect = GetFieldRectangle(); // ボールが右から外へ出てしまった if(fieldRect.Right < ballRect.Right) { if(ballDirectX > 0) ballDirectX *= -1; return true; } // ボールが左から外へ出てしまった if(ballRect.Left < fieldRect.Left) { if(ballDirectX < 0) ballDirectX *= -1; return true; } // ボールが上へ出てしまった if(ballRect.Top < fieldRect.Top) { if(ballDirectY < 0) ballDirectY *= -1; return true; } // ボールが下へ出てしまった = ミスをした if(fieldRect.Bottom < ballRect.Bottom) { OnMiss(); return true; } return false; } } |
OnMissメソッド
OnMissメソッドではボールが動かないようにするためにタイマーを止めます。そして2秒間休みます。そのあとボールを最初の位置に戻して出現させます。
それからなにもしないとボールがフィールドの外側に描画されるので、ボールの描画をやめます。
以下はそのための処理で追加されたフィールド変数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public partial class Form1 : Form { const int BALL_START_POS_X = 20; const int BALL_START_POS_Y = 200; const int BALL_START_DIRECT_X = 2; const int BALL_START_DIRECT_Y = 5; int ballPosX = BALL_START_POS_X; int ballPosY = BALL_START_POS_Y; int ballDirectX = BALL_START_DIRECT_X; int ballDirectY = BALL_START_DIRECT_Y; // ミスをして復帰するまでのあいだは true bool missing = false; } |
OnMissメソッドとその関連のメソッドを示します。
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 |
public partial class Form1 : Form { async void OnMiss() { missing = true; timer.Stop(); DecrementRest(); if(IsGameOver()) return; await Task.Delay(2000); timer.Start(); // 初期位置にボールを戻して再開 ballPosX = BALL_START_POS_X; ballPosY = BALL_START_POS_Y; ballDirectX = BALL_START_DIRECT_X; ballDirectY = BALL_START_DIRECT_Y; missing = false; } void DrawBall(Graphics g) { // ミスしてから復帰するまではボールを描画しない if(missing) return; SolidBrush brush = new SolidBrush(Color.LightBlue); Rectangle rect = new Rectangle(new Point(ballPosX, ballPosY), new Size(BALL_WIDTH, BALL_HEIGHT)); g.FillEllipse(brush, rect); } void DecrementRest() { // 後述 } bool IsGameOver() { // 後述 } } |
残機を表示させる
DecrementRestメソッドは残機を減らすメソッドです。ただし残機減らす前提として残機を表示させる必要があります。
残機はフィールドの下側にLabelを作成してそこに表示させます。
これは残機を表示するラベルを作成するメソッドです。コンストラクタの最後に呼んでおけばよいかと思います。
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 { Label label = new Label(); void ShowRestLabel() { Rectangle rect = GetFieldRectangle(); Point point = new Point(rect.Left, rect.Bottom + 10); label.Location = point; label.Size = new Size(100, 10); label.Parent = this; label.ForeColor = Color.White; } public Form1() { InitializeComponent(); BackColor = Color.Black; this.DoubleBuffered = true; timer.Interval = 30; timer.Tick += Timer_Tick; timer.Start(); ShowRestLabel(); // 追加 GameStart(); } } |
残機の表示は自作したRestCountプロパティでおこないます。したがって残機の表示はこのプロパティを使えばよいということになります。ゲームオーバーかどうかは RestCount == 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 |
public partial class Form1 : Form { int RestCount { get { return rest; } set { rest = value; if(rest > 0) label.Text = "残り " + rest.ToString(); else label.Text = "Game Over"; } } void DecrementRest() { RestCount--; } bool IsGameOver() { if(RestCount == 0) return true; else return false; } } |
またゲーム開始時は残機3ということで開始します。
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { const int REST_COUNT_MAX = 3; void GameStart() { RestCount = REST_COUNT_MAX; // 残機は3 ClearAllBreaked(); barPosX = (FIELD_WIDTH - BAR_WIDTH) / 2; } } |