手順 6: タイマーの追加
次に、絵合わせゲームに Timer コントロールを追加します。タイマーは、指定されたミリ秒間待機してから、ティックと呼ばれるイベントを発生させます。タイマーは、アクションを開始したり定期的に繰り返したりする場合に便利です。ここではタイマーの使用例として、プレーヤーが 2 つのアイコンを選択し、アイコンが一致しない場合は、短時間の経過後にその 2 つのアイコンが再び非表示になるようにします。
タイマーを追加するには
Windows フォーム デザイナーのツール ボックスから、[タイマー] ([コンポーネント] カテゴリ内) を選択して Enter キーを押すか、タイマーをダブルクリックして、タイマー コントロールをフォームに追加します。次の図に示しているように、タイマーのアイコンが [Timer1] という名前で、フォームの下の領域に表示されます。
タイマー
[!メモ]
ツール ボックスが空の場合は、フォームのコードではなくフォーム デザイナーを選択してから、ツール ボックスを開いてください。
[Timer1] アイコンをクリックしてタイマーを選択します。[プロパティ] ウィンドウで、表示イベントから表示プロパティに切り替えます。次に、タイマーの [Interval] プロパティを 750 に設定します。ただし、その [Enabled] プロパティは [False] のままにします。[Interval] プロパティは、ティック間の待機時間 (Tick イベントのトリガーまでの待機時間) をタイマーに指示します。このプロパティの値として 750 を指定すると、その Tick イベントを発生させるまでに 4 分の 3 秒 (750 ミリ秒) 待機するようタイマーに指示することになります。Start() メソッドを呼び出して、プレーヤーが 2 つ目のラベルをクリックした後にのみタイマーが開始されるようにします。
Windows フォーム デザイナーでタイマー コントロール アイコンを選択して Enter キーを押すか、タイマーをダブルクリックして、空の Tick イベント ハンドラーを追加します。次のコードを既存のコードと置き換えるか、手動でイベント ハンドラーに入力します。
''' <summary> ''' This timer is started when the player clicks ''' two icons that don't match, ''' so it counts three quarters of a second ''' and then turns itself off and hides both icons ''' </summary> ''' <remarks></remarks> Private Sub Timer1_Tick() Handles Timer1.Tick ' Stop the timer Timer1.Stop() ' Hide both icons firstClicked.ForeColor = firstClicked.BackColor secondClicked.ForeColor = secondClicked.BackColor ' Reset firstClicked and secondClicked ' so the next time a label is ' clicked, the program knows it's the first click firstClicked = Nothing secondClicked = Nothing End Sub
/// <summary> /// This timer is started when the player clicks /// two icons that don't match, /// so it counts three quarters of a second /// and then turns itself off and hides both icons /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timer1_Tick(object sender, EventArgs e) { // Stop the timer timer1.Stop(); // Hide both icons firstClicked.ForeColor = firstClicked.BackColor; secondClicked.ForeColor = secondClicked.BackColor; // Reset firstClicked and secondClicked // so the next time a label is // clicked, the program knows it's the first click firstClicked = null; secondClicked = null; }
Tick イベント ハンドラーは、3 つのことを実行します。まず、Stop() メソッドを呼び出してタイマーを停止します。次に、2 つの参照変数 firstClicked および secondClicked を使用して、プレーヤーがクリックした 2 つのラベルを再び非表示にします。最後に、firstClicked 参照変数と secondClicked 参照変数を null (Visual C# の場合) または Nothing (Visual Basic の場合) にリセットします。この手順は、プログラム自体がリセットされるしくみであるため重要です。この時点では、Label コントロールが追跡されておらず、プレーヤーはラベルを再びクリックできる状態になっています。
[!メモ]
Timer オブジェクトには、タイマーを開始する Start() メソッドと、タイマーを停止する Stop() メソッドがあります。[プロパティ] ウィンドウでタイマーの [Enabled] プロパティを [True] に設定した場合、タイマーはプログラムが起動するとすぐに時間を刻み始めます。一方、[False] に設定したままにした場合、その Start() メソッドが呼び出されるまでは時間の刻みは始まりません。通常、タイマーは、Interval プロパティを使用して、次に時間を刻むまでに待機するミリ秒数を判断し、その Tick イベントを繰り返し発生させます。ここでは、タイマーの Stop() メソッドが Tick イベント内で呼び出されるしくみになっています。これにより、タイマーがワン ショット モードになります。つまり、Start() メソッドが呼び出されると、タイマーは指定された間隔分の時間を待機し、Tick イベントを 1 回発生させた後に、停止するようになります。
新しいタイマーの動作を確認するには、コード エディターに移動し、label_Click() イベント ハンドラー メソッドの上部と下部に次のコードを追加します (if ステートメントを、上部に 1 つ追加し、下部に 3 つ追加することになります。メソッドの他の部分は同じです)。
''' <summary> ''' Every label's Click event is handled by this event handler ''' </summary> ''' <param name="sender">The label that was clicked</param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub label_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label9.Click, Label8.Click, Label7.Click, Label6.Click, Label5.Click, Label4.Click, Label3.Click, Label2.Click, Label16.Click, Label15.Click, Label14.Click, Label13.Click, Label12.Click, Label11.Click, Label10.Click, Label1.Click ' The timer is only on after two non-matching ' icons have been shown to the player, ' so ignore any clicks if the timer is running If Timer1.Enabled Then Exit Sub Dim clickedLabel = TryCast(sender, Label) If clickedLabel IsNot Nothing Then ' If the clicked label is black, the player clicked ' an icon that's already been revealed -- ' ignore the click If clickedLabel.ForeColor = Color.Black Then Exit Sub ' If firstClicked is Nothing, this is the first icon ' in the pair that the player clicked, ' so set firstClicked to the label that the player ' clicked, change its color to black, and return If firstClicked Is Nothing Then firstClicked = clickedLabel firstClicked.ForeColor = Color.Black Exit Sub End If ' If the player gets this far, the timer isn't ' running and firstClicked isn't Nothing, ' so this must be the second icon the player clicked ' Set its color to black secondClicked = clickedLabel secondClicked.ForeColor = Color.Black ' If the player gets this far, the player ' clicked two different icons, so start the ' timer (which will wait three quarters of ' a second, and then hide the icons) Timer1.Start() End If End Sub
/// <summary> /// Every label's Click event is handled by this event handler /// </summary> /// <param name="sender">The label that was clicked</param> /// <param name="e"></param> private void label_Click(object sender, EventArgs e) { // The timer is only on after two non-matching // icons have been shown to the player, // so ignore any clicks if the timer is running if (timer1.Enabled == true) return; Label clickedLabel = sender as Label; if (clickedLabel != null) { // If the clicked label is black, the player clicked // an icon that's already been revealed -- // ignore the click if (clickedLabel.ForeColor == Color.Black) return; // If firstClicked is null, this is the first icon // in the pair that the player clicked, // so set firstClicked to the label that the player // clicked, change its color to black, and return if (firstClicked == null) { firstClicked = clickedLabel; firstClicked.ForeColor = Color.Black; return; } // If the player gets this far, the timer isn't // running and firstClicked isn't null, // so this must be the second icon the player clicked // Set its color to black secondClicked = clickedLabel; secondClicked.ForeColor = Color.Black; // If the player gets this far, the player // clicked two different icons, so start the // timer (which will wait three quarters of // a second, and then hide the icons) timer1.Start(); } }
メソッドの上部のコードは、Enabled プロパティの値をチェックして、タイマーが開始されているかどうかをチェックします。これにより、プレーヤーが 1 つ目と 2 つ目の Label コントロールをクリックした場合はタイマーが開始され、3 つ目のラベルをクリックした場合は何も実行されません。
メソッドの下部のコードは、プレーヤーがクリックした 2 つ目の Label コントロールを追跡し、そのラベルのアイコンの色を黒に設定してアイコンを表示するように、secondClicked 参照変数を設定します。これにより、タイマーがワン ショット モードで開始され、750 ミリ秒待機してから、Tick イベントを 1 回発生させるようになります。その後で、タイマーの Tick イベント ハンドラーが 2 つのアイコンを非表示にし、firstClicked 参照変数と secondClicked 参照変数をリセットします。この時点で、プレーヤーはフォーム上で別の 1 組のアイコンをクリックできる状態になります。
プログラムを保存し、実行します。アイコンをクリックすると、そのアイコンが表示されます。
別のアイコンをクリックします。そのアイコンが一時的に表示され、その後、両方のアイコンが非表示になります。これを何度も繰り返します。これで、フォームで、クリックした 1 つ目と 2 つ目のアイコンが追跡され、タイマーを使用して、少し時間をおいてからアイコンが非表示にされるようになりました。
続行または確認するには
チュートリアルの次の手順に進むには、「手順 7: ペアの表示の維持」を参照してください。
チュートリアルの前の手順に戻るには、「手順 5: ラベルの参照の追加」を参照してください。